// modules are defined as an array
// [ module function, map of requires ]
//
// map of requires is short require name -> numeric require
//
// anything defined in a previous bundle is accessed via the
// orig method which is the require for previous bundles

(function (modules, entry, mainEntry, parcelRequireName, globalName) {
  /* eslint-disable no-undef */
  var globalObject =
    typeof globalThis !== 'undefined'
      ? globalThis
      : typeof self !== 'undefined'
      ? self
      : typeof window !== 'undefined'
      ? window
      : typeof global !== 'undefined'
      ? global
      : {};
  /* eslint-enable no-undef */

  // Save the require from previous bundle to this closure if any
  var previousRequire =
    typeof globalObject[parcelRequireName] === 'function' &&
    globalObject[parcelRequireName];

  var cache = previousRequire.cache || {};
  // Do not use `require` to prevent Webpack from trying to bundle this call
  var nodeRequire =
    typeof module !== 'undefined' &&
    typeof module.require === 'function' &&
    module.require.bind(module);

  function newRequire(name, jumped) {
    if (!cache[name]) {
      if (!modules[name]) {
        // if we cannot find the module within our internal map or
        // cache jump to the current global require ie. the last bundle
        // that was added to the page.
        var currentRequire =
          typeof globalObject[parcelRequireName] === 'function' &&
          globalObject[parcelRequireName];
        if (!jumped && currentRequire) {
          return currentRequire(name, true);
        }

        // If there are other bundles on this page the require from the
        // previous one is saved to 'previousRequire'. Repeat this as
        // many times as there are bundles until the module is found or
        // we exhaust the require chain.
        if (previousRequire) {
          return previousRequire(name, true);
        }

        // Try the node require function if it exists.
        if (nodeRequire && typeof name === 'string') {
          return nodeRequire(name);
        }

        var err = new Error("Cannot find module '" + name + "'");
        err.code = 'MODULE_NOT_FOUND';
        throw err;
      }

      localRequire.resolve = resolve;
      localRequire.cache = {};

      var module = (cache[name] = new newRequire.Module(name));

      modules[name][0].call(
        module.exports,
        localRequire,
        module,
        module.exports,
        this
      );
    }

    return cache[name].exports;

    function localRequire(x) {
      return newRequire(localRequire.resolve(x));
    }

    function resolve(x) {
      return modules[name][1][x] || x;
    }
  }

  function Module(moduleName) {
    this.id = moduleName;
    this.bundle = newRequire;
    this.exports = {};
  }

  newRequire.isParcelRequire = true;
  newRequire.Module = Module;
  newRequire.modules = modules;
  newRequire.cache = cache;
  newRequire.parent = previousRequire;
  newRequire.register = function (id, exports) {
    modules[id] = [
      function (require, module) {
        module.exports = exports;
      },
      {},
    ];
  };

  Object.defineProperty(newRequire, 'root', {
    get: function () {
      return globalObject[parcelRequireName];
    },
  });

  globalObject[parcelRequireName] = newRequire;

  for (var i = 0; i < entry.length; i++) {
    newRequire(entry[i]);
  }

  if (mainEntry) {
    // Expose entry point to Node, AMD or browser globals
    // Based on https://github.com/ForbesLindesay/umd/blob/master/template.js
    var mainExports = newRequire(mainEntry);

    // CommonJS
    if (typeof exports === 'object' && typeof module !== 'undefined') {
      module.exports = mainExports;

      // RequireJS
    } else if (typeof define === 'function' && define.amd) {
      define(function () {
        return mainExports;
      });

      // <script>
    } else if (globalName) {
      this[globalName] = mainExports;
    }
  }
})({"lBB98":[function(require,module,exports) {
var HMR_HOST = null;
var HMR_PORT = null;
var HMR_SECURE = false;
var HMR_ENV_HASH = "4a236f9275d0a351";
module.bundle.HMR_BUNDLE_ID = "c9b2bbcd379dd93c";
"use strict";
function _createForOfIteratorHelper(o, allowArrayLike) {
    var it;
    if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) {
        if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
            if (it) o = it;
            var i = 0;
            var F = function F() {
            };
            return {
                s: F,
                n: function n() {
                    if (i >= o.length) return {
                        done: true
                    };
                    return {
                        done: false,
                        value: o[i++]
                    };
                },
                e: function e(_e) {
                    throw _e;
                },
                f: F
            };
        }
        throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
    }
    var normalCompletion = true, didErr = false, err;
    return {
        s: function s() {
            it = o[Symbol.iterator]();
        },
        n: function n() {
            var step = it.next();
            normalCompletion = step.done;
            return step;
        },
        e: function e(_e2) {
            didErr = true;
            err = _e2;
        },
        f: function f() {
            try {
                if (!normalCompletion && it.return != null) it.return();
            } finally{
                if (didErr) throw err;
            }
        }
    };
}
function _unsupportedIterableToArray(o, minLen) {
    if (!o) return;
    if (typeof o === "string") return _arrayLikeToArray(o, minLen);
    var n = Object.prototype.toString.call(o).slice(8, -1);
    if (n === "Object" && o.constructor) n = o.constructor.name;
    if (n === "Map" || n === "Set") return Array.from(o);
    if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}
function _arrayLikeToArray(arr, len) {
    if (len == null || len > arr.length) len = arr.length;
    for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
    return arr2;
}
/* global HMR_HOST, HMR_PORT, HMR_ENV_HASH, HMR_SECURE */ /*::
import type {
  HMRAsset,
  HMRMessage,
} from '@parcel/reporter-dev-server/src/HMRServer.js';
interface ParcelRequire {
  (string): mixed;
  cache: {|[string]: ParcelModule|};
  hotData: mixed;
  Module: any;
  parent: ?ParcelRequire;
  isParcelRequire: true;
  modules: {|[string]: [Function, {|[string]: string|}]|};
  HMR_BUNDLE_ID: string;
  root: ParcelRequire;
}
interface ParcelModule {
  hot: {|
    data: mixed,
    accept(cb: (Function) => void): void,
    dispose(cb: (mixed) => void): void,
    // accept(deps: Array<string> | string, cb: (Function) => void): void,
    // decline(): void,
    _acceptCallbacks: Array<(Function) => void>,
    _disposeCallbacks: Array<(mixed) => void>,
  |};
}
declare var module: {bundle: ParcelRequire, ...};
declare var HMR_HOST: string;
declare var HMR_PORT: string;
declare var HMR_ENV_HASH: string;
declare var HMR_SECURE: boolean;
*/ var OVERLAY_ID = '__parcel__error__overlay__';
var OldModule = module.bundle.Module;
function Module(moduleName) {
    OldModule.call(this, moduleName);
    this.hot = {
        data: module.bundle.hotData,
        _acceptCallbacks: [],
        _disposeCallbacks: [],
        accept: function accept(fn) {
            this._acceptCallbacks.push(fn || function() {
            });
        },
        dispose: function dispose(fn) {
            this._disposeCallbacks.push(fn);
        }
    };
    module.bundle.hotData = undefined;
}
module.bundle.Module = Module;
var checkedAssets, acceptedAssets, assetsToAccept;
function getHostname() {
    return HMR_HOST || (location.protocol.indexOf('http') === 0 ? location.hostname : 'localhost');
}
function getPort() {
    return HMR_PORT || location.port;
} // eslint-disable-next-line no-redeclare
var parent = module.bundle.parent;
if ((!parent || !parent.isParcelRequire) && typeof WebSocket !== 'undefined') {
    var hostname = getHostname();
    var port = getPort();
    var protocol = HMR_SECURE || location.protocol == 'https:' && !/localhost|127.0.0.1|0.0.0.0/.test(hostname) ? 'wss' : 'ws';
    var ws = new WebSocket(protocol + '://' + hostname + (port ? ':' + port : '') + '/'); // $FlowFixMe
    ws.onmessage = function(event) {
        checkedAssets = {
        };
        acceptedAssets = {
        };
        assetsToAccept = [];
        var data = JSON.parse(event.data);
        if (data.type === 'update') {
            // Remove error overlay if there is one
            if (typeof document !== 'undefined') removeErrorOverlay();
            var assets = data.assets.filter(function(asset) {
                return asset.envHash === HMR_ENV_HASH;
            }); // Handle HMR Update
            var handled = assets.every(function(asset) {
                return asset.type === 'css' || asset.type === 'js' && hmrAcceptCheck(module.bundle.root, asset.id, asset.depsByBundle);
            });
            if (handled) {
                console.clear();
                assets.forEach(function(asset) {
                    hmrApply(module.bundle.root, asset);
                });
                for(var i = 0; i < assetsToAccept.length; i++){
                    var id = assetsToAccept[i][1];
                    if (!acceptedAssets[id]) hmrAcceptRun(assetsToAccept[i][0], id);
                }
            } else window.location.reload();
        }
        if (data.type === 'error') {
            // Log parcel errors to console
            var _iterator = _createForOfIteratorHelper(data.diagnostics.ansi), _step;
            try {
                for(_iterator.s(); !(_step = _iterator.n()).done;){
                    var ansiDiagnostic = _step.value;
                    var stack = ansiDiagnostic.codeframe ? ansiDiagnostic.codeframe : ansiDiagnostic.stack;
                    console.error('🚨 [parcel]: ' + ansiDiagnostic.message + '\n' + stack + '\n\n' + ansiDiagnostic.hints.join('\n'));
                }
            } catch (err) {
                _iterator.e(err);
            } finally{
                _iterator.f();
            }
            if (typeof document !== 'undefined') {
                // Render the fancy html overlay
                removeErrorOverlay();
                var overlay = createErrorOverlay(data.diagnostics.html); // $FlowFixMe
                document.body.appendChild(overlay);
            }
        }
    };
    ws.onerror = function(e) {
        console.error(e.message);
    };
    ws.onclose = function() {
        console.warn('[parcel] 🚨 Connection to the HMR server was lost');
    };
}
function removeErrorOverlay() {
    var overlay = document.getElementById(OVERLAY_ID);
    if (overlay) {
        overlay.remove();
        console.log('[parcel] ✨ Error resolved');
    }
}
function createErrorOverlay(diagnostics) {
    var overlay = document.createElement('div');
    overlay.id = OVERLAY_ID;
    var errorHTML = '<div style="background: black; opacity: 0.85; font-size: 16px; color: white; position: fixed; height: 100%; width: 100%; top: 0px; left: 0px; padding: 30px; font-family: Menlo, Consolas, monospace; z-index: 9999;">';
    var _iterator2 = _createForOfIteratorHelper(diagnostics), _step2;
    try {
        for(_iterator2.s(); !(_step2 = _iterator2.n()).done;){
            var diagnostic = _step2.value;
            var stack = diagnostic.codeframe ? diagnostic.codeframe : diagnostic.stack;
            errorHTML += "\n      <div>\n        <div style=\"font-size: 18px; font-weight: bold; margin-top: 20px;\">\n          \uD83D\uDEA8 ".concat(diagnostic.message, "\n        </div>\n        <pre>").concat(stack, "</pre>\n        <div>\n          ").concat(diagnostic.hints.map(function(hint) {
                return '<div>💡 ' + hint + '</div>';
            }).join(''), "\n        </div>\n        ").concat(diagnostic.documentation ? "<div>\uD83D\uDCDD <a style=\"color: violet\" href=\"".concat(diagnostic.documentation, "\" target=\"_blank\">Learn more</a></div>") : '', "\n      </div>\n    ");
        }
    } catch (err) {
        _iterator2.e(err);
    } finally{
        _iterator2.f();
    }
    errorHTML += '</div>';
    overlay.innerHTML = errorHTML;
    return overlay;
}
function getParents(bundle, id) /*: Array<[ParcelRequire, string]> */ {
    var modules = bundle.modules;
    if (!modules) return [];
    var parents = [];
    var k, d, dep;
    for(k in modules)for(d in modules[k][1]){
        dep = modules[k][1][d];
        if (dep === id || Array.isArray(dep) && dep[dep.length - 1] === id) parents.push([
            bundle,
            k
        ]);
    }
    if (bundle.parent) parents = parents.concat(getParents(bundle.parent, id));
    return parents;
}
function updateLink(link) {
    var newLink = link.cloneNode();
    newLink.onload = function() {
        if (link.parentNode !== null) // $FlowFixMe
        link.parentNode.removeChild(link);
    };
    newLink.setAttribute('href', link.getAttribute('href').split('?')[0] + '?' + Date.now()); // $FlowFixMe
    link.parentNode.insertBefore(newLink, link.nextSibling);
}
var cssTimeout = null;
function reloadCSS() {
    if (cssTimeout) return;
    cssTimeout = setTimeout(function() {
        var links = document.querySelectorAll('link[rel="stylesheet"]');
        for(var i = 0; i < links.length; i++){
            // $FlowFixMe[incompatible-type]
            var href = links[i].getAttribute('href');
            var hostname = getHostname();
            var servedFromHMRServer = hostname === 'localhost' ? new RegExp('^(https?:\\/\\/(0.0.0.0|127.0.0.1)|localhost):' + getPort()).test(href) : href.indexOf(hostname + ':' + getPort());
            var absolute = /^https?:\/\//i.test(href) && href.indexOf(window.location.origin) !== 0 && !servedFromHMRServer;
            if (!absolute) updateLink(links[i]);
        }
        cssTimeout = null;
    }, 50);
}
function hmrApply(bundle, asset) {
    var modules = bundle.modules;
    if (!modules) return;
    if (asset.type === 'css') reloadCSS();
    else if (asset.type === 'js') {
        var deps = asset.depsByBundle[bundle.HMR_BUNDLE_ID];
        if (deps) {
            var fn = new Function('require', 'module', 'exports', asset.output);
            modules[asset.id] = [
                fn,
                deps
            ];
        } else if (bundle.parent) hmrApply(bundle.parent, asset);
    }
}
function hmrAcceptCheck(bundle, id, depsByBundle) {
    var modules = bundle.modules;
    if (!modules) return;
    if (depsByBundle && !depsByBundle[bundle.HMR_BUNDLE_ID]) {
        // If we reached the root bundle without finding where the asset should go,
        // there's nothing to do. Mark as "accepted" so we don't reload the page.
        if (!bundle.parent) return true;
        return hmrAcceptCheck(bundle.parent, id, depsByBundle);
    }
    if (checkedAssets[id]) return true;
    checkedAssets[id] = true;
    var cached = bundle.cache[id];
    assetsToAccept.push([
        bundle,
        id
    ]);
    if (cached && cached.hot && cached.hot._acceptCallbacks.length) return true;
    var parents = getParents(module.bundle.root, id); // If no parents, the asset is new. Prevent reloading the page.
    if (!parents.length) return true;
    return parents.some(function(v) {
        return hmrAcceptCheck(v[0], v[1], null);
    });
}
function hmrAcceptRun(bundle, id) {
    var cached = bundle.cache[id];
    bundle.hotData = {
    };
    if (cached && cached.hot) cached.hot.data = bundle.hotData;
    if (cached && cached.hot && cached.hot._disposeCallbacks.length) cached.hot._disposeCallbacks.forEach(function(cb) {
        cb(bundle.hotData);
    });
    delete bundle.cache[id];
    bundle(id);
    cached = bundle.cache[id];
    if (cached && cached.hot && cached.hot._acceptCallbacks.length) cached.hot._acceptCallbacks.forEach(function(cb) {
        var assetsToAlsoAccept = cb(function() {
            return getParents(module.bundle.root, id);
        });
        if (assetsToAlsoAccept && assetsToAccept.length) // $FlowFixMe[method-unbinding]
        assetsToAccept.push.apply(assetsToAccept, assetsToAlsoAccept);
    });
    acceptedAssets[id] = true;
}

},{}],"hD4hw":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
var _ipfsCore = require("ipfs-core");
var _hlsJs = require("hls.js");
var _hlsJsDefault = parcelHelpers.interopDefault(_hlsJs);
var _hlsjsIpfsLoader = require("hlsjs-ipfs-loader");
var _hlsjsIpfsLoaderDefault = parcelHelpers.interopDefault(_hlsjsIpfsLoader);
'use strict';
let node;
function getUrlParameter(name) {
    name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
    var regex = new RegExp('[\\?&]' + name + '=([^&#]*)');
    var results = regex.exec(location.search);
    return results === null ? null : decodeURIComponent(results[1].replace(/\+/g, ' '));
}
function showStatus(message, hide = false) {
    const status = document.getElementById('status');
    status.classList.toggle("is-hiding", hide);
    status.innerText = message;
}
document.addEventListener('DOMContentLoaded', async ()=>{
    const hash = getUrlParameter("hash");
    const source = getUrlParameter("source") || 'master.m3u8';
    const title = getUrlParameter("title");
    if (title) document.title = title;
    if (hash) {
        document.getElementById("help").style.display = "none";
        const video = document.getElementById('video');
        video.style.display = "block";
        const repoPath = 'ipfs-' + Math.random();
        showStatus("Connecting to IPFS");
        node = await _ipfsCore.create({
            repo: repoPath
        });
        showStatus("Connected");
        _hlsJsDefault.default.DefaultConfig.loader = _hlsjsIpfsLoaderDefault.default;
        _hlsJsDefault.default.DefaultConfig.debug = false;
        if (_hlsJsDefault.default.isSupported()) {
            const hls = new _hlsJsDefault.default();
            hls.config.ipfs = node;
            hls.config.ipfsHash = hash;
            showStatus("Video loading");
            hls.loadSource(source);
            hls.attachMedia(video);
            hls.on(_hlsJsDefault.default.Events.MANIFEST_PARSED, ()=>{
                showStatus("Video loaded", true);
                video.play();
            });
        }
    }
});

},{"ipfs-core":"717cg","hls.js":"lpMGM","hlsjs-ipfs-loader":"7UXcy","@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"717cg":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var index = require('./components/index.js');
var crypto$1 = require('libp2p-crypto');
var isIpfs = require('is-ipfs');
var cid = require('multiformats/cid');
var multiaddr$1 = require('multiaddr');
var PeerId$1 = require('peer-id');
var globSourceImport = require('ipfs-utils/src/files/glob-source.js');
var urlSourceImport = require('ipfs-utils/src/files/url-source.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var crypto__default = /*#__PURE__*/ _interopDefaultLegacy(crypto$1);
var isIpfs__default = /*#__PURE__*/ _interopDefaultLegacy(isIpfs);
var PeerId__default = /*#__PURE__*/ _interopDefaultLegacy(PeerId$1);
var globSourceImport__default = /*#__PURE__*/ _interopDefaultLegacy(globSourceImport);
var urlSourceImport__default = /*#__PURE__*/ _interopDefaultLegacy(urlSourceImport);
const create = index.create;
const crypto = crypto__default['default'];
const isIPFS = isIpfs__default['default'];
const CID = cid.CID;
const multiaddr = multiaddr$1.Multiaddr;
const PeerId = PeerId__default['default'];
const globSource = globSourceImport__default['default'];
const urlSource = urlSourceImport__default['default'];
exports.CID = CID;
exports.PeerId = PeerId;
exports.create = create;
exports.crypto = crypto;
exports.globSource = globSource;
exports.isIPFS = isIPFS;
exports.multiaddr = multiaddr;
exports.urlSource = urlSource;

},{"./components/index.js":"iLRfG","libp2p-crypto":"hsRcr","is-ipfs":"2Nskw","multiformats/cid":"fJJnW","multiaddr":"kOPrF","peer-id":"4VGWt","ipfs-utils/src/files/glob-source.js":"joWnX","ipfs-utils/src/files/url-source.js":"hdaYP"}],"iLRfG":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var mergeOpts = require('merge-options');
var env_js = require('ipfs-utils/src/env.js');
var debug = require('debug');
var errCode = require('err-code');
var ipfsUnixfs = require('ipfs-unixfs');
var dagPB = require('@ipld/dag-pb');
var dagCBOR = require('@ipld/dag-cbor');
var identity = require('multiformats/hashes/identity');
var basics = require('multiformats/basics');
var initAssets = require('ipfs-core-config/init-assets');
var errors = require('../errors.js');
var fromString = require('uint8arrays/from-string');
var start = require('./start.js');
var stop = require('./stop.js');
var dns = require('./dns.js');
var isOnline = require('./is-online.js');
var resolve = require('./resolve.js');
var index = require('./pin/index.js');
var ipns = require('./ipns.js');
var index$2 = require('./name/index.js');
var index$4 = require('./refs/index.js');
var local = require('./refs/local.js');
var index$6 = require('./bitswap/index.js');
var index$7 = require('./bootstrap/index.js');
var index$1 = require('./block/index.js');
var root = require('./root.js');
var version = require('./version.js');
var id1 = require('./id.js');
var index$8 = require('./config/index.js');
var index$3 = require('./dag/index.js');
var preload = require('../preload.js');
var mfsPreload = require('../mfs-preload.js');
var index$5 = require('./files/index.js');
var index$9 = require('./key/index.js');
var index$a = require('./object/index.js');
var index$b = require('./repo/index.js');
var index$c = require('./stats/index.js');
var storage = require('./storage.js');
var network = require('./network.js');
var service = require('../utils/service.js');
var index$d = require('./swarm/index.js');
var ping = require('./ping.js');
var dht = require('./dht.js');
var pubsub = require('./pubsub.js');
var multicodecs = require('ipfs-core-utils/multicodecs');
var multihashes = require('ipfs-core-utils/multihashes');
var multibases = require('ipfs-core-utils/multibases');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n['default'] = e;
    return Object.freeze(n);
}
var mergeOpts__default = /*#__PURE__*/ _interopDefaultLegacy(mergeOpts);
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
var dagPB__namespace = /*#__PURE__*/ _interopNamespace(dagPB);
var dagCBOR__namespace = /*#__PURE__*/ _interopNamespace(dagCBOR);
const mergeOptions = mergeOpts__default['default'].bind({
    ignoreUndefined: true
});
const log = debug__default['default']('ipfs');
class IPFS {
    constructor({ print: print1 , storage: storage1 , codecs , options: options1  }){
        const { peerId , repo , keychain  } = storage1;
        const network$1 = service.Service.create(network.Network);
        const preload$1 = preload.createPreloader(options1.preload);
        const dns$1 = dns.createDns();
        const isOnline$1 = isOnline.createIsOnline({
            network: network$1
        });
        const ipns$1 = new ipns.IPNSAPI(options1);
        const multihashHashers = Object.values(basics.hashes);
        (options1.ipld && options1.ipld.hashers ? options1.ipld.hashers : []).forEach((hasher)=>multihashHashers.push(hasher)
        );
        this.hashers = new multihashes.Multihashes({
            hashers: multihashHashers,
            loadHasher: options1.ipld && options1.ipld.loadHasher
        });
        const multibaseCodecs = Object.values(basics.bases);
        (options1.ipld && options1.ipld.bases ? options1.ipld.bases : []).forEach((base)=>multibaseCodecs.push(base)
        );
        this.bases = new multibases.Multibases({
            bases: multibaseCodecs,
            loadBase: options1.ipld && options1.ipld.loadBase
        });
        const pin = new index.PinAPI({
            repo,
            codecs
        });
        const block = new index$1.BlockAPI({
            codecs,
            hashers: this.hashers,
            preload: preload$1,
            repo
        });
        const name = new index$2.NameAPI({
            dns: dns$1,
            ipns: ipns$1,
            repo,
            codecs,
            peerId,
            isOnline: isOnline$1,
            keychain,
            options: options1
        });
        const resolve$1 = resolve.createResolve({
            repo,
            codecs,
            bases: this.bases,
            name
        });
        const dag = new index$3.DagAPI({
            repo,
            codecs,
            hashers: this.hashers,
            preload: preload$1
        });
        const refs = Object.assign(index$4.createRefs({
            repo,
            codecs,
            resolve: resolve$1,
            preload: preload$1
        }), {
            local: local.createLocal({
                repo: storage1.repo
            })
        });
        const { add , addAll , cat , get , ls  } = new root.RootAPI({
            preload: preload$1,
            repo,
            options: options1.EXPERIMENTAL
        });
        const files = index$5.createFiles({
            repo,
            preload: preload$1,
            hashers: this.hashers,
            options: options1
        });
        const mfsPreload$1 = mfsPreload.createMfsPreloader({
            files,
            preload: preload$1,
            options: options1.preload
        });
        this.preload = preload$1;
        this.name = name;
        this.ipns = ipns$1;
        this.pin = pin;
        this.resolve = resolve$1;
        this.block = block;
        this.refs = refs;
        this.start = start.createStart({
            network: network$1,
            peerId,
            repo,
            preload: preload$1,
            ipns: ipns$1,
            mfsPreload: mfsPreload$1,
            print: print1,
            keychain,
            options: options1
        });
        this.stop = stop.createStop({
            network: network$1,
            preload: preload$1,
            mfsPreload: mfsPreload$1,
            ipns: ipns$1,
            repo
        });
        this.dht = dht.createDht({
            network: network$1,
            repo
        });
        this.pubsub = pubsub.createPubsub({
            network: network$1,
            config: options1.config
        });
        this.dns = dns$1;
        this.isOnline = isOnline$1;
        this.id = id1.createId({
            network: network$1,
            peerId
        });
        this.version = version.createVersion({
            repo
        });
        this.bitswap = new index$6.BitswapAPI({
            network: network$1
        });
        this.bootstrap = new index$7.BootstrapAPI({
            repo
        });
        this.config = index$8.createConfig({
            repo
        });
        this.ping = ping.createPing({
            network: network$1
        });
        this.add = add;
        this.addAll = addAll;
        this.cat = cat;
        this.get = get;
        this.ls = ls;
        this.dag = dag;
        this.files = files;
        this.key = new index$9.KeyAPI({
            keychain
        });
        this.object = new index$a.ObjectAPI({
            preload: preload$1,
            codecs,
            repo
        });
        this.repo = new index$b.RepoAPI({
            repo,
            hashers: this.hashers
        });
        this.stats = new index$c.StatsAPI({
            repo,
            network: network$1
        });
        this.swarm = new index$d.SwarmAPI({
            network: network$1
        });
        Object.defineProperty(this, 'libp2p', {
            get () {
                const net = network$1.try();
                return net ? net.libp2p : undefined;
            }
        });
        const notImplemented = ()=>Promise.reject(errCode__default['default'](new Error('Not implemented'), 'ERR_NOT_IMPLEMENTED'))
        ;
        const notImplementedIter = async function*() {
            throw errCode__default['default'](new Error('Not implemented'), 'ERR_NOT_IMPLEMENTED');
        };
        this.commands = notImplemented;
        this.diag = {
            cmds: notImplemented,
            net: notImplemented,
            sys: notImplemented
        };
        this.log = {
            level: notImplemented,
            ls: notImplemented,
            tail: notImplementedIter
        };
        this.mount = notImplemented;
        this.codecs = codecs;
    }
    async init() {
        throw new errors.AlreadyInitializedError();
    }
}
const addEmptyDir = async (ipfs)=>{
    const buf = dagPB__namespace.encode({
        Data: new ipfsUnixfs.UnixFS({
            type: 'directory'
        }).marshal(),
        Links: []
    });
    const cid = await ipfs.block.put(buf, {
        mhtype: 'sha2-256',
        format: 'dag-pb'
    });
    await ipfs.pin.add(cid);
    return cid;
};
const getDefaultOptions = ()=>({
        start: true,
        EXPERIMENTAL: {
        },
        preload: {
            enabled: !env_js.isTest,
            addresses: [
                '/dns4/node0.preload.ipfs.io/https',
                '/dns4/node1.preload.ipfs.io/https',
                '/dns4/node2.preload.ipfs.io/https',
                '/dns4/node3.preload.ipfs.io/https'
            ]
        }
    })
;
async function create(options = {
}) {
    options = mergeOptions(getDefaultOptions(), options);
    const initOptions = options.init || {
    };
    const id2 = {
        name: identity.identity.name,
        code: identity.identity.code,
        encode: (id)=>id
        ,
        decode: (id)=>id
    };
    const blockCodecs = Object.values(basics.codecs);
    [
        dagPB__namespace,
        dagCBOR__namespace,
        id2
    ].concat(options.ipld && options.ipld.codecs || []).forEach((codec)=>blockCodecs.push(codec)
    );
    const multicodecs$1 = new multicodecs.Multicodecs({
        codecs: blockCodecs,
        loadCodec: options.ipld && options.ipld.loadCodec
    });
    const print = options.silent ? log : console.log;
    const storage$1 = await storage.Storage.start(print, multicodecs$1, options);
    const config = await storage$1.repo.config.getAll();
    const ipfs = new IPFS({
        storage: storage$1,
        print,
        codecs: multicodecs$1,
        options: {
            ...options,
            config
        }
    });
    await ipfs.preload.start();
    ipfs.ipns.startOffline(storage$1);
    if (storage$1.isNew && !initOptions.emptyRepo) {
        const cid = await addEmptyDir(ipfs);
        log('adding default assets');
        await initAssets.initAssets({
            addAll: ipfs.addAll,
            print
        });
        log('initializing IPNS keyspace');
        await ipfs.ipns.initializeKeyspace(storage$1.peerId.privKey, fromString.fromString(`/ipfs/${cid}`));
    }
    if (options.start !== false) await ipfs.start();
    return ipfs;
}
exports.create = create;

},{"merge-options":"8VjFj","ipfs-utils/src/env.js":"42nOp","debug":"lWlU4","err-code":"eQvyh","ipfs-unixfs":"fttXc","@ipld/dag-pb":"e9gy2","@ipld/dag-cbor":"kSG7F","multiformats/hashes/identity":"7Cndu","multiformats/basics":"7w1HC","ipfs-core-config/init-assets":"7SacM","../errors.js":"itpk8","uint8arrays/from-string":"lo45E","./start.js":"2jhMT","./stop.js":"l8lhl","./dns.js":"lSUS4","./is-online.js":"h8Bpc","./resolve.js":"iTKY7","./pin/index.js":"eF5jW","./ipns.js":"bBMH7","./name/index.js":"deZ7j","./refs/index.js":"baWA4","./refs/local.js":"dlxkt","./bitswap/index.js":"8MrnJ","./bootstrap/index.js":"dqIZu","./block/index.js":"3VMpM","./root.js":"9Zlor","./version.js":"4Kit3","./id.js":"9peBJ","./config/index.js":"8ed7u","./dag/index.js":"6CCMQ","../preload.js":"9hQTT","../mfs-preload.js":"ii7Xb","./files/index.js":"lvLJk","./key/index.js":"hjU4j","./object/index.js":"6z811","./repo/index.js":"fcFbR","./stats/index.js":"5ncKr","./storage.js":"cFB52","./network.js":"5ljCS","../utils/service.js":"e1v7I","./swarm/index.js":"cYhgJ","./ping.js":"fbyky","./dht.js":"1NaIw","./pubsub.js":"4jVcM","ipfs-core-utils/multicodecs":"hQFTl","ipfs-core-utils/multihashes":"9DlWG","ipfs-core-utils/multibases":"a70gY"}],"8VjFj":[function(require,module,exports) {
'use strict';
const isOptionObject = require('is-plain-obj');
const { hasOwnProperty  } = Object.prototype;
const { propertyIsEnumerable  } = Object;
const defineProperty = (object, name, value)=>Object.defineProperty(object, name, {
        value,
        writable: true,
        enumerable: true,
        configurable: true
    })
;
const globalThis = this;
const defaultMergeOptions = {
    concatArrays: false,
    ignoreUndefined: false
};
const getEnumerableOwnPropertyKeys = (value)=>{
    const keys = [];
    for(const key in value)if (hasOwnProperty.call(value, key)) keys.push(key);
    /* istanbul ignore else  */ if (Object.getOwnPropertySymbols) {
        const symbols = Object.getOwnPropertySymbols(value);
        for (const symbol of symbols)if (propertyIsEnumerable.call(value, symbol)) keys.push(symbol);
    }
    return keys;
};
function clone(value) {
    if (Array.isArray(value)) return cloneArray(value);
    if (isOptionObject(value)) return cloneOptionObject(value);
    return value;
}
function cloneArray(array) {
    const result = array.slice(0, 0);
    getEnumerableOwnPropertyKeys(array).forEach((key)=>{
        defineProperty(result, key, clone(array[key]));
    });
    return result;
}
function cloneOptionObject(object) {
    const result = Object.getPrototypeOf(object) === null ? Object.create(null) : {
    };
    getEnumerableOwnPropertyKeys(object).forEach((key)=>{
        defineProperty(result, key, clone(object[key]));
    });
    return result;
}
/**
 * @param {*} merged already cloned
 * @param {*} source something to merge
 * @param {string[]} keys keys to merge
 * @param {Object} config Config Object
 * @returns {*} cloned Object
 */ const mergeKeys = (merged, source, keys, config)=>{
    keys.forEach((key)=>{
        if (typeof source[key] === 'undefined' && config.ignoreUndefined) return;
        // Do not recurse into prototype chain of merged
        if (key in merged && merged[key] !== Object.getPrototypeOf(merged)) defineProperty(merged, key, merge(merged[key], source[key], config));
        else defineProperty(merged, key, clone(source[key]));
    });
    return merged;
};
/**
 * @param {*} merged already cloned
 * @param {*} source something to merge
 * @param {Object} config Config Object
 * @returns {*} cloned Object
 *
 * see [Array.prototype.concat ( ...arguments )](http://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.concat)
 */ const concatArrays = (merged, source, config)=>{
    let result = merged.slice(0, 0);
    let resultIndex = 0;
    [
        merged,
        source
    ].forEach((array)=>{
        const indices = [];
        // `result.concat(array)` with cloning
        for(let k = 0; k < array.length; k++){
            if (!hasOwnProperty.call(array, k)) continue;
            indices.push(String(k));
            if (array === merged) // Already cloned
            defineProperty(result, resultIndex++, array[k]);
            else defineProperty(result, resultIndex++, clone(array[k]));
        }
        // Merge non-index keys
        result = mergeKeys(result, array, getEnumerableOwnPropertyKeys(array).filter((key)=>!indices.includes(key)
        ), config);
    });
    return result;
};
/**
 * @param {*} merged already cloned
 * @param {*} source something to merge
 * @param {Object} config Config Object
 * @returns {*} cloned Object
 */ function merge(merged, source, config) {
    if (config.concatArrays && Array.isArray(merged) && Array.isArray(source)) return concatArrays(merged, source, config);
    if (!isOptionObject(source) || !isOptionObject(merged)) return clone(source);
    return mergeKeys(merged, source, getEnumerableOwnPropertyKeys(source), config);
}
module.exports = function(...options) {
    const config = merge(clone(defaultMergeOptions), this !== globalThis && this || {
    }, defaultMergeOptions);
    let merged = {
        _: {
        }
    };
    for (const option of options){
        if (option === undefined) continue;
        if (!isOptionObject(option)) throw new TypeError('`' + option + '` is not an Option Object');
        merged = merge(merged, {
            _: option
        }, config);
    }
    return merged._;
};

},{"is-plain-obj":"96KLh"}],"96KLh":[function(require,module,exports) {
'use strict';
module.exports = (value)=>{
    if (Object.prototype.toString.call(value) !== '[object Object]') return false;
    const prototype = Object.getPrototypeOf(value);
    return prototype === null || prototype === Object.prototype;
};

},{}],"42nOp":[function(require,module,exports) {
var process = require("process");
'use strict';
const isElectron = require('is-electron');
const IS_ENV_WITH_DOM = typeof window === 'object' && typeof document === 'object' && document.nodeType === 9;
// @ts-ignore
const IS_ELECTRON = isElectron();
const IS_BROWSER = IS_ENV_WITH_DOM && !IS_ELECTRON;
const IS_ELECTRON_MAIN = IS_ELECTRON && !IS_ENV_WITH_DOM;
const IS_ELECTRON_RENDERER = IS_ELECTRON && IS_ENV_WITH_DOM;
const IS_NODE = typeof require === 'function' && typeof process !== 'undefined' && typeof process.release !== 'undefined' && process.release.name === 'node' && !IS_ELECTRON;
// @ts-ignore - we either ignore worker scope or dom scope
const IS_WEBWORKER = typeof importScripts === 'function' && typeof self !== 'undefined' && typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope;
const IS_TEST = typeof process !== 'undefined' && typeof process.env !== 'undefined' && false;
const IS_REACT_NATIVE = typeof navigator !== 'undefined' && navigator.product === 'ReactNative';
module.exports = {
    isTest: IS_TEST,
    isElectron: IS_ELECTRON,
    isElectronMain: IS_ELECTRON_MAIN,
    isElectronRenderer: IS_ELECTRON_RENDERER,
    isNode: IS_NODE,
    /**
   * Detects browser main thread  **NOT** web worker or service worker
   */ isBrowser: IS_BROWSER,
    isWebWorker: IS_WEBWORKER,
    isEnvWithDom: IS_ENV_WITH_DOM,
    isReactNative: IS_REACT_NATIVE
};

},{"process":"lDnB8","is-electron":"ijHtZ"}],"lDnB8":[function(require,module,exports) {
// shim for using process in browser
var process = module.exports = {
};
// cached from whatever global is present so that test runners that stub it
// don't break things.  But we need to wrap it in a try catch in case it is
// wrapped in strict mode code which doesn't define any globals.  It's inside a
// function because try/catches deoptimize in certain engines.
var cachedSetTimeout;
var cachedClearTimeout;
function defaultSetTimout() {
    throw new Error('setTimeout has not been defined');
}
function defaultClearTimeout() {
    throw new Error('clearTimeout has not been defined');
}
(function() {
    try {
        if (typeof setTimeout === 'function') cachedSetTimeout = setTimeout;
        else cachedSetTimeout = defaultSetTimout;
    } catch (e) {
        cachedSetTimeout = defaultSetTimout;
    }
    try {
        if (typeof clearTimeout === 'function') cachedClearTimeout = clearTimeout;
        else cachedClearTimeout = defaultClearTimeout;
    } catch (e1) {
        cachedClearTimeout = defaultClearTimeout;
    }
})();
function runTimeout(fun) {
    if (cachedSetTimeout === setTimeout) //normal enviroments in sane situations
    return setTimeout(fun, 0);
    // if setTimeout wasn't available but was latter defined
    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
        cachedSetTimeout = setTimeout;
        return setTimeout(fun, 0);
    }
    try {
        // when when somebody has screwed with setTimeout but no I.E. maddness
        return cachedSetTimeout(fun, 0);
    } catch (e) {
        try {
            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
            return cachedSetTimeout.call(null, fun, 0);
        } catch (e) {
            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
            return cachedSetTimeout.call(this, fun, 0);
        }
    }
}
function runClearTimeout(marker) {
    if (cachedClearTimeout === clearTimeout) //normal enviroments in sane situations
    return clearTimeout(marker);
    // if clearTimeout wasn't available but was latter defined
    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
        cachedClearTimeout = clearTimeout;
        return clearTimeout(marker);
    }
    try {
        // when when somebody has screwed with setTimeout but no I.E. maddness
        return cachedClearTimeout(marker);
    } catch (e) {
        try {
            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally
            return cachedClearTimeout.call(null, marker);
        } catch (e) {
            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
            // Some versions of I.E. have different rules for clearTimeout vs setTimeout
            return cachedClearTimeout.call(this, marker);
        }
    }
}
var queue = [];
var draining = false;
var currentQueue;
var queueIndex = -1;
function cleanUpNextTick() {
    if (!draining || !currentQueue) return;
    draining = false;
    if (currentQueue.length) queue = currentQueue.concat(queue);
    else queueIndex = -1;
    if (queue.length) drainQueue();
}
function drainQueue() {
    if (draining) return;
    var timeout = runTimeout(cleanUpNextTick);
    draining = true;
    var len = queue.length;
    while(len){
        currentQueue = queue;
        queue = [];
        while(++queueIndex < len)if (currentQueue) currentQueue[queueIndex].run();
        queueIndex = -1;
        len = queue.length;
    }
    currentQueue = null;
    draining = false;
    runClearTimeout(timeout);
}
process.nextTick = function(fun) {
    var args = new Array(arguments.length - 1);
    if (arguments.length > 1) for(var i = 1; i < arguments.length; i++)args[i - 1] = arguments[i];
    queue.push(new Item(fun, args));
    if (queue.length === 1 && !draining) runTimeout(drainQueue);
};
// v8 likes predictible objects
function Item(fun, array) {
    this.fun = fun;
    this.array = array;
}
Item.prototype.run = function() {
    this.fun.apply(null, this.array);
};
process.title = 'browser';
process.browser = true;
process.env = {
};
process.argv = [];
process.version = ''; // empty string to avoid regexp issues
process.versions = {
};
function noop() {
}
process.on = noop;
process.addListener = noop;
process.once = noop;
process.off = noop;
process.removeListener = noop;
process.removeAllListeners = noop;
process.emit = noop;
process.prependListener = noop;
process.prependOnceListener = noop;
process.listeners = function(name) {
    return [];
};
process.binding = function(name) {
    throw new Error('process.binding is not supported');
};
process.cwd = function() {
    return '/';
};
process.chdir = function(dir) {
    throw new Error('process.chdir is not supported');
};
process.umask = function() {
    return 0;
};

},{}],"ijHtZ":[function(require,module,exports) {
var process = require("process");
// https://github.com/electron/electron/issues/2288
function isElectron() {
    // Renderer process
    if (typeof window !== 'undefined' && typeof window.process === 'object' && window.process.type === 'renderer') return true;
    // Main process
    if (typeof process !== 'undefined' && typeof process.versions === 'object' && !!process.versions.electron) return true;
    // Detect the user agent when the `nodeIntegration` option is set to false
    if (typeof navigator === 'object' && typeof navigator.userAgent === 'string' && navigator.userAgent.indexOf('Electron') >= 0) return true;
    return false;
}
module.exports = isElectron;

},{"process":"lDnB8"}],"lWlU4":[function(require,module,exports) {
var process = require("process");
/* eslint-env browser */ /**
 * This is the web browser implementation of `debug()`.
 */ exports.formatArgs = formatArgs;
exports.save = save;
exports.load = load;
exports.useColors = useColors;
exports.storage = localstorage();
exports.destroy = (()=>{
    let warned = false;
    return ()=>{
        if (!warned) {
            warned = true;
            console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');
        }
    };
})();
/**
 * Colors.
 */ exports.colors = [
    '#0000CC',
    '#0000FF',
    '#0033CC',
    '#0033FF',
    '#0066CC',
    '#0066FF',
    '#0099CC',
    '#0099FF',
    '#00CC00',
    '#00CC33',
    '#00CC66',
    '#00CC99',
    '#00CCCC',
    '#00CCFF',
    '#3300CC',
    '#3300FF',
    '#3333CC',
    '#3333FF',
    '#3366CC',
    '#3366FF',
    '#3399CC',
    '#3399FF',
    '#33CC00',
    '#33CC33',
    '#33CC66',
    '#33CC99',
    '#33CCCC',
    '#33CCFF',
    '#6600CC',
    '#6600FF',
    '#6633CC',
    '#6633FF',
    '#66CC00',
    '#66CC33',
    '#9900CC',
    '#9900FF',
    '#9933CC',
    '#9933FF',
    '#99CC00',
    '#99CC33',
    '#CC0000',
    '#CC0033',
    '#CC0066',
    '#CC0099',
    '#CC00CC',
    '#CC00FF',
    '#CC3300',
    '#CC3333',
    '#CC3366',
    '#CC3399',
    '#CC33CC',
    '#CC33FF',
    '#CC6600',
    '#CC6633',
    '#CC9900',
    '#CC9933',
    '#CCCC00',
    '#CCCC33',
    '#FF0000',
    '#FF0033',
    '#FF0066',
    '#FF0099',
    '#FF00CC',
    '#FF00FF',
    '#FF3300',
    '#FF3333',
    '#FF3366',
    '#FF3399',
    '#FF33CC',
    '#FF33FF',
    '#FF6600',
    '#FF6633',
    '#FF9900',
    '#FF9933',
    '#FFCC00',
    '#FFCC33'
];
/**
 * Currently only WebKit-based Web Inspectors, Firefox >= v31,
 * and the Firebug extension (any Firefox version) are known
 * to support "%c" CSS customizations.
 *
 * TODO: add a `localStorage` variable to explicitly enable/disable colors
 */ // eslint-disable-next-line complexity
function useColors() {
    // NB: In an Electron preload script, document will be defined but not fully
    // initialized. Since we know we're in Chrome, we'll just detect this case
    // explicitly
    if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) return true;
    // Internet Explorer and Edge do not support colors.
    if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) return false;
    // Is webkit? http://stackoverflow.com/a/16459606/376773
    // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
    return typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || typeof window !== 'undefined' && window.console && (window.console.firebug || window.console.exception && window.console.table) || typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31 || typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/);
}
/**
 * Colorize log arguments if enabled.
 *
 * @api public
 */ function formatArgs(args) {
    args[0] = (this.useColors ? '%c' : '') + this.namespace + (this.useColors ? ' %c' : ' ') + args[0] + (this.useColors ? '%c ' : ' ') + '+' + module.exports.humanize(this.diff);
    if (!this.useColors) return;
    const c = 'color: ' + this.color;
    args.splice(1, 0, c, 'color: inherit');
    // The final "%c" is somewhat tricky, because there could be other
    // arguments passed either before or after the %c, so we need to
    // figure out the correct index to insert the CSS into
    let index = 0;
    let lastC = 0;
    args[0].replace(/%[a-zA-Z%]/g, (match)=>{
        if (match === '%%') return;
        index++;
        if (match === '%c') // We only are interested in the *last* %c
        // (the user may have provided their own)
        lastC = index;
    });
    args.splice(lastC, 0, c);
}
/**
 * Invokes `console.debug()` when available.
 * No-op when `console.debug` is not a "function".
 * If `console.debug` is not available, falls back
 * to `console.log`.
 *
 * @api public
 */ exports.log = console.debug || console.log || (()=>{
});
/**
 * Save `namespaces`.
 *
 * @param {String} namespaces
 * @api private
 */ function save(namespaces) {
    try {
        if (namespaces) exports.storage.setItem('debug', namespaces);
        else exports.storage.removeItem('debug');
    } catch (error) {
    // Swallow
    // XXX (@Qix-) should we be logging these?
    }
}
/**
 * Load `namespaces`.
 *
 * @return {String} returns the previously persisted debug modes
 * @api private
 */ function load() {
    let r;
    try {
        r = exports.storage.getItem('debug');
    } catch (error) {
    // Swallow
    // XXX (@Qix-) should we be logging these?
    }
    // If debug isn't set in LS, and we're in Electron, try to load $DEBUG
    if (!r && typeof process !== 'undefined' && 'env' in process) r = undefined;
    return r;
}
/**
 * Localstorage attempts to return the localstorage.
 *
 * This is necessary because safari throws
 * when a user disables cookies/localstorage
 * and you attempt to access it.
 *
 * @return {LocalStorage}
 * @api private
 */ function localstorage() {
    try {
        // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context
        // The Browser also has localStorage in the global context.
        return localStorage;
    } catch (error) {
    // Swallow
    // XXX (@Qix-) should we be logging these?
    }
}
module.exports = require('./common')(exports);
const { formatters  } = module.exports;
/**
 * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
 */ formatters.j = function(v) {
    try {
        return JSON.stringify(v);
    } catch (error) {
        return '[UnexpectedJSONParseError]: ' + error.message;
    }
};

},{"process":"lDnB8","./common":"gT61T"}],"gT61T":[function(require,module,exports) {
/**
 * This is the common logic for both the Node.js and web browser
 * implementations of `debug()`.
 */ function setup(env) {
    createDebug.debug = createDebug;
    createDebug.default = createDebug;
    createDebug.coerce = coerce;
    createDebug.disable = disable;
    createDebug.enable = enable;
    createDebug.enabled = enabled;
    createDebug.humanize = require('ms');
    createDebug.destroy = destroy;
    Object.keys(env).forEach((key)=>{
        createDebug[key] = env[key];
    });
    /**
	* The currently active debug mode names, and names to skip.
	*/ createDebug.names = [];
    createDebug.skips = [];
    /**
	* Map of special "%n" handling functions, for the debug "format" argument.
	*
	* Valid key names are a single, lower or upper-case letter, i.e. "n" and "N".
	*/ createDebug.formatters = {
    };
    /**
	* Selects a color for a debug namespace
	* @param {String} namespace The namespace string for the for the debug instance to be colored
	* @return {Number|String} An ANSI color code for the given namespace
	* @api private
	*/ function selectColor(namespace) {
        let hash = 0;
        for(let i = 0; i < namespace.length; i++){
            hash = (hash << 5) - hash + namespace.charCodeAt(i);
            hash |= 0; // Convert to 32bit integer
        }
        return createDebug.colors[Math.abs(hash) % createDebug.colors.length];
    }
    createDebug.selectColor = selectColor;
    /**
	* Create a debugger with the given `namespace`.
	*
	* @param {String} namespace
	* @return {Function}
	* @api public
	*/ function createDebug(namespace) {
        let prevTime;
        let enableOverride = null;
        let namespacesCache;
        let enabledCache;
        function debug(...args) {
            // Disabled?
            if (!debug.enabled) return;
            const self = debug;
            // Set `diff` timestamp
            const curr = Number(new Date());
            const ms = curr - (prevTime || curr);
            self.diff = ms;
            self.prev = prevTime;
            self.curr = curr;
            prevTime = curr;
            args[0] = createDebug.coerce(args[0]);
            if (typeof args[0] !== 'string') // Anything else let's inspect with %O
            args.unshift('%O');
            // Apply any `formatters` transformations
            let index = 0;
            args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format)=>{
                // If we encounter an escaped % then don't increase the array index
                if (match === '%%') return '%';
                index++;
                const formatter = createDebug.formatters[format];
                if (typeof formatter === 'function') {
                    const val = args[index];
                    match = formatter.call(self, val);
                    // Now we need to remove `args[index]` since it's inlined in the `format`
                    args.splice(index, 1);
                    index--;
                }
                return match;
            });
            // Apply env-specific formatting (colors, etc.)
            createDebug.formatArgs.call(self, args);
            const logFn = self.log || createDebug.log;
            logFn.apply(self, args);
        }
        debug.namespace = namespace;
        debug.useColors = createDebug.useColors();
        debug.color = createDebug.selectColor(namespace);
        debug.extend = extend;
        debug.destroy = createDebug.destroy; // XXX Temporary. Will be removed in the next major release.
        Object.defineProperty(debug, 'enabled', {
            enumerable: true,
            configurable: false,
            get: ()=>{
                if (enableOverride !== null) return enableOverride;
                if (namespacesCache !== createDebug.namespaces) {
                    namespacesCache = createDebug.namespaces;
                    enabledCache = createDebug.enabled(namespace);
                }
                return enabledCache;
            },
            set: (v)=>{
                enableOverride = v;
            }
        });
        // Env-specific initialization logic for debug instances
        if (typeof createDebug.init === 'function') createDebug.init(debug);
        return debug;
    }
    function extend(namespace, delimiter) {
        const newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace);
        newDebug.log = this.log;
        return newDebug;
    }
    /**
	* Enables a debug mode by namespaces. This can include modes
	* separated by a colon and wildcards.
	*
	* @param {String} namespaces
	* @api public
	*/ function enable(namespaces) {
        createDebug.save(namespaces);
        createDebug.namespaces = namespaces;
        createDebug.names = [];
        createDebug.skips = [];
        let i;
        const split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
        const len = split.length;
        for(i = 0; i < len; i++){
            if (!split[i]) continue;
            namespaces = split[i].replace(/\*/g, '.*?');
            if (namespaces[0] === '-') createDebug.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
            else createDebug.names.push(new RegExp('^' + namespaces + '$'));
        }
    }
    /**
	* Disable debug output.
	*
	* @return {String} namespaces
	* @api public
	*/ function disable() {
        const namespaces = [
            ...createDebug.names.map(toNamespace),
            ...createDebug.skips.map(toNamespace).map((namespace)=>'-' + namespace
            )
        ].join(',');
        createDebug.enable('');
        return namespaces;
    }
    /**
	* Returns true if the given mode name is enabled, false otherwise.
	*
	* @param {String} name
	* @return {Boolean}
	* @api public
	*/ function enabled(name) {
        if (name[name.length - 1] === '*') return true;
        let i;
        let len;
        for(i = 0, len = createDebug.skips.length; i < len; i++){
            if (createDebug.skips[i].test(name)) return false;
        }
        for(i = 0, len = createDebug.names.length; i < len; i++){
            if (createDebug.names[i].test(name)) return true;
        }
        return false;
    }
    /**
	* Convert regexp to namespace
	*
	* @param {RegExp} regxep
	* @return {String} namespace
	* @api private
	*/ function toNamespace(regexp) {
        return regexp.toString().substring(2, regexp.toString().length - 2).replace(/\.\*\?$/, '*');
    }
    /**
	* Coerce `val`.
	*
	* @param {Mixed} val
	* @return {Mixed}
	* @api private
	*/ function coerce(val) {
        if (val instanceof Error) return val.stack || val.message;
        return val;
    }
    /**
	* XXX DO NOT USE. This is a temporary stub function.
	* XXX It WILL be removed in the next major release.
	*/ function destroy() {
        console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');
    }
    createDebug.enable(createDebug.load());
    return createDebug;
}
module.exports = setup;

},{"ms":"8Hh5e"}],"8Hh5e":[function(require,module,exports) {
/**
 * Helpers.
 */ var s = 1000;
var m = s * 60;
var h = m * 60;
var d = h * 24;
var w = d * 7;
var y = d * 365.25;
/**
 * Parse or format the given `val`.
 *
 * Options:
 *
 *  - `long` verbose formatting [false]
 *
 * @param {String|Number} val
 * @param {Object} [options]
 * @throws {Error} throw an error if val is not a non-empty string or a number
 * @return {String|Number}
 * @api public
 */ module.exports = function(val, options) {
    options = options || {
    };
    var type = typeof val;
    if (type === 'string' && val.length > 0) return parse(val);
    else if (type === 'number' && isFinite(val)) return options.long ? fmtLong(val) : fmtShort(val);
    throw new Error('val is not a non-empty string or a valid number. val=' + JSON.stringify(val));
};
/**
 * Parse the given `str` and return milliseconds.
 *
 * @param {String} str
 * @return {Number}
 * @api private
 */ function parse(str) {
    str = String(str);
    if (str.length > 100) return;
    var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(str);
    if (!match) return;
    var n = parseFloat(match[1]);
    var type = (match[2] || 'ms').toLowerCase();
    switch(type){
        case 'years':
        case 'year':
        case 'yrs':
        case 'yr':
        case 'y':
            return n * y;
        case 'weeks':
        case 'week':
        case 'w':
            return n * w;
        case 'days':
        case 'day':
        case 'd':
            return n * d;
        case 'hours':
        case 'hour':
        case 'hrs':
        case 'hr':
        case 'h':
            return n * h;
        case 'minutes':
        case 'minute':
        case 'mins':
        case 'min':
        case 'm':
            return n * m;
        case 'seconds':
        case 'second':
        case 'secs':
        case 'sec':
        case 's':
            return n * s;
        case 'milliseconds':
        case 'millisecond':
        case 'msecs':
        case 'msec':
        case 'ms':
            return n;
        default:
            return undefined;
    }
}
/**
 * Short format for `ms`.
 *
 * @param {Number} ms
 * @return {String}
 * @api private
 */ function fmtShort(ms) {
    var msAbs = Math.abs(ms);
    if (msAbs >= d) return Math.round(ms / d) + 'd';
    if (msAbs >= h) return Math.round(ms / h) + 'h';
    if (msAbs >= m) return Math.round(ms / m) + 'm';
    if (msAbs >= s) return Math.round(ms / s) + 's';
    return ms + 'ms';
}
/**
 * Long format for `ms`.
 *
 * @param {Number} ms
 * @return {String}
 * @api private
 */ function fmtLong(ms) {
    var msAbs = Math.abs(ms);
    if (msAbs >= d) return plural(ms, msAbs, d, 'day');
    if (msAbs >= h) return plural(ms, msAbs, h, 'hour');
    if (msAbs >= m) return plural(ms, msAbs, m, 'minute');
    if (msAbs >= s) return plural(ms, msAbs, s, 'second');
    return ms + ' ms';
}
/**
 * Pluralization helper.
 */ function plural(ms, msAbs, n, name) {
    var isPlural = msAbs >= n * 1.5;
    return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');
}

},{}],"eQvyh":[function(require,module,exports) {
'use strict';
/**
 * @typedef {{ [key: string]: any }} Extensions
 * @typedef {Error} Err
 * @property {string} message
 */ /**
 *
 * @param {Error} obj
 * @param {Extensions} props
 * @returns {Error & Extensions}
 */ function assign(obj, props) {
    for(const key in props)Object.defineProperty(obj, key, {
        value: props[key],
        enumerable: true,
        configurable: true
    });
    return obj;
}
/**
 *
 * @param {any} err - An Error
 * @param {string|Extensions} code - A string code or props to set on the error
 * @param {Extensions} [props] - Props to set on the error
 * @returns {Error & Extensions}
 */ function createError(err, code, props) {
    if (!err || typeof err === 'string') throw new TypeError('Please pass an Error to err-code');
    if (!props) props = {
    };
    if (typeof code === 'object') {
        props = code;
        code = '';
    }
    if (code) props.code = code;
    try {
        return assign(err, props);
    } catch (_) {
        props.message = err.message;
        props.stack = err.stack;
        const ErrClass = function() {
        };
        ErrClass.prototype = Object.create(Object.getPrototypeOf(err));
        // @ts-ignore
        const output = assign(new ErrClass(), props);
        return output;
    }
}
module.exports = createError;

},{}],"fttXc":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var errcode = require('err-code');
var unixfs = require('./unixfs.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var errcode__default = /*#__PURE__*/ _interopDefaultLegacy(errcode);
const PBData = unixfs.Data;
const types = [
    'raw',
    'directory',
    'file',
    'metadata',
    'symlink',
    'hamt-sharded-directory'
];
const dirTypes = [
    'directory',
    'hamt-sharded-directory'
];
const DEFAULT_FILE_MODE = parseInt('0644', 8);
const DEFAULT_DIRECTORY_MODE = parseInt('0755', 8);
function parseMode(mode) {
    if (mode == null) return undefined;
    if (typeof mode === 'number') return mode & 4095;
    mode = mode.toString();
    if (mode.substring(0, 1) === '0') return parseInt(mode, 8) & 4095;
    return parseInt(mode, 10) & 4095;
}
function parseMtime(input) {
    if (input == null) return undefined;
    let mtime;
    if (input.secs != null) mtime = {
        secs: input.secs,
        nsecs: input.nsecs
    };
    if (input.Seconds != null) mtime = {
        secs: input.Seconds,
        nsecs: input.FractionalNanoseconds
    };
    if (Array.isArray(input)) mtime = {
        secs: input[0],
        nsecs: input[1]
    };
    if (input instanceof Date) {
        const ms = input.getTime();
        const secs = Math.floor(ms / 1000);
        mtime = {
            secs: secs,
            nsecs: (ms - secs * 1000) * 1000
        };
    }
    if (!Object.prototype.hasOwnProperty.call(mtime, 'secs')) return undefined;
    if (mtime != null && mtime.nsecs != null && (mtime.nsecs < 0 || mtime.nsecs > 999999999)) throw errcode__default['default'](new Error('mtime-nsecs must be within the range [0,999999999]'), 'ERR_INVALID_MTIME_NSECS');
    return mtime;
}
class UnixFS {
    static unmarshal(marshaled) {
        const message = PBData.decode(marshaled);
        const decoded = PBData.toObject(message, {
            defaults: false,
            arrays: true,
            longs: Number,
            objects: false
        });
        const data = new UnixFS({
            type: types[decoded.Type],
            data: decoded.Data,
            blockSizes: decoded.blocksizes,
            mode: decoded.mode,
            mtime: decoded.mtime ? {
                secs: decoded.mtime.Seconds,
                nsecs: decoded.mtime.FractionalNanoseconds
            } : undefined
        });
        data._originalMode = decoded.mode || 0;
        return data;
    }
    constructor(options = {
        type: 'file'
    }){
        const { type , data , blockSizes , hashType , fanout , mtime , mode  } = options;
        if (type && !types.includes(type)) throw errcode__default['default'](new Error('Type: ' + type + ' is not valid'), 'ERR_INVALID_TYPE');
        this.type = type || 'file';
        this.data = data;
        this.hashType = hashType;
        this.fanout = fanout;
        this.blockSizes = blockSizes || [];
        this._originalMode = 0;
        this.mode = parseMode(mode);
        if (mtime) {
            this.mtime = parseMtime(mtime);
            if (this.mtime && !this.mtime.nsecs) this.mtime.nsecs = 0;
        }
    }
    set mode(mode) {
        this._mode = this.isDirectory() ? DEFAULT_DIRECTORY_MODE : DEFAULT_FILE_MODE;
        const parsedMode = parseMode(mode);
        if (parsedMode !== undefined) this._mode = parsedMode;
    }
    get mode() {
        return this._mode;
    }
    isDirectory() {
        return Boolean(this.type && dirTypes.includes(this.type));
    }
    addBlockSize(size1) {
        this.blockSizes.push(size1);
    }
    removeBlockSize(index) {
        this.blockSizes.splice(index, 1);
    }
    fileSize() {
        if (this.isDirectory()) return 0;
        let sum = 0;
        this.blockSizes.forEach((size)=>{
            sum += size;
        });
        if (this.data) sum += this.data.length;
        return sum;
    }
    marshal() {
        let type;
        switch(this.type){
            case 'raw':
                type = PBData.DataType.Raw;
                break;
            case 'directory':
                type = PBData.DataType.Directory;
                break;
            case 'file':
                type = PBData.DataType.File;
                break;
            case 'metadata':
                type = PBData.DataType.Metadata;
                break;
            case 'symlink':
                type = PBData.DataType.Symlink;
                break;
            case 'hamt-sharded-directory':
                type = PBData.DataType.HAMTShard;
                break;
            default:
                throw errcode__default['default'](new Error('Type: ' + type + ' is not valid'), 'ERR_INVALID_TYPE');
        }
        let data = this.data;
        if (!this.data || !this.data.length) data = undefined;
        let mode;
        if (this.mode != null) {
            mode = this._originalMode & 4294963200 | (parseMode(this.mode) || 0);
            if (mode === DEFAULT_FILE_MODE && !this.isDirectory()) mode = undefined;
            if (mode === DEFAULT_DIRECTORY_MODE && this.isDirectory()) mode = undefined;
        }
        let mtime;
        if (this.mtime != null) {
            const parsed = parseMtime(this.mtime);
            if (parsed) {
                mtime = {
                    Seconds: parsed.secs,
                    FractionalNanoseconds: parsed.nsecs
                };
                if (mtime.FractionalNanoseconds === 0) delete mtime.FractionalNanoseconds;
            }
        }
        const pbData = {
            Type: type,
            Data: data,
            filesize: this.isDirectory() ? undefined : this.fileSize(),
            blocksizes: this.blockSizes,
            hashType: this.hashType,
            fanout: this.fanout,
            mode,
            mtime
        };
        return PBData.encode(pbData).finish();
    }
}
exports.UnixFS = UnixFS;
exports.parseMode = parseMode;
exports.parseMtime = parseMtime;

},{"err-code":"eQvyh","./unixfs.js":"a2M1B"}],"a2M1B":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var $protobuf = require('protobufjs/minimal.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var $protobuf__default = /*#__PURE__*/ _interopDefaultLegacy($protobuf);
const $Reader = $protobuf__default['default'].Reader, $Writer = $protobuf__default['default'].Writer, $util = $protobuf__default['default'].util;
const $root = $protobuf__default['default'].roots['ipfs-unixfs'] || ($protobuf__default['default'].roots['ipfs-unixfs'] = {
});
const Data1 = $root.Data = (()=>{
    function Data(p) {
        this.blocksizes = [];
        if (p) {
            for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
        }
    }
    Data.prototype.Type = 0;
    Data.prototype.Data = $util.newBuffer([]);
    Data.prototype.filesize = $util.Long ? $util.Long.fromBits(0, 0, true) : 0;
    Data.prototype.blocksizes = $util.emptyArray;
    Data.prototype.hashType = $util.Long ? $util.Long.fromBits(0, 0, true) : 0;
    Data.prototype.fanout = $util.Long ? $util.Long.fromBits(0, 0, true) : 0;
    Data.prototype.mode = 0;
    Data.prototype.mtime = null;
    Data.encode = function encode(m, w) {
        if (!w) w = $Writer.create();
        w.uint32(8).int32(m.Type);
        if (m.Data != null && Object.hasOwnProperty.call(m, 'Data')) w.uint32(18).bytes(m.Data);
        if (m.filesize != null && Object.hasOwnProperty.call(m, 'filesize')) w.uint32(24).uint64(m.filesize);
        if (m.blocksizes != null && m.blocksizes.length) for(var i = 0; i < m.blocksizes.length; ++i)w.uint32(32).uint64(m.blocksizes[i]);
        if (m.hashType != null && Object.hasOwnProperty.call(m, 'hashType')) w.uint32(40).uint64(m.hashType);
        if (m.fanout != null && Object.hasOwnProperty.call(m, 'fanout')) w.uint32(48).uint64(m.fanout);
        if (m.mode != null && Object.hasOwnProperty.call(m, 'mode')) w.uint32(56).uint32(m.mode);
        if (m.mtime != null && Object.hasOwnProperty.call(m, 'mtime')) $root.UnixTime.encode(m.mtime, w.uint32(66).fork()).ldelim();
        return w;
    };
    Data.decode = function decode(r, l) {
        if (!(r instanceof $Reader)) r = $Reader.create(r);
        var c = l === undefined ? r.len : r.pos + l, m = new $root.Data();
        while(r.pos < c){
            var t = r.uint32();
            switch(t >>> 3){
                case 1:
                    m.Type = r.int32();
                    break;
                case 2:
                    m.Data = r.bytes();
                    break;
                case 3:
                    m.filesize = r.uint64();
                    break;
                case 4:
                    if (!(m.blocksizes && m.blocksizes.length)) m.blocksizes = [];
                    if ((t & 7) === 2) {
                        var c2 = r.uint32() + r.pos;
                        while(r.pos < c2)m.blocksizes.push(r.uint64());
                    } else m.blocksizes.push(r.uint64());
                    break;
                case 5:
                    m.hashType = r.uint64();
                    break;
                case 6:
                    m.fanout = r.uint64();
                    break;
                case 7:
                    m.mode = r.uint32();
                    break;
                case 8:
                    m.mtime = $root.UnixTime.decode(r, r.uint32());
                    break;
                default:
                    r.skipType(t & 7);
                    break;
            }
        }
        if (!m.hasOwnProperty('Type')) throw $util.ProtocolError('missing required \'Type\'', {
            instance: m
        });
        return m;
    };
    Data.fromObject = function fromObject(d) {
        if (d instanceof $root.Data) return d;
        var m = new $root.Data();
        switch(d.Type){
            case 'Raw':
            case 0:
                m.Type = 0;
                break;
            case 'Directory':
            case 1:
                m.Type = 1;
                break;
            case 'File':
            case 2:
                m.Type = 2;
                break;
            case 'Metadata':
            case 3:
                m.Type = 3;
                break;
            case 'Symlink':
            case 4:
                m.Type = 4;
                break;
            case 'HAMTShard':
            case 5:
                m.Type = 5;
                break;
        }
        if (d.Data != null) {
            if (typeof d.Data === 'string') $util.base64.decode(d.Data, m.Data = $util.newBuffer($util.base64.length(d.Data)), 0);
            else if (d.Data.length) m.Data = d.Data;
        }
        if (d.filesize != null) {
            if ($util.Long) (m.filesize = $util.Long.fromValue(d.filesize)).unsigned = true;
            else if (typeof d.filesize === 'string') m.filesize = parseInt(d.filesize, 10);
            else if (typeof d.filesize === 'number') m.filesize = d.filesize;
            else if (typeof d.filesize === 'object') m.filesize = new $util.LongBits(d.filesize.low >>> 0, d.filesize.high >>> 0).toNumber(true);
        }
        if (d.blocksizes) {
            if (!Array.isArray(d.blocksizes)) throw TypeError('.Data.blocksizes: array expected');
            m.blocksizes = [];
            for(var i = 0; i < d.blocksizes.length; ++i){
                if ($util.Long) (m.blocksizes[i] = $util.Long.fromValue(d.blocksizes[i])).unsigned = true;
                else if (typeof d.blocksizes[i] === 'string') m.blocksizes[i] = parseInt(d.blocksizes[i], 10);
                else if (typeof d.blocksizes[i] === 'number') m.blocksizes[i] = d.blocksizes[i];
                else if (typeof d.blocksizes[i] === 'object') m.blocksizes[i] = new $util.LongBits(d.blocksizes[i].low >>> 0, d.blocksizes[i].high >>> 0).toNumber(true);
            }
        }
        if (d.hashType != null) {
            if ($util.Long) (m.hashType = $util.Long.fromValue(d.hashType)).unsigned = true;
            else if (typeof d.hashType === 'string') m.hashType = parseInt(d.hashType, 10);
            else if (typeof d.hashType === 'number') m.hashType = d.hashType;
            else if (typeof d.hashType === 'object') m.hashType = new $util.LongBits(d.hashType.low >>> 0, d.hashType.high >>> 0).toNumber(true);
        }
        if (d.fanout != null) {
            if ($util.Long) (m.fanout = $util.Long.fromValue(d.fanout)).unsigned = true;
            else if (typeof d.fanout === 'string') m.fanout = parseInt(d.fanout, 10);
            else if (typeof d.fanout === 'number') m.fanout = d.fanout;
            else if (typeof d.fanout === 'object') m.fanout = new $util.LongBits(d.fanout.low >>> 0, d.fanout.high >>> 0).toNumber(true);
        }
        if (d.mode != null) m.mode = d.mode >>> 0;
        if (d.mtime != null) {
            if (typeof d.mtime !== 'object') throw TypeError('.Data.mtime: object expected');
            m.mtime = $root.UnixTime.fromObject(d.mtime);
        }
        return m;
    };
    Data.toObject = function toObject(m, o) {
        if (!o) o = {
        };
        var d = {
        };
        if (o.arrays || o.defaults) d.blocksizes = [];
        if (o.defaults) {
            d.Type = o.enums === String ? 'Raw' : 0;
            if (o.bytes === String) d.Data = '';
            else {
                d.Data = [];
                if (o.bytes !== Array) d.Data = $util.newBuffer(d.Data);
            }
            if ($util.Long) {
                var n = new $util.Long(0, 0, true);
                d.filesize = o.longs === String ? n.toString() : o.longs === Number ? n.toNumber() : n;
            } else d.filesize = o.longs === String ? '0' : 0;
            if ($util.Long) {
                var n = new $util.Long(0, 0, true);
                d.hashType = o.longs === String ? n.toString() : o.longs === Number ? n.toNumber() : n;
            } else d.hashType = o.longs === String ? '0' : 0;
            if ($util.Long) {
                var n = new $util.Long(0, 0, true);
                d.fanout = o.longs === String ? n.toString() : o.longs === Number ? n.toNumber() : n;
            } else d.fanout = o.longs === String ? '0' : 0;
            d.mode = 0;
            d.mtime = null;
        }
        if (m.Type != null && m.hasOwnProperty('Type')) d.Type = o.enums === String ? $root.Data.DataType[m.Type] : m.Type;
        if (m.Data != null && m.hasOwnProperty('Data')) d.Data = o.bytes === String ? $util.base64.encode(m.Data, 0, m.Data.length) : o.bytes === Array ? Array.prototype.slice.call(m.Data) : m.Data;
        if (m.filesize != null && m.hasOwnProperty('filesize')) {
            if (typeof m.filesize === 'number') d.filesize = o.longs === String ? String(m.filesize) : m.filesize;
            else d.filesize = o.longs === String ? $util.Long.prototype.toString.call(m.filesize) : o.longs === Number ? new $util.LongBits(m.filesize.low >>> 0, m.filesize.high >>> 0).toNumber(true) : m.filesize;
        }
        if (m.blocksizes && m.blocksizes.length) {
            d.blocksizes = [];
            for(var j = 0; j < m.blocksizes.length; ++j)if (typeof m.blocksizes[j] === 'number') d.blocksizes[j] = o.longs === String ? String(m.blocksizes[j]) : m.blocksizes[j];
            else d.blocksizes[j] = o.longs === String ? $util.Long.prototype.toString.call(m.blocksizes[j]) : o.longs === Number ? new $util.LongBits(m.blocksizes[j].low >>> 0, m.blocksizes[j].high >>> 0).toNumber(true) : m.blocksizes[j];
        }
        if (m.hashType != null && m.hasOwnProperty('hashType')) {
            if (typeof m.hashType === 'number') d.hashType = o.longs === String ? String(m.hashType) : m.hashType;
            else d.hashType = o.longs === String ? $util.Long.prototype.toString.call(m.hashType) : o.longs === Number ? new $util.LongBits(m.hashType.low >>> 0, m.hashType.high >>> 0).toNumber(true) : m.hashType;
        }
        if (m.fanout != null && m.hasOwnProperty('fanout')) {
            if (typeof m.fanout === 'number') d.fanout = o.longs === String ? String(m.fanout) : m.fanout;
            else d.fanout = o.longs === String ? $util.Long.prototype.toString.call(m.fanout) : o.longs === Number ? new $util.LongBits(m.fanout.low >>> 0, m.fanout.high >>> 0).toNumber(true) : m.fanout;
        }
        if (m.mode != null && m.hasOwnProperty('mode')) d.mode = m.mode;
        if (m.mtime != null && m.hasOwnProperty('mtime')) d.mtime = $root.UnixTime.toObject(m.mtime, o);
        return d;
    };
    Data.prototype.toJSON = function toJSON() {
        return this.constructor.toObject(this, $protobuf__default['default'].util.toJSONOptions);
    };
    Data.DataType = (function() {
        const valuesById = {
        }, values = Object.create(valuesById);
        values[valuesById[0] = 'Raw'] = 0;
        values[valuesById[1] = 'Directory'] = 1;
        values[valuesById[2] = 'File'] = 2;
        values[valuesById[3] = 'Metadata'] = 3;
        values[valuesById[4] = 'Symlink'] = 4;
        values[valuesById[5] = 'HAMTShard'] = 5;
        return values;
    })();
    return Data;
})();
const UnixTime1 = $root.UnixTime = (()=>{
    function UnixTime(p) {
        if (p) {
            for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
        }
    }
    UnixTime.prototype.Seconds = $util.Long ? $util.Long.fromBits(0, 0, false) : 0;
    UnixTime.prototype.FractionalNanoseconds = 0;
    UnixTime.encode = function encode(m, w) {
        if (!w) w = $Writer.create();
        w.uint32(8).int64(m.Seconds);
        if (m.FractionalNanoseconds != null && Object.hasOwnProperty.call(m, 'FractionalNanoseconds')) w.uint32(21).fixed32(m.FractionalNanoseconds);
        return w;
    };
    UnixTime.decode = function decode(r, l) {
        if (!(r instanceof $Reader)) r = $Reader.create(r);
        var c = l === undefined ? r.len : r.pos + l, m = new $root.UnixTime();
        while(r.pos < c){
            var t = r.uint32();
            switch(t >>> 3){
                case 1:
                    m.Seconds = r.int64();
                    break;
                case 2:
                    m.FractionalNanoseconds = r.fixed32();
                    break;
                default:
                    r.skipType(t & 7);
                    break;
            }
        }
        if (!m.hasOwnProperty('Seconds')) throw $util.ProtocolError('missing required \'Seconds\'', {
            instance: m
        });
        return m;
    };
    UnixTime.fromObject = function fromObject(d) {
        if (d instanceof $root.UnixTime) return d;
        var m = new $root.UnixTime();
        if (d.Seconds != null) {
            if ($util.Long) (m.Seconds = $util.Long.fromValue(d.Seconds)).unsigned = false;
            else if (typeof d.Seconds === 'string') m.Seconds = parseInt(d.Seconds, 10);
            else if (typeof d.Seconds === 'number') m.Seconds = d.Seconds;
            else if (typeof d.Seconds === 'object') m.Seconds = new $util.LongBits(d.Seconds.low >>> 0, d.Seconds.high >>> 0).toNumber();
        }
        if (d.FractionalNanoseconds != null) m.FractionalNanoseconds = d.FractionalNanoseconds >>> 0;
        return m;
    };
    UnixTime.toObject = function toObject(m, o) {
        if (!o) o = {
        };
        var d = {
        };
        if (o.defaults) {
            if ($util.Long) {
                var n = new $util.Long(0, 0, false);
                d.Seconds = o.longs === String ? n.toString() : o.longs === Number ? n.toNumber() : n;
            } else d.Seconds = o.longs === String ? '0' : 0;
            d.FractionalNanoseconds = 0;
        }
        if (m.Seconds != null && m.hasOwnProperty('Seconds')) {
            if (typeof m.Seconds === 'number') d.Seconds = o.longs === String ? String(m.Seconds) : m.Seconds;
            else d.Seconds = o.longs === String ? $util.Long.prototype.toString.call(m.Seconds) : o.longs === Number ? new $util.LongBits(m.Seconds.low >>> 0, m.Seconds.high >>> 0).toNumber() : m.Seconds;
        }
        if (m.FractionalNanoseconds != null && m.hasOwnProperty('FractionalNanoseconds')) d.FractionalNanoseconds = m.FractionalNanoseconds;
        return d;
    };
    UnixTime.prototype.toJSON = function toJSON() {
        return this.constructor.toObject(this, $protobuf__default['default'].util.toJSONOptions);
    };
    return UnixTime;
})();
const Metadata1 = $root.Metadata = (()=>{
    function Metadata(p) {
        if (p) {
            for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
        }
    }
    Metadata.prototype.MimeType = '';
    Metadata.encode = function encode(m, w) {
        if (!w) w = $Writer.create();
        if (m.MimeType != null && Object.hasOwnProperty.call(m, 'MimeType')) w.uint32(10).string(m.MimeType);
        return w;
    };
    Metadata.decode = function decode(r, l) {
        if (!(r instanceof $Reader)) r = $Reader.create(r);
        var c = l === undefined ? r.len : r.pos + l, m = new $root.Metadata();
        while(r.pos < c){
            var t = r.uint32();
            switch(t >>> 3){
                case 1:
                    m.MimeType = r.string();
                    break;
                default:
                    r.skipType(t & 7);
                    break;
            }
        }
        return m;
    };
    Metadata.fromObject = function fromObject(d) {
        if (d instanceof $root.Metadata) return d;
        var m = new $root.Metadata();
        if (d.MimeType != null) m.MimeType = String(d.MimeType);
        return m;
    };
    Metadata.toObject = function toObject(m, o) {
        if (!o) o = {
        };
        var d = {
        };
        if (o.defaults) d.MimeType = '';
        if (m.MimeType != null && m.hasOwnProperty('MimeType')) d.MimeType = m.MimeType;
        return d;
    };
    Metadata.prototype.toJSON = function toJSON() {
        return this.constructor.toObject(this, $protobuf__default['default'].util.toJSONOptions);
    };
    return Metadata;
})();
exports.Data = Data1;
exports.Metadata = Metadata1;
exports.UnixTime = UnixTime1;
exports['default'] = $root;

},{"protobufjs/minimal.js":"9Jmso"}],"9Jmso":[function(require,module,exports) {
// minimal library entry point.
"use strict";
module.exports = require("./src/index-minimal");

},{"./src/index-minimal":"7cBii"}],"7cBii":[function(require,module,exports) {
"use strict";
var protobuf = exports;
/**
 * Build type, one of `"full"`, `"light"` or `"minimal"`.
 * @name build
 * @type {string}
 * @const
 */ protobuf.build = "minimal";
// Serialization
protobuf.Writer = require("./writer");
protobuf.BufferWriter = require("./writer_buffer");
protobuf.Reader = require("./reader");
protobuf.BufferReader = require("./reader_buffer");
// Utility
protobuf.util = require("./util/minimal");
protobuf.rpc = require("./rpc");
protobuf.roots = require("./roots");
protobuf.configure = configure;
/* istanbul ignore next */ /**
 * Reconfigures the library according to the environment.
 * @returns {undefined}
 */ function configure() {
    protobuf.util._configure();
    protobuf.Writer._configure(protobuf.BufferWriter);
    protobuf.Reader._configure(protobuf.BufferReader);
}
// Set up buffer utility according to the environment
configure();

},{"./writer":"ioLTt","./writer_buffer":"lJqIp","./reader":"kIgj8","./reader_buffer":"GbpZ2","./util/minimal":"j9KH1","./rpc":"sUD8u","./roots":"enPZC"}],"ioLTt":[function(require,module,exports) {
"use strict";
module.exports = Writer;
var util = require("./util/minimal");
var BufferWriter; // cyclic
var LongBits = util.LongBits, base64 = util.base64, utf8 = util.utf8;
/**
 * Constructs a new writer operation instance.
 * @classdesc Scheduled writer operation.
 * @constructor
 * @param {function(*, Uint8Array, number)} fn Function to call
 * @param {number} len Value byte length
 * @param {*} val Value to write
 * @ignore
 */ function Op(fn, len, val) {
    /**
     * Function to call.
     * @type {function(Uint8Array, number, *)}
     */ this.fn = fn;
    /**
     * Value byte length.
     * @type {number}
     */ this.len = len;
    /**
     * Next operation.
     * @type {Writer.Op|undefined}
     */ this.next = undefined;
    /**
     * Value to write.
     * @type {*}
     */ this.val = val; // type varies
}
/* istanbul ignore next */ function noop() {
} // eslint-disable-line no-empty-function
/**
 * Constructs a new writer state instance.
 * @classdesc Copied writer state.
 * @memberof Writer
 * @constructor
 * @param {Writer} writer Writer to copy state from
 * @ignore
 */ function State(writer) {
    /**
     * Current head.
     * @type {Writer.Op}
     */ this.head = writer.head;
    /**
     * Current tail.
     * @type {Writer.Op}
     */ this.tail = writer.tail;
    /**
     * Current buffer length.
     * @type {number}
     */ this.len = writer.len;
    /**
     * Next state.
     * @type {State|null}
     */ this.next = writer.states;
}
/**
 * Constructs a new writer instance.
 * @classdesc Wire format writer using `Uint8Array` if available, otherwise `Array`.
 * @constructor
 */ function Writer() {
    /**
     * Current length.
     * @type {number}
     */ this.len = 0;
    /**
     * Operations head.
     * @type {Object}
     */ this.head = new Op(noop, 0, 0);
    /**
     * Operations tail
     * @type {Object}
     */ this.tail = this.head;
    /**
     * Linked forked states.
     * @type {Object|null}
     */ this.states = null;
// When a value is written, the writer calculates its byte length and puts it into a linked
// list of operations to perform when finish() is called. This both allows us to allocate
// buffers of the exact required size and reduces the amount of work we have to do compared
// to first calculating over objects and then encoding over objects. In our case, the encoding
// part is just a linked list walk calling operations with already prepared values.
}
var create = function create() {
    return util.Buffer ? function create_buffer_setup() {
        return (Writer.create = function create_buffer() {
            return new BufferWriter();
        })();
    } : function create_array() {
        return new Writer();
    };
};
/**
 * Creates a new writer.
 * @function
 * @returns {BufferWriter|Writer} A {@link BufferWriter} when Buffers are supported, otherwise a {@link Writer}
 */ Writer.create = create();
/**
 * Allocates a buffer of the specified size.
 * @param {number} size Buffer size
 * @returns {Uint8Array} Buffer
 */ Writer.alloc = function alloc(size) {
    return new util.Array(size);
};
// Use Uint8Array buffer pool in the browser, just like node does with buffers
/* istanbul ignore else */ if (util.Array !== Array) Writer.alloc = util.pool(Writer.alloc, util.Array.prototype.subarray);
/**
 * Pushes a new operation to the queue.
 * @param {function(Uint8Array, number, *)} fn Function to call
 * @param {number} len Value byte length
 * @param {number} val Value to write
 * @returns {Writer} `this`
 * @private
 */ Writer.prototype._push = function push(fn, len, val) {
    this.tail = this.tail.next = new Op(fn, len, val);
    this.len += len;
    return this;
};
function writeByte(val, buf, pos) {
    buf[pos] = val & 255;
}
function writeVarint32(val, buf, pos) {
    while(val > 127){
        buf[pos++] = val & 127 | 128;
        val >>>= 7;
    }
    buf[pos] = val;
}
/**
 * Constructs a new varint writer operation instance.
 * @classdesc Scheduled varint writer operation.
 * @extends Op
 * @constructor
 * @param {number} len Value byte length
 * @param {number} val Value to write
 * @ignore
 */ function VarintOp(len, val) {
    this.len = len;
    this.next = undefined;
    this.val = val;
}
VarintOp.prototype = Object.create(Op.prototype);
VarintOp.prototype.fn = writeVarint32;
/**
 * Writes an unsigned 32 bit value as a varint.
 * @param {number} value Value to write
 * @returns {Writer} `this`
 */ Writer.prototype.uint32 = function write_uint32(value) {
    // here, the call to this.push has been inlined and a varint specific Op subclass is used.
    // uint32 is by far the most frequently used operation and benefits significantly from this.
    this.len += (this.tail = this.tail.next = new VarintOp((value = value >>> 0) < 128 ? 1 : value < 16384 ? 2 : value < 2097152 ? 3 : value < 268435456 ? 4 : 5, value)).len;
    return this;
};
/**
 * Writes a signed 32 bit value as a varint.
 * @function
 * @param {number} value Value to write
 * @returns {Writer} `this`
 */ Writer.prototype.int32 = function write_int32(value) {
    return value < 0 ? this._push(writeVarint64, 10, LongBits.fromNumber(value)) // 10 bytes per spec
     : this.uint32(value);
};
/**
 * Writes a 32 bit value as a varint, zig-zag encoded.
 * @param {number} value Value to write
 * @returns {Writer} `this`
 */ Writer.prototype.sint32 = function write_sint32(value) {
    return this.uint32((value << 1 ^ value >> 31) >>> 0);
};
function writeVarint64(val, buf, pos) {
    while(val.hi){
        buf[pos++] = val.lo & 127 | 128;
        val.lo = (val.lo >>> 7 | val.hi << 25) >>> 0;
        val.hi >>>= 7;
    }
    while(val.lo > 127){
        buf[pos++] = val.lo & 127 | 128;
        val.lo = val.lo >>> 7;
    }
    buf[pos++] = val.lo;
}
/**
 * Writes an unsigned 64 bit value as a varint.
 * @param {Long|number|string} value Value to write
 * @returns {Writer} `this`
 * @throws {TypeError} If `value` is a string and no long library is present.
 */ Writer.prototype.uint64 = function write_uint64(value) {
    var bits = LongBits.from(value);
    return this._push(writeVarint64, bits.length(), bits);
};
/**
 * Writes a signed 64 bit value as a varint.
 * @function
 * @param {Long|number|string} value Value to write
 * @returns {Writer} `this`
 * @throws {TypeError} If `value` is a string and no long library is present.
 */ Writer.prototype.int64 = Writer.prototype.uint64;
/**
 * Writes a signed 64 bit value as a varint, zig-zag encoded.
 * @param {Long|number|string} value Value to write
 * @returns {Writer} `this`
 * @throws {TypeError} If `value` is a string and no long library is present.
 */ Writer.prototype.sint64 = function write_sint64(value) {
    var bits = LongBits.from(value).zzEncode();
    return this._push(writeVarint64, bits.length(), bits);
};
/**
 * Writes a boolish value as a varint.
 * @param {boolean} value Value to write
 * @returns {Writer} `this`
 */ Writer.prototype.bool = function write_bool(value) {
    return this._push(writeByte, 1, value ? 1 : 0);
};
function writeFixed32(val, buf, pos) {
    buf[pos] = val & 255;
    buf[pos + 1] = val >>> 8 & 255;
    buf[pos + 2] = val >>> 16 & 255;
    buf[pos + 3] = val >>> 24;
}
/**
 * Writes an unsigned 32 bit value as fixed 32 bits.
 * @param {number} value Value to write
 * @returns {Writer} `this`
 */ Writer.prototype.fixed32 = function write_fixed32(value) {
    return this._push(writeFixed32, 4, value >>> 0);
};
/**
 * Writes a signed 32 bit value as fixed 32 bits.
 * @function
 * @param {number} value Value to write
 * @returns {Writer} `this`
 */ Writer.prototype.sfixed32 = Writer.prototype.fixed32;
/**
 * Writes an unsigned 64 bit value as fixed 64 bits.
 * @param {Long|number|string} value Value to write
 * @returns {Writer} `this`
 * @throws {TypeError} If `value` is a string and no long library is present.
 */ Writer.prototype.fixed64 = function write_fixed64(value) {
    var bits = LongBits.from(value);
    return this._push(writeFixed32, 4, bits.lo)._push(writeFixed32, 4, bits.hi);
};
/**
 * Writes a signed 64 bit value as fixed 64 bits.
 * @function
 * @param {Long|number|string} value Value to write
 * @returns {Writer} `this`
 * @throws {TypeError} If `value` is a string and no long library is present.
 */ Writer.prototype.sfixed64 = Writer.prototype.fixed64;
/**
 * Writes a float (32 bit).
 * @function
 * @param {number} value Value to write
 * @returns {Writer} `this`
 */ Writer.prototype.float = function write_float(value) {
    return this._push(util.float.writeFloatLE, 4, value);
};
/**
 * Writes a double (64 bit float).
 * @function
 * @param {number} value Value to write
 * @returns {Writer} `this`
 */ Writer.prototype.double = function write_double(value) {
    return this._push(util.float.writeDoubleLE, 8, value);
};
var writeBytes = util.Array.prototype.set ? function writeBytes_set(val, buf, pos) {
    buf.set(val, pos); // also works for plain array values
} : function writeBytes_for(val, buf, pos) {
    for(var i = 0; i < val.length; ++i)buf[pos + i] = val[i];
};
/**
 * Writes a sequence of bytes.
 * @param {Uint8Array|string} value Buffer or base64 encoded string to write
 * @returns {Writer} `this`
 */ Writer.prototype.bytes = function write_bytes(value) {
    var len = value.length >>> 0;
    if (!len) return this._push(writeByte, 1, 0);
    if (util.isString(value)) {
        var buf = Writer.alloc(len = base64.length(value));
        base64.decode(value, buf, 0);
        value = buf;
    }
    return this.uint32(len)._push(writeBytes, len, value);
};
/**
 * Writes a string.
 * @param {string} value Value to write
 * @returns {Writer} `this`
 */ Writer.prototype.string = function write_string(value) {
    var len = utf8.length(value);
    return len ? this.uint32(len)._push(utf8.write, len, value) : this._push(writeByte, 1, 0);
};
/**
 * Forks this writer's state by pushing it to a stack.
 * Calling {@link Writer#reset|reset} or {@link Writer#ldelim|ldelim} resets the writer to the previous state.
 * @returns {Writer} `this`
 */ Writer.prototype.fork = function fork() {
    this.states = new State(this);
    this.head = this.tail = new Op(noop, 0, 0);
    this.len = 0;
    return this;
};
/**
 * Resets this instance to the last state.
 * @returns {Writer} `this`
 */ Writer.prototype.reset = function reset() {
    if (this.states) {
        this.head = this.states.head;
        this.tail = this.states.tail;
        this.len = this.states.len;
        this.states = this.states.next;
    } else {
        this.head = this.tail = new Op(noop, 0, 0);
        this.len = 0;
    }
    return this;
};
/**
 * Resets to the last state and appends the fork state's current write length as a varint followed by its operations.
 * @returns {Writer} `this`
 */ Writer.prototype.ldelim = function ldelim() {
    var head = this.head, tail = this.tail, len = this.len;
    this.reset().uint32(len);
    if (len) {
        this.tail.next = head.next; // skip noop
        this.tail = tail;
        this.len += len;
    }
    return this;
};
/**
 * Finishes the write operation.
 * @returns {Uint8Array} Finished buffer
 */ Writer.prototype.finish = function finish() {
    var head = this.head.next, buf = this.constructor.alloc(this.len), pos = 0;
    while(head){
        head.fn(head.val, buf, pos);
        pos += head.len;
        head = head.next;
    }
    // this.head = this.tail = null;
    return buf;
};
Writer._configure = function(BufferWriter_) {
    BufferWriter = BufferWriter_;
    Writer.create = create();
    BufferWriter._configure();
};

},{"./util/minimal":"j9KH1"}],"j9KH1":[function(require,module,exports) {
var global = arguments[3];
"use strict";
var util = exports;
// used to return a Promise where callback is omitted
util.asPromise = require("@protobufjs/aspromise");
// converts to / from base64 encoded strings
util.base64 = require("@protobufjs/base64");
// base class of rpc.Service
util.EventEmitter = require("@protobufjs/eventemitter");
// float handling accross browsers
util.float = require("@protobufjs/float");
// requires modules optionally and hides the call from bundlers
util.inquire = require("@protobufjs/inquire");
// converts to / from utf8 encoded strings
util.utf8 = require("@protobufjs/utf8");
// provides a node-like buffer pool in the browser
util.pool = require("@protobufjs/pool");
// utility to work with the low and high bits of a 64 bit value
util.LongBits = require("./longbits");
/**
 * Whether running within node or not.
 * @memberof util
 * @type {boolean}
 */ util.isNode = Boolean(typeof global !== "undefined" && global && global.process && global.process.versions && global.process.versions.node);
/**
 * Global object reference.
 * @memberof util
 * @type {Object}
 */ util.global = util.isNode && global || typeof window !== "undefined" && window || typeof self !== "undefined" && self || this; // eslint-disable-line no-invalid-this
/**
 * An immuable empty array.
 * @memberof util
 * @type {Array.<*>}
 * @const
 */ util.emptyArray = Object.freeze ? Object.freeze([]) : /* istanbul ignore next */ []; // used on prototypes
/**
 * An immutable empty object.
 * @type {Object}
 * @const
 */ util.emptyObject = Object.freeze ? Object.freeze({
}) : /* istanbul ignore next */ {
}; // used on prototypes
/**
 * Tests if the specified value is an integer.
 * @function
 * @param {*} value Value to test
 * @returns {boolean} `true` if the value is an integer
 */ util.isInteger = Number.isInteger || /* istanbul ignore next */ function isInteger(value) {
    return typeof value === "number" && isFinite(value) && Math.floor(value) === value;
};
/**
 * Tests if the specified value is a string.
 * @param {*} value Value to test
 * @returns {boolean} `true` if the value is a string
 */ util.isString = function isString(value) {
    return typeof value === "string" || value instanceof String;
};
/**
 * Tests if the specified value is a non-null object.
 * @param {*} value Value to test
 * @returns {boolean} `true` if the value is a non-null object
 */ util.isObject = function isObject(value) {
    return value && typeof value === "object";
};
/**
 * Checks if a property on a message is considered to be present.
 * This is an alias of {@link util.isSet}.
 * @function
 * @param {Object} obj Plain object or message instance
 * @param {string} prop Property name
 * @returns {boolean} `true` if considered to be present, otherwise `false`
 */ util.isset = /**
 * Checks if a property on a message is considered to be present.
 * @param {Object} obj Plain object or message instance
 * @param {string} prop Property name
 * @returns {boolean} `true` if considered to be present, otherwise `false`
 */ util.isSet = function isSet(obj, prop) {
    var value = obj[prop];
    if (value != null && obj.hasOwnProperty(prop)) return typeof value !== "object" || (Array.isArray(value) ? value.length : Object.keys(value).length) > 0;
    return false;
};
/**
 * Any compatible Buffer instance.
 * This is a minimal stand-alone definition of a Buffer instance. The actual type is that exported by node's typings.
 * @interface Buffer
 * @extends Uint8Array
 */ /**
 * Node's Buffer class if available.
 * @type {Constructor<Buffer>}
 */ util.Buffer = (function() {
    try {
        var Buffer = util.inquire("buffer").Buffer;
        // refuse to use non-node buffers if not explicitly assigned (perf reasons):
        return Buffer.prototype.utf8Write ? Buffer : /* istanbul ignore next */ null;
    } catch (e) {
        /* istanbul ignore next */ return null;
    }
})();
// Internal alias of or polyfull for Buffer.from.
util._Buffer_from = null;
// Internal alias of or polyfill for Buffer.allocUnsafe.
util._Buffer_allocUnsafe = null;
/**
 * Creates a new buffer of whatever type supported by the environment.
 * @param {number|number[]} [sizeOrArray=0] Buffer size or number array
 * @returns {Uint8Array|Buffer} Buffer
 */ util.newBuffer = function newBuffer(sizeOrArray) {
    /* istanbul ignore next */ return typeof sizeOrArray === "number" ? util.Buffer ? util._Buffer_allocUnsafe(sizeOrArray) : new util.Array(sizeOrArray) : util.Buffer ? util._Buffer_from(sizeOrArray) : typeof Uint8Array === "undefined" ? sizeOrArray : new Uint8Array(sizeOrArray);
};
/**
 * Array implementation used in the browser. `Uint8Array` if supported, otherwise `Array`.
 * @type {Constructor<Uint8Array>}
 */ util.Array = typeof Uint8Array !== "undefined" ? Uint8Array /* istanbul ignore next */  : Array;
/**
 * Any compatible Long instance.
 * This is a minimal stand-alone definition of a Long instance. The actual type is that exported by long.js.
 * @interface Long
 * @property {number} low Low bits
 * @property {number} high High bits
 * @property {boolean} unsigned Whether unsigned or not
 */ /**
 * Long.js's Long class if available.
 * @type {Constructor<Long>}
 */ util.Long = /* istanbul ignore next */ util.global.dcodeIO && /* istanbul ignore next */ util.global.dcodeIO.Long || /* istanbul ignore next */ util.global.Long || util.inquire("long");
/**
 * Regular expression used to verify 2 bit (`bool`) map keys.
 * @type {RegExp}
 * @const
 */ util.key2Re = /^true|false|0|1$/;
/**
 * Regular expression used to verify 32 bit (`int32` etc.) map keys.
 * @type {RegExp}
 * @const
 */ util.key32Re = /^-?(?:0|[1-9][0-9]*)$/;
/**
 * Regular expression used to verify 64 bit (`int64` etc.) map keys.
 * @type {RegExp}
 * @const
 */ util.key64Re = /^(?:[\\x00-\\xff]{8}|-?(?:0|[1-9][0-9]*))$/;
/**
 * Converts a number or long to an 8 characters long hash string.
 * @param {Long|number} value Value to convert
 * @returns {string} Hash
 */ util.longToHash = function longToHash(value) {
    return value ? util.LongBits.from(value).toHash() : util.LongBits.zeroHash;
};
/**
 * Converts an 8 characters long hash string to a long or number.
 * @param {string} hash Hash
 * @param {boolean} [unsigned=false] Whether unsigned or not
 * @returns {Long|number} Original value
 */ util.longFromHash = function longFromHash(hash, unsigned) {
    var bits = util.LongBits.fromHash(hash);
    if (util.Long) return util.Long.fromBits(bits.lo, bits.hi, unsigned);
    return bits.toNumber(Boolean(unsigned));
};
/**
 * Merges the properties of the source object into the destination object.
 * @memberof util
 * @param {Object.<string,*>} dst Destination object
 * @param {Object.<string,*>} src Source object
 * @param {boolean} [ifNotSet=false] Merges only if the key is not already set
 * @returns {Object.<string,*>} Destination object
 */ function merge(dst, src, ifNotSet) {
    for(var keys = Object.keys(src), i = 0; i < keys.length; ++i)if (dst[keys[i]] === undefined || !ifNotSet) dst[keys[i]] = src[keys[i]];
    return dst;
}
util.merge = merge;
/**
 * Converts the first character of a string to lower case.
 * @param {string} str String to convert
 * @returns {string} Converted string
 */ util.lcFirst = function lcFirst(str) {
    return str.charAt(0).toLowerCase() + str.substring(1);
};
/**
 * Creates a custom error constructor.
 * @memberof util
 * @param {string} name Error name
 * @returns {Constructor<Error>} Custom error constructor
 */ function newError(name) {
    function CustomError(message, properties) {
        if (!(this instanceof CustomError)) return new CustomError(message, properties);
        // Error.call(this, message);
        // ^ just returns a new error instance because the ctor can be called as a function
        Object.defineProperty(this, "message", {
            get: function() {
                return message;
            }
        });
        /* istanbul ignore next */ if (Error.captureStackTrace) Error.captureStackTrace(this, CustomError);
        else Object.defineProperty(this, "stack", {
            value: new Error().stack || ""
        });
        if (properties) merge(this, properties);
    }
    (CustomError.prototype = Object.create(Error.prototype)).constructor = CustomError;
    Object.defineProperty(CustomError.prototype, "name", {
        get: function() {
            return name;
        }
    });
    CustomError.prototype.toString = function toString() {
        return this.name + ": " + this.message;
    };
    return CustomError;
}
util.newError = newError;
/**
 * Constructs a new protocol error.
 * @classdesc Error subclass indicating a protocol specifc error.
 * @memberof util
 * @extends Error
 * @template T extends Message<T>
 * @constructor
 * @param {string} message Error message
 * @param {Object.<string,*>} [properties] Additional properties
 * @example
 * try {
 *     MyMessage.decode(someBuffer); // throws if required fields are missing
 * } catch (e) {
 *     if (e instanceof ProtocolError && e.instance)
 *         console.log("decoded so far: " + JSON.stringify(e.instance));
 * }
 */ util.ProtocolError = newError("ProtocolError");
/**
 * So far decoded message instance.
 * @name util.ProtocolError#instance
 * @type {Message<T>}
 */ /**
 * A OneOf getter as returned by {@link util.oneOfGetter}.
 * @typedef OneOfGetter
 * @type {function}
 * @returns {string|undefined} Set field name, if any
 */ /**
 * Builds a getter for a oneof's present field name.
 * @param {string[]} fieldNames Field names
 * @returns {OneOfGetter} Unbound getter
 */ util.oneOfGetter = function getOneOf(fieldNames) {
    var fieldMap = {
    };
    for(var i1 = 0; i1 < fieldNames.length; ++i1)fieldMap[fieldNames[i1]] = 1;
    /**
     * @returns {string|undefined} Set field name, if any
     * @this Object
     * @ignore
     */ return function() {
        for(var keys = Object.keys(this), i = keys.length - 1; i > -1; --i)if (fieldMap[keys[i]] === 1 && this[keys[i]] !== undefined && this[keys[i]] !== null) return keys[i];
    };
};
/**
 * A OneOf setter as returned by {@link util.oneOfSetter}.
 * @typedef OneOfSetter
 * @type {function}
 * @param {string|undefined} value Field name
 * @returns {undefined}
 */ /**
 * Builds a setter for a oneof's present field name.
 * @param {string[]} fieldNames Field names
 * @returns {OneOfSetter} Unbound setter
 */ util.oneOfSetter = function setOneOf(fieldNames) {
    /**
     * @param {string} name Field name
     * @returns {undefined}
     * @this Object
     * @ignore
     */ return function(name) {
        for(var i = 0; i < fieldNames.length; ++i)if (fieldNames[i] !== name) delete this[fieldNames[i]];
    };
};
/**
 * Default conversion options used for {@link Message#toJSON} implementations.
 *
 * These options are close to proto3's JSON mapping with the exception that internal types like Any are handled just like messages. More precisely:
 *
 * - Longs become strings
 * - Enums become string keys
 * - Bytes become base64 encoded strings
 * - (Sub-)Messages become plain objects
 * - Maps become plain objects with all string keys
 * - Repeated fields become arrays
 * - NaN and Infinity for float and double fields become strings
 *
 * @type {IConversionOptions}
 * @see https://developers.google.com/protocol-buffers/docs/proto3?hl=en#json
 */ util.toJSONOptions = {
    longs: String,
    enums: String,
    bytes: String,
    json: true
};
// Sets up buffer utility according to the environment (called in index-minimal)
util._configure = function() {
    var Buffer = util.Buffer;
    /* istanbul ignore if */ if (!Buffer) {
        util._Buffer_from = util._Buffer_allocUnsafe = null;
        return;
    }
    // because node 4.x buffers are incompatible & immutable
    // see: https://github.com/dcodeIO/protobuf.js/pull/665
    util._Buffer_from = Buffer.from !== Uint8Array.from && Buffer.from || /* istanbul ignore next */ function Buffer_from(value, encoding) {
        return new Buffer(value, encoding);
    };
    util._Buffer_allocUnsafe = Buffer.allocUnsafe || /* istanbul ignore next */ function Buffer_allocUnsafe(size) {
        return new Buffer(size);
    };
};

},{"@protobufjs/aspromise":"5dz1w","@protobufjs/base64":"9bWvX","@protobufjs/eventemitter":"6gcPw","@protobufjs/float":"eoEGm","@protobufjs/inquire":"3DPWh","@protobufjs/utf8":"kahmI","@protobufjs/pool":"jRK1K","./longbits":"hOFZN"}],"5dz1w":[function(require,module,exports) {
"use strict";
module.exports = asPromise;
/**
 * Callback as used by {@link util.asPromise}.
 * @typedef asPromiseCallback
 * @type {function}
 * @param {Error|null} error Error, if any
 * @param {...*} params Additional arguments
 * @returns {undefined}
 */ /**
 * Returns a promise from a node-style callback function.
 * @memberof util
 * @param {asPromiseCallback} fn Function to call
 * @param {*} ctx Function context
 * @param {...*} params Function arguments
 * @returns {Promise<*>} Promisified function
 */ function asPromise(fn, ctx /*, varargs */ ) {
    var params1 = new Array(arguments.length - 1), offset1 = 0, index = 2, pending = true;
    while(index < arguments.length)params1[offset1++] = arguments[index++];
    return new Promise(function executor(resolve, reject) {
        params1[offset1] = function callback(err /*, varargs */ ) {
            if (pending) {
                pending = false;
                if (err) reject(err);
                else {
                    var params = new Array(arguments.length - 1), offset = 0;
                    while(offset < params.length)params[offset++] = arguments[offset];
                    resolve.apply(null, params);
                }
            }
        };
        try {
            fn.apply(ctx || null, params1);
        } catch (err) {
            if (pending) {
                pending = false;
                reject(err);
            }
        }
    });
}

},{}],"9bWvX":[function(require,module,exports) {
"use strict";
/**
 * A minimal base64 implementation for number arrays.
 * @memberof util
 * @namespace
 */ var base64 = exports;
/**
 * Calculates the byte length of a base64 encoded string.
 * @param {string} string Base64 encoded string
 * @returns {number} Byte length
 */ base64.length = function length(string) {
    var p = string.length;
    if (!p) return 0;
    var n = 0;
    while(--p % 4 > 1 && string.charAt(p) === "=")++n;
    return Math.ceil(string.length * 3) / 4 - n;
};
// Base64 encoding table
var b64 = new Array(64);
// Base64 decoding table
var s64 = new Array(123);
// 65..90, 97..122, 48..57, 43, 47
for(var i1 = 0; i1 < 64;)s64[b64[i1] = i1 < 26 ? i1 + 65 : i1 < 52 ? i1 + 71 : i1 < 62 ? i1 - 4 : i1 - 59 | 43] = i1++;
/**
 * Encodes a buffer to a base64 encoded string.
 * @param {Uint8Array} buffer Source buffer
 * @param {number} start Source start
 * @param {number} end Source end
 * @returns {string} Base64 encoded string
 */ base64.encode = function encode(buffer, start, end) {
    var parts = null, chunk = [];
    var i = 0, j = 0, t; // temporary
    while(start < end){
        var b = buffer[start++];
        switch(j){
            case 0:
                chunk[i++] = b64[b >> 2];
                t = (b & 3) << 4;
                j = 1;
                break;
            case 1:
                chunk[i++] = b64[t | b >> 4];
                t = (b & 15) << 2;
                j = 2;
                break;
            case 2:
                chunk[i++] = b64[t | b >> 6];
                chunk[i++] = b64[b & 63];
                j = 0;
                break;
        }
        if (i > 8191) {
            (parts || (parts = [])).push(String.fromCharCode.apply(String, chunk));
            i = 0;
        }
    }
    if (j) {
        chunk[i++] = b64[t];
        chunk[i++] = 61;
        if (j === 1) chunk[i++] = 61;
    }
    if (parts) {
        if (i) parts.push(String.fromCharCode.apply(String, chunk.slice(0, i)));
        return parts.join("");
    }
    return String.fromCharCode.apply(String, chunk.slice(0, i));
};
var invalidEncoding = "invalid encoding";
/**
 * Decodes a base64 encoded string to a buffer.
 * @param {string} string Source string
 * @param {Uint8Array} buffer Destination buffer
 * @param {number} offset Destination offset
 * @returns {number} Number of bytes written
 * @throws {Error} If encoding is invalid
 */ base64.decode = function decode(string, buffer, offset) {
    var start = offset;
    var j = 0, t; // temporary
    for(var i = 0; i < string.length;){
        var c = string.charCodeAt(i++);
        if (c === 61 && j > 1) break;
        if ((c = s64[c]) === undefined) throw Error(invalidEncoding);
        switch(j){
            case 0:
                t = c;
                j = 1;
                break;
            case 1:
                buffer[offset++] = t << 2 | (c & 48) >> 4;
                t = c;
                j = 2;
                break;
            case 2:
                buffer[offset++] = (t & 15) << 4 | (c & 60) >> 2;
                t = c;
                j = 3;
                break;
            case 3:
                buffer[offset++] = (t & 3) << 6 | c;
                j = 0;
                break;
        }
    }
    if (j === 1) throw Error(invalidEncoding);
    return offset - start;
};
/**
 * Tests if the specified string appears to be base64 encoded.
 * @param {string} string String to test
 * @returns {boolean} `true` if probably base64 encoded, otherwise false
 */ base64.test = function test(string) {
    return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(string);
};

},{}],"6gcPw":[function(require,module,exports) {
"use strict";
module.exports = EventEmitter;
/**
 * Constructs a new event emitter instance.
 * @classdesc A minimal event emitter.
 * @memberof util
 * @constructor
 */ function EventEmitter() {
    /**
     * Registered listeners.
     * @type {Object.<string,*>}
     * @private
     */ this._listeners = {
    };
}
/**
 * Registers an event listener.
 * @param {string} evt Event name
 * @param {function} fn Listener
 * @param {*} [ctx] Listener context
 * @returns {util.EventEmitter} `this`
 */ EventEmitter.prototype.on = function on(evt, fn, ctx) {
    (this._listeners[evt] || (this._listeners[evt] = [])).push({
        fn: fn,
        ctx: ctx || this
    });
    return this;
};
/**
 * Removes an event listener or any matching listeners if arguments are omitted.
 * @param {string} [evt] Event name. Removes all listeners if omitted.
 * @param {function} [fn] Listener to remove. Removes all listeners of `evt` if omitted.
 * @returns {util.EventEmitter} `this`
 */ EventEmitter.prototype.off = function off(evt, fn) {
    if (evt === undefined) this._listeners = {
    };
    else if (fn === undefined) this._listeners[evt] = [];
    else {
        var listeners = this._listeners[evt];
        for(var i = 0; i < listeners.length;)if (listeners[i].fn === fn) listeners.splice(i, 1);
        else ++i;
    }
    return this;
};
/**
 * Emits an event by calling its listeners with the specified arguments.
 * @param {string} evt Event name
 * @param {...*} args Arguments
 * @returns {util.EventEmitter} `this`
 */ EventEmitter.prototype.emit = function emit(evt) {
    var listeners = this._listeners[evt];
    if (listeners) {
        var args = [], i = 1;
        for(; i < arguments.length;)args.push(arguments[i++]);
        for(i = 0; i < listeners.length;)listeners[i].fn.apply(listeners[i++].ctx, args);
    }
    return this;
};

},{}],"eoEGm":[function(require,module,exports) {
"use strict";
module.exports = factory(factory);
/**
 * Reads / writes floats / doubles from / to buffers.
 * @name util.float
 * @namespace
 */ /**
 * Writes a 32 bit float to a buffer using little endian byte order.
 * @name util.float.writeFloatLE
 * @function
 * @param {number} val Value to write
 * @param {Uint8Array} buf Target buffer
 * @param {number} pos Target buffer offset
 * @returns {undefined}
 */ /**
 * Writes a 32 bit float to a buffer using big endian byte order.
 * @name util.float.writeFloatBE
 * @function
 * @param {number} val Value to write
 * @param {Uint8Array} buf Target buffer
 * @param {number} pos Target buffer offset
 * @returns {undefined}
 */ /**
 * Reads a 32 bit float from a buffer using little endian byte order.
 * @name util.float.readFloatLE
 * @function
 * @param {Uint8Array} buf Source buffer
 * @param {number} pos Source buffer offset
 * @returns {number} Value read
 */ /**
 * Reads a 32 bit float from a buffer using big endian byte order.
 * @name util.float.readFloatBE
 * @function
 * @param {Uint8Array} buf Source buffer
 * @param {number} pos Source buffer offset
 * @returns {number} Value read
 */ /**
 * Writes a 64 bit double to a buffer using little endian byte order.
 * @name util.float.writeDoubleLE
 * @function
 * @param {number} val Value to write
 * @param {Uint8Array} buf Target buffer
 * @param {number} pos Target buffer offset
 * @returns {undefined}
 */ /**
 * Writes a 64 bit double to a buffer using big endian byte order.
 * @name util.float.writeDoubleBE
 * @function
 * @param {number} val Value to write
 * @param {Uint8Array} buf Target buffer
 * @param {number} pos Target buffer offset
 * @returns {undefined}
 */ /**
 * Reads a 64 bit double from a buffer using little endian byte order.
 * @name util.float.readDoubleLE
 * @function
 * @param {Uint8Array} buf Source buffer
 * @param {number} pos Source buffer offset
 * @returns {number} Value read
 */ /**
 * Reads a 64 bit double from a buffer using big endian byte order.
 * @name util.float.readDoubleBE
 * @function
 * @param {Uint8Array} buf Source buffer
 * @param {number} pos Source buffer offset
 * @returns {number} Value read
 */ // Factory function for the purpose of node-based testing in modified global environments
function factory(exports) {
    // float: typed array
    if (typeof Float32Array !== "undefined") (function() {
        var f32 = new Float32Array([
            -0
        ]), f8b = new Uint8Array(f32.buffer), le = f8b[3] === 128;
        function writeFloat_f32_cpy(val, buf, pos) {
            f32[0] = val;
            buf[pos] = f8b[0];
            buf[pos + 1] = f8b[1];
            buf[pos + 2] = f8b[2];
            buf[pos + 3] = f8b[3];
        }
        function writeFloat_f32_rev(val, buf, pos) {
            f32[0] = val;
            buf[pos] = f8b[3];
            buf[pos + 1] = f8b[2];
            buf[pos + 2] = f8b[1];
            buf[pos + 3] = f8b[0];
        }
        /* istanbul ignore next */ exports.writeFloatLE = le ? writeFloat_f32_cpy : writeFloat_f32_rev;
        /* istanbul ignore next */ exports.writeFloatBE = le ? writeFloat_f32_rev : writeFloat_f32_cpy;
        function readFloat_f32_cpy(buf, pos) {
            f8b[0] = buf[pos];
            f8b[1] = buf[pos + 1];
            f8b[2] = buf[pos + 2];
            f8b[3] = buf[pos + 3];
            return f32[0];
        }
        function readFloat_f32_rev(buf, pos) {
            f8b[3] = buf[pos];
            f8b[2] = buf[pos + 1];
            f8b[1] = buf[pos + 2];
            f8b[0] = buf[pos + 3];
            return f32[0];
        }
        /* istanbul ignore next */ exports.readFloatLE = le ? readFloat_f32_cpy : readFloat_f32_rev;
        /* istanbul ignore next */ exports.readFloatBE = le ? readFloat_f32_rev : readFloat_f32_cpy;
    // float: ieee754
    })();
    else (function() {
        function writeFloat_ieee754(writeUint, val, buf, pos) {
            var sign = val < 0 ? 1 : 0;
            if (sign) val = -val;
            if (val === 0) writeUint(1 / val > 0 ? /* positive */ 0 : /* negative 0 */ 2147483648, buf, pos);
            else if (isNaN(val)) writeUint(2143289344, buf, pos);
            else if (val > 340282346638528860000000000000000000000) writeUint((sign << 31 | 2139095040) >>> 0, buf, pos);
            else if (val < 0.000000000000000000000000000000000000011754943508222875) writeUint((sign << 31 | Math.round(val / 0.000000000000000000000000000000000000000000001401298464324817)) >>> 0, buf, pos);
            else {
                var exponent = Math.floor(Math.log(val) / Math.LN2), mantissa = Math.round(val * Math.pow(2, -exponent) * 8388608) & 8388607;
                writeUint((sign << 31 | exponent + 127 << 23 | mantissa) >>> 0, buf, pos);
            }
        }
        exports.writeFloatLE = writeFloat_ieee754.bind(null, writeUintLE);
        exports.writeFloatBE = writeFloat_ieee754.bind(null, writeUintBE);
        function readFloat_ieee754(readUint, buf, pos) {
            var uint = readUint(buf, pos), sign = (uint >> 31) * 2 + 1, exponent = uint >>> 23 & 255, mantissa = uint & 8388607;
            return exponent === 255 ? mantissa ? NaN : sign * Infinity : exponent === 0 // denormal
             ? sign * 0.000000000000000000000000000000000000000000001401298464324817 * mantissa : sign * Math.pow(2, exponent - 150) * (mantissa + 8388608);
        }
        exports.readFloatLE = readFloat_ieee754.bind(null, readUintLE);
        exports.readFloatBE = readFloat_ieee754.bind(null, readUintBE);
    })();
    // double: typed array
    if (typeof Float64Array !== "undefined") (function() {
        var f64 = new Float64Array([
            -0
        ]), f8b = new Uint8Array(f64.buffer), le = f8b[7] === 128;
        function writeDouble_f64_cpy(val, buf, pos) {
            f64[0] = val;
            buf[pos] = f8b[0];
            buf[pos + 1] = f8b[1];
            buf[pos + 2] = f8b[2];
            buf[pos + 3] = f8b[3];
            buf[pos + 4] = f8b[4];
            buf[pos + 5] = f8b[5];
            buf[pos + 6] = f8b[6];
            buf[pos + 7] = f8b[7];
        }
        function writeDouble_f64_rev(val, buf, pos) {
            f64[0] = val;
            buf[pos] = f8b[7];
            buf[pos + 1] = f8b[6];
            buf[pos + 2] = f8b[5];
            buf[pos + 3] = f8b[4];
            buf[pos + 4] = f8b[3];
            buf[pos + 5] = f8b[2];
            buf[pos + 6] = f8b[1];
            buf[pos + 7] = f8b[0];
        }
        /* istanbul ignore next */ exports.writeDoubleLE = le ? writeDouble_f64_cpy : writeDouble_f64_rev;
        /* istanbul ignore next */ exports.writeDoubleBE = le ? writeDouble_f64_rev : writeDouble_f64_cpy;
        function readDouble_f64_cpy(buf, pos) {
            f8b[0] = buf[pos];
            f8b[1] = buf[pos + 1];
            f8b[2] = buf[pos + 2];
            f8b[3] = buf[pos + 3];
            f8b[4] = buf[pos + 4];
            f8b[5] = buf[pos + 5];
            f8b[6] = buf[pos + 6];
            f8b[7] = buf[pos + 7];
            return f64[0];
        }
        function readDouble_f64_rev(buf, pos) {
            f8b[7] = buf[pos];
            f8b[6] = buf[pos + 1];
            f8b[5] = buf[pos + 2];
            f8b[4] = buf[pos + 3];
            f8b[3] = buf[pos + 4];
            f8b[2] = buf[pos + 5];
            f8b[1] = buf[pos + 6];
            f8b[0] = buf[pos + 7];
            return f64[0];
        }
        /* istanbul ignore next */ exports.readDoubleLE = le ? readDouble_f64_cpy : readDouble_f64_rev;
        /* istanbul ignore next */ exports.readDoubleBE = le ? readDouble_f64_rev : readDouble_f64_cpy;
    // double: ieee754
    })();
    else (function() {
        function writeDouble_ieee754(writeUint, off0, off1, val, buf, pos) {
            var sign = val < 0 ? 1 : 0;
            if (sign) val = -val;
            if (val === 0) {
                writeUint(0, buf, pos + off0);
                writeUint(1 / val > 0 ? /* positive */ 0 : /* negative 0 */ 2147483648, buf, pos + off1);
            } else if (isNaN(val)) {
                writeUint(0, buf, pos + off0);
                writeUint(2146959360, buf, pos + off1);
            } else if (val > 179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) {
                writeUint(0, buf, pos + off0);
                writeUint((sign << 31 | 2146435072) >>> 0, buf, pos + off1);
            } else {
                var mantissa;
                if (val < 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022250738585072014) {
                    mantissa = val / 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005;
                    writeUint(mantissa >>> 0, buf, pos + off0);
                    writeUint((sign << 31 | mantissa / 4294967296) >>> 0, buf, pos + off1);
                } else {
                    var exponent = Math.floor(Math.log(val) / Math.LN2);
                    if (exponent === 1024) exponent = 1023;
                    mantissa = val * Math.pow(2, -exponent);
                    writeUint(mantissa * 4503599627370496 >>> 0, buf, pos + off0);
                    writeUint((sign << 31 | exponent + 1023 << 20 | mantissa * 1048576 & 1048575) >>> 0, buf, pos + off1);
                }
            }
        }
        exports.writeDoubleLE = writeDouble_ieee754.bind(null, writeUintLE, 0, 4);
        exports.writeDoubleBE = writeDouble_ieee754.bind(null, writeUintBE, 4, 0);
        function readDouble_ieee754(readUint, off0, off1, buf, pos) {
            var lo = readUint(buf, pos + off0), hi = readUint(buf, pos + off1);
            var sign = (hi >> 31) * 2 + 1, exponent = hi >>> 20 & 2047, mantissa = 4294967296 * (hi & 1048575) + lo;
            return exponent === 2047 ? mantissa ? NaN : sign * Infinity : exponent === 0 // denormal
             ? sign * 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005 * mantissa : sign * Math.pow(2, exponent - 1075) * (mantissa + 4503599627370496);
        }
        exports.readDoubleLE = readDouble_ieee754.bind(null, readUintLE, 0, 4);
        exports.readDoubleBE = readDouble_ieee754.bind(null, readUintBE, 4, 0);
    })();
    return exports;
}
// uint helpers
function writeUintLE(val, buf, pos) {
    buf[pos] = val & 255;
    buf[pos + 1] = val >>> 8 & 255;
    buf[pos + 2] = val >>> 16 & 255;
    buf[pos + 3] = val >>> 24;
}
function writeUintBE(val, buf, pos) {
    buf[pos] = val >>> 24;
    buf[pos + 1] = val >>> 16 & 255;
    buf[pos + 2] = val >>> 8 & 255;
    buf[pos + 3] = val & 255;
}
function readUintLE(buf, pos) {
    return (buf[pos] | buf[pos + 1] << 8 | buf[pos + 2] << 16 | buf[pos + 3] << 24) >>> 0;
}
function readUintBE(buf, pos) {
    return (buf[pos] << 24 | buf[pos + 1] << 16 | buf[pos + 2] << 8 | buf[pos + 3]) >>> 0;
}

},{}],"3DPWh":[function(require,module,exports) {
"use strict";
module.exports = inquire;
/**
 * Requires a module only if available.
 * @memberof util
 * @param {string} moduleName Module to require
 * @returns {?Object} Required module if available and not empty, otherwise `null`
 */ function inquire(moduleName) {
    try {
        var mod = eval("quire".replace(/^/, "re"))(moduleName); // eslint-disable-line no-eval
        if (mod && (mod.length || Object.keys(mod).length)) return mod;
    } catch (e) {
    } // eslint-disable-line no-empty
    return null;
}

},{}],"kahmI":[function(require,module,exports) {
"use strict";
/**
 * A minimal UTF8 implementation for number arrays.
 * @memberof util
 * @namespace
 */ var utf8 = exports;
/**
 * Calculates the UTF8 byte length of a string.
 * @param {string} string String
 * @returns {number} Byte length
 */ utf8.length = function utf8_length(string) {
    var len = 0, c = 0;
    for(var i = 0; i < string.length; ++i){
        c = string.charCodeAt(i);
        if (c < 128) len += 1;
        else if (c < 2048) len += 2;
        else if ((c & 64512) === 55296 && (string.charCodeAt(i + 1) & 64512) === 56320) {
            ++i;
            len += 4;
        } else len += 3;
    }
    return len;
};
/**
 * Reads UTF8 bytes as a string.
 * @param {Uint8Array} buffer Source buffer
 * @param {number} start Source start
 * @param {number} end Source end
 * @returns {string} String read
 */ utf8.read = function utf8_read(buffer, start, end) {
    var len = end - start;
    if (len < 1) return "";
    var parts = null, chunk = [], i = 0, t; // temporary
    while(start < end){
        t = buffer[start++];
        if (t < 128) chunk[i++] = t;
        else if (t > 191 && t < 224) chunk[i++] = (t & 31) << 6 | buffer[start++] & 63;
        else if (t > 239 && t < 365) {
            t = ((t & 7) << 18 | (buffer[start++] & 63) << 12 | (buffer[start++] & 63) << 6 | buffer[start++] & 63) - 65536;
            chunk[i++] = 55296 + (t >> 10);
            chunk[i++] = 56320 + (t & 1023);
        } else chunk[i++] = (t & 15) << 12 | (buffer[start++] & 63) << 6 | buffer[start++] & 63;
        if (i > 8191) {
            (parts || (parts = [])).push(String.fromCharCode.apply(String, chunk));
            i = 0;
        }
    }
    if (parts) {
        if (i) parts.push(String.fromCharCode.apply(String, chunk.slice(0, i)));
        return parts.join("");
    }
    return String.fromCharCode.apply(String, chunk.slice(0, i));
};
/**
 * Writes a string as UTF8 bytes.
 * @param {string} string Source string
 * @param {Uint8Array} buffer Destination buffer
 * @param {number} offset Destination offset
 * @returns {number} Bytes written
 */ utf8.write = function utf8_write(string, buffer, offset) {
    var start = offset, c1, c2; // character 2
    for(var i = 0; i < string.length; ++i){
        c1 = string.charCodeAt(i);
        if (c1 < 128) buffer[offset++] = c1;
        else if (c1 < 2048) {
            buffer[offset++] = c1 >> 6 | 192;
            buffer[offset++] = c1 & 63 | 128;
        } else if ((c1 & 64512) === 55296 && ((c2 = string.charCodeAt(i + 1)) & 64512) === 56320) {
            c1 = 65536 + ((c1 & 1023) << 10) + (c2 & 1023);
            ++i;
            buffer[offset++] = c1 >> 18 | 240;
            buffer[offset++] = c1 >> 12 & 63 | 128;
            buffer[offset++] = c1 >> 6 & 63 | 128;
            buffer[offset++] = c1 & 63 | 128;
        } else {
            buffer[offset++] = c1 >> 12 | 224;
            buffer[offset++] = c1 >> 6 & 63 | 128;
            buffer[offset++] = c1 & 63 | 128;
        }
    }
    return offset - start;
};

},{}],"jRK1K":[function(require,module,exports) {
"use strict";
module.exports = pool;
/**
 * An allocator as used by {@link util.pool}.
 * @typedef PoolAllocator
 * @type {function}
 * @param {number} size Buffer size
 * @returns {Uint8Array} Buffer
 */ /**
 * A slicer as used by {@link util.pool}.
 * @typedef PoolSlicer
 * @type {function}
 * @param {number} start Start offset
 * @param {number} end End offset
 * @returns {Uint8Array} Buffer slice
 * @this {Uint8Array}
 */ /**
 * A general purpose buffer pool.
 * @memberof util
 * @function
 * @param {PoolAllocator} alloc Allocator
 * @param {PoolSlicer} slice Slicer
 * @param {number} [size=8192] Slab size
 * @returns {PoolAllocator} Pooled allocator
 */ function pool(alloc, slice, size1) {
    var SIZE = size1 || 8192;
    var MAX = SIZE >>> 1;
    var slab = null;
    var offset = SIZE;
    return function pool_alloc(size) {
        if (size < 1 || size > MAX) return alloc(size);
        if (offset + size > SIZE) {
            slab = alloc(SIZE);
            offset = 0;
        }
        var buf = slice.call(slab, offset, offset += size);
        if (offset & 7) offset = (offset | 7) + 1;
        return buf;
    };
}

},{}],"hOFZN":[function(require,module,exports) {
"use strict";
module.exports = LongBits;
var util = require("../util/minimal");
/**
 * Constructs new long bits.
 * @classdesc Helper class for working with the low and high bits of a 64 bit value.
 * @memberof util
 * @constructor
 * @param {number} lo Low 32 bits, unsigned
 * @param {number} hi High 32 bits, unsigned
 */ function LongBits(lo, hi) {
    // note that the casts below are theoretically unnecessary as of today, but older statically
    // generated converter code might still call the ctor with signed 32bits. kept for compat.
    /**
     * Low bits.
     * @type {number}
     */ this.lo = lo >>> 0;
    /**
     * High bits.
     * @type {number}
     */ this.hi = hi >>> 0;
}
/**
 * Zero bits.
 * @memberof util.LongBits
 * @type {util.LongBits}
 */ var zero = LongBits.zero = new LongBits(0, 0);
zero.toNumber = function() {
    return 0;
};
zero.zzEncode = zero.zzDecode = function() {
    return this;
};
zero.length = function() {
    return 1;
};
/**
 * Zero hash.
 * @memberof util.LongBits
 * @type {string}
 */ var zeroHash = LongBits.zeroHash = "\0\0\0\0\0\0\0\0";
/**
 * Constructs new long bits from the specified number.
 * @param {number} value Value
 * @returns {util.LongBits} Instance
 */ LongBits.fromNumber = function fromNumber(value) {
    if (value === 0) return zero;
    var sign = value < 0;
    if (sign) value = -value;
    var lo = value >>> 0, hi = (value - lo) / 4294967296 >>> 0;
    if (sign) {
        hi = ~hi >>> 0;
        lo = ~lo >>> 0;
        if (++lo > 4294967295) {
            lo = 0;
            if (++hi > 4294967295) hi = 0;
        }
    }
    return new LongBits(lo, hi);
};
/**
 * Constructs new long bits from a number, long or string.
 * @param {Long|number|string} value Value
 * @returns {util.LongBits} Instance
 */ LongBits.from = function from(value) {
    if (typeof value === "number") return LongBits.fromNumber(value);
    if (util.isString(value)) {
        /* istanbul ignore else */ if (util.Long) value = util.Long.fromString(value);
        else return LongBits.fromNumber(parseInt(value, 10));
    }
    return value.low || value.high ? new LongBits(value.low >>> 0, value.high >>> 0) : zero;
};
/**
 * Converts this long bits to a possibly unsafe JavaScript number.
 * @param {boolean} [unsigned=false] Whether unsigned or not
 * @returns {number} Possibly unsafe number
 */ LongBits.prototype.toNumber = function toNumber(unsigned) {
    if (!unsigned && this.hi >>> 31) {
        var lo = ~this.lo + 1 >>> 0, hi = ~this.hi >>> 0;
        if (!lo) hi = hi + 1 >>> 0;
        return -(lo + hi * 4294967296);
    }
    return this.lo + this.hi * 4294967296;
};
/**
 * Converts this long bits to a long.
 * @param {boolean} [unsigned=false] Whether unsigned or not
 * @returns {Long} Long
 */ LongBits.prototype.toLong = function toLong(unsigned) {
    return util.Long ? new util.Long(this.lo | 0, this.hi | 0, Boolean(unsigned)) : {
        low: this.lo | 0,
        high: this.hi | 0,
        unsigned: Boolean(unsigned)
    };
};
var charCodeAt = String.prototype.charCodeAt;
/**
 * Constructs new long bits from the specified 8 characters long hash.
 * @param {string} hash Hash
 * @returns {util.LongBits} Bits
 */ LongBits.fromHash = function fromHash(hash) {
    if (hash === zeroHash) return zero;
    return new LongBits((charCodeAt.call(hash, 0) | charCodeAt.call(hash, 1) << 8 | charCodeAt.call(hash, 2) << 16 | charCodeAt.call(hash, 3) << 24) >>> 0, (charCodeAt.call(hash, 4) | charCodeAt.call(hash, 5) << 8 | charCodeAt.call(hash, 6) << 16 | charCodeAt.call(hash, 7) << 24) >>> 0);
};
/**
 * Converts this long bits to a 8 characters long hash.
 * @returns {string} Hash
 */ LongBits.prototype.toHash = function toHash() {
    return String.fromCharCode(this.lo & 255, this.lo >>> 8 & 255, this.lo >>> 16 & 255, this.lo >>> 24, this.hi & 255, this.hi >>> 8 & 255, this.hi >>> 16 & 255, this.hi >>> 24);
};
/**
 * Zig-zag encodes this long bits.
 * @returns {util.LongBits} `this`
 */ LongBits.prototype.zzEncode = function zzEncode() {
    var mask = this.hi >> 31;
    this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask) >>> 0;
    this.lo = (this.lo << 1 ^ mask) >>> 0;
    return this;
};
/**
 * Zig-zag decodes this long bits.
 * @returns {util.LongBits} `this`
 */ LongBits.prototype.zzDecode = function zzDecode() {
    var mask = -(this.lo & 1);
    this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask) >>> 0;
    this.hi = (this.hi >>> 1 ^ mask) >>> 0;
    return this;
};
/**
 * Calculates the length of this longbits when encoded as a varint.
 * @returns {number} Length
 */ LongBits.prototype.length = function length() {
    var part0 = this.lo, part1 = (this.lo >>> 28 | this.hi << 4) >>> 0, part2 = this.hi >>> 24;
    return part2 === 0 ? part1 === 0 ? part0 < 16384 ? part0 < 128 ? 1 : 2 : part0 < 2097152 ? 3 : 4 : part1 < 16384 ? part1 < 128 ? 5 : 6 : part1 < 2097152 ? 7 : 8 : part2 < 128 ? 9 : 10;
};

},{"../util/minimal":"j9KH1"}],"lJqIp":[function(require,module,exports) {
"use strict";
module.exports = BufferWriter;
// extends Writer
var Writer = require("./writer");
(BufferWriter.prototype = Object.create(Writer.prototype)).constructor = BufferWriter;
var util = require("./util/minimal");
/**
 * Constructs a new buffer writer instance.
 * @classdesc Wire format writer using node buffers.
 * @extends Writer
 * @constructor
 */ function BufferWriter() {
    Writer.call(this);
}
BufferWriter._configure = function() {
    /**
     * Allocates a buffer of the specified size.
     * @function
     * @param {number} size Buffer size
     * @returns {Buffer} Buffer
     */ BufferWriter.alloc = util._Buffer_allocUnsafe;
    BufferWriter.writeBytesBuffer = util.Buffer && util.Buffer.prototype instanceof Uint8Array && util.Buffer.prototype.set.name === "set" ? function writeBytesBuffer_set(val, buf, pos) {
        buf.set(val, pos); // faster than copy (requires node >= 4 where Buffers extend Uint8Array and set is properly inherited)
    // also works for plain array values
    } : function writeBytesBuffer_copy(val, buf, pos) {
        if (val.copy) val.copy(buf, pos, 0, val.length);
        else for(var i = 0; i < val.length;)buf[pos++] = val[i++];
    };
};
/**
 * @override
 */ BufferWriter.prototype.bytes = function write_bytes_buffer(value) {
    if (util.isString(value)) value = util._Buffer_from(value, "base64");
    var len = value.length >>> 0;
    this.uint32(len);
    if (len) this._push(BufferWriter.writeBytesBuffer, len, value);
    return this;
};
function writeStringBuffer(val, buf, pos) {
    if (val.length < 40) util.utf8.write(val, buf, pos);
    else if (buf.utf8Write) buf.utf8Write(val, pos);
    else buf.write(val, pos);
}
/**
 * @override
 */ BufferWriter.prototype.string = function write_string_buffer(value) {
    var len = util.Buffer.byteLength(value);
    this.uint32(len);
    if (len) this._push(writeStringBuffer, len, value);
    return this;
};
/**
 * Finishes the write operation.
 * @name BufferWriter#finish
 * @function
 * @returns {Buffer} Finished buffer
 */ BufferWriter._configure();

},{"./writer":"ioLTt","./util/minimal":"j9KH1"}],"kIgj8":[function(require,module,exports) {
"use strict";
module.exports = Reader;
var util = require("./util/minimal");
var BufferReader; // cyclic
var LongBits = util.LongBits, utf8 = util.utf8;
/* istanbul ignore next */ function indexOutOfRange(reader, writeLength) {
    return RangeError("index out of range: " + reader.pos + " + " + (writeLength || 1) + " > " + reader.len);
}
/**
 * Constructs a new reader instance using the specified buffer.
 * @classdesc Wire format reader using `Uint8Array` if available, otherwise `Array`.
 * @constructor
 * @param {Uint8Array} buffer Buffer to read from
 */ function Reader(buffer) {
    /**
     * Read buffer.
     * @type {Uint8Array}
     */ this.buf = buffer;
    /**
     * Read buffer position.
     * @type {number}
     */ this.pos = 0;
    /**
     * Read buffer length.
     * @type {number}
     */ this.len = buffer.length;
}
var create_array = typeof Uint8Array !== "undefined" ? function create_typed_array(buffer) {
    if (buffer instanceof Uint8Array || Array.isArray(buffer)) return new Reader(buffer);
    throw Error("illegal buffer");
} : function create_array(buffer) {
    if (Array.isArray(buffer)) return new Reader(buffer);
    throw Error("illegal buffer");
};
var create = function create() {
    return util.Buffer ? function create_buffer_setup(buffer1) {
        return (Reader.create = function create_buffer(buffer) {
            return util.Buffer.isBuffer(buffer) ? new BufferReader(buffer) : create_array(buffer);
        })(buffer1);
    } : create_array;
};
/**
 * Creates a new reader using the specified buffer.
 * @function
 * @param {Uint8Array|Buffer} buffer Buffer to read from
 * @returns {Reader|BufferReader} A {@link BufferReader} if `buffer` is a Buffer, otherwise a {@link Reader}
 * @throws {Error} If `buffer` is not a valid buffer
 */ Reader.create = create();
Reader.prototype._slice = util.Array.prototype.subarray || /* istanbul ignore next */ util.Array.prototype.slice;
/**
 * Reads a varint as an unsigned 32 bit value.
 * @function
 * @returns {number} Value read
 */ Reader.prototype.uint32 = (function read_uint32_setup() {
    var value = 4294967295; // optimizer type-hint, tends to deopt otherwise (?!)
    return function read_uint32() {
        value = (this.buf[this.pos] & 127) >>> 0;
        if (this.buf[this.pos++] < 128) return value;
        value = (value | (this.buf[this.pos] & 127) << 7) >>> 0;
        if (this.buf[this.pos++] < 128) return value;
        value = (value | (this.buf[this.pos] & 127) << 14) >>> 0;
        if (this.buf[this.pos++] < 128) return value;
        value = (value | (this.buf[this.pos] & 127) << 21) >>> 0;
        if (this.buf[this.pos++] < 128) return value;
        value = (value | (this.buf[this.pos] & 15) << 28) >>> 0;
        if (this.buf[this.pos++] < 128) return value;
        /* istanbul ignore if */ if ((this.pos += 5) > this.len) {
            this.pos = this.len;
            throw indexOutOfRange(this, 10);
        }
        return value;
    };
})();
/**
 * Reads a varint as a signed 32 bit value.
 * @returns {number} Value read
 */ Reader.prototype.int32 = function read_int32() {
    return this.uint32() | 0;
};
/**
 * Reads a zig-zag encoded varint as a signed 32 bit value.
 * @returns {number} Value read
 */ Reader.prototype.sint32 = function read_sint32() {
    var value = this.uint32();
    return value >>> 1 ^ -(value & 1) | 0;
};
/* eslint-disable no-invalid-this */ function readLongVarint() {
    // tends to deopt with local vars for octet etc.
    var bits = new LongBits(0, 0);
    var i = 0;
    if (this.len - this.pos > 4) {
        for(; i < 4; ++i){
            // 1st..4th
            bits.lo = (bits.lo | (this.buf[this.pos] & 127) << i * 7) >>> 0;
            if (this.buf[this.pos++] < 128) return bits;
        }
        // 5th
        bits.lo = (bits.lo | (this.buf[this.pos] & 127) << 28) >>> 0;
        bits.hi = (bits.hi | (this.buf[this.pos] & 127) >> 4) >>> 0;
        if (this.buf[this.pos++] < 128) return bits;
        i = 0;
    } else {
        for(; i < 3; ++i){
            /* istanbul ignore if */ if (this.pos >= this.len) throw indexOutOfRange(this);
            // 1st..3th
            bits.lo = (bits.lo | (this.buf[this.pos] & 127) << i * 7) >>> 0;
            if (this.buf[this.pos++] < 128) return bits;
        }
        // 4th
        bits.lo = (bits.lo | (this.buf[this.pos++] & 127) << i * 7) >>> 0;
        return bits;
    }
    if (this.len - this.pos > 4) for(; i < 5; ++i){
        // 6th..10th
        bits.hi = (bits.hi | (this.buf[this.pos] & 127) << i * 7 + 3) >>> 0;
        if (this.buf[this.pos++] < 128) return bits;
    }
    else for(; i < 5; ++i){
        /* istanbul ignore if */ if (this.pos >= this.len) throw indexOutOfRange(this);
        // 6th..10th
        bits.hi = (bits.hi | (this.buf[this.pos] & 127) << i * 7 + 3) >>> 0;
        if (this.buf[this.pos++] < 128) return bits;
    }
    /* istanbul ignore next */ throw Error("invalid varint encoding");
}
/* eslint-enable no-invalid-this */ /**
 * Reads a varint as a signed 64 bit value.
 * @name Reader#int64
 * @function
 * @returns {Long} Value read
 */ /**
 * Reads a varint as an unsigned 64 bit value.
 * @name Reader#uint64
 * @function
 * @returns {Long} Value read
 */ /**
 * Reads a zig-zag encoded varint as a signed 64 bit value.
 * @name Reader#sint64
 * @function
 * @returns {Long} Value read
 */ /**
 * Reads a varint as a boolean.
 * @returns {boolean} Value read
 */ Reader.prototype.bool = function read_bool() {
    return this.uint32() !== 0;
};
function readFixed32_end(buf, end) {
    return (buf[end - 4] | buf[end - 3] << 8 | buf[end - 2] << 16 | buf[end - 1] << 24) >>> 0;
}
/**
 * Reads fixed 32 bits as an unsigned 32 bit integer.
 * @returns {number} Value read
 */ Reader.prototype.fixed32 = function read_fixed32() {
    /* istanbul ignore if */ if (this.pos + 4 > this.len) throw indexOutOfRange(this, 4);
    return readFixed32_end(this.buf, this.pos += 4);
};
/**
 * Reads fixed 32 bits as a signed 32 bit integer.
 * @returns {number} Value read
 */ Reader.prototype.sfixed32 = function read_sfixed32() {
    /* istanbul ignore if */ if (this.pos + 4 > this.len) throw indexOutOfRange(this, 4);
    return readFixed32_end(this.buf, this.pos += 4) | 0;
};
/* eslint-disable no-invalid-this */ function readFixed64() {
    /* istanbul ignore if */ if (this.pos + 8 > this.len) throw indexOutOfRange(this, 8);
    return new LongBits(readFixed32_end(this.buf, this.pos += 4), readFixed32_end(this.buf, this.pos += 4));
}
/* eslint-enable no-invalid-this */ /**
 * Reads fixed 64 bits.
 * @name Reader#fixed64
 * @function
 * @returns {Long} Value read
 */ /**
 * Reads zig-zag encoded fixed 64 bits.
 * @name Reader#sfixed64
 * @function
 * @returns {Long} Value read
 */ /**
 * Reads a float (32 bit) as a number.
 * @function
 * @returns {number} Value read
 */ Reader.prototype.float = function read_float() {
    /* istanbul ignore if */ if (this.pos + 4 > this.len) throw indexOutOfRange(this, 4);
    var value = util.float.readFloatLE(this.buf, this.pos);
    this.pos += 4;
    return value;
};
/**
 * Reads a double (64 bit float) as a number.
 * @function
 * @returns {number} Value read
 */ Reader.prototype.double = function read_double() {
    /* istanbul ignore if */ if (this.pos + 8 > this.len) throw indexOutOfRange(this, 4);
    var value = util.float.readDoubleLE(this.buf, this.pos);
    this.pos += 8;
    return value;
};
/**
 * Reads a sequence of bytes preceeded by its length as a varint.
 * @returns {Uint8Array} Value read
 */ Reader.prototype.bytes = function read_bytes() {
    var length = this.uint32(), start = this.pos, end = this.pos + length;
    /* istanbul ignore if */ if (end > this.len) throw indexOutOfRange(this, length);
    this.pos += length;
    if (Array.isArray(this.buf)) return this.buf.slice(start, end);
    return start === end // fix for IE 10/Win8 and others' subarray returning array of size 1
     ? new this.buf.constructor(0) : this._slice.call(this.buf, start, end);
};
/**
 * Reads a string preceeded by its byte length as a varint.
 * @returns {string} Value read
 */ Reader.prototype.string = function read_string() {
    var bytes = this.bytes();
    return utf8.read(bytes, 0, bytes.length);
};
/**
 * Skips the specified number of bytes if specified, otherwise skips a varint.
 * @param {number} [length] Length if known, otherwise a varint is assumed
 * @returns {Reader} `this`
 */ Reader.prototype.skip = function skip(length) {
    if (typeof length === "number") {
        /* istanbul ignore if */ if (this.pos + length > this.len) throw indexOutOfRange(this, length);
        this.pos += length;
    } else do {
        /* istanbul ignore if */ if (this.pos >= this.len) throw indexOutOfRange(this);
    }while (this.buf[this.pos++] & 128)
    return this;
};
/**
 * Skips the next element of the specified wire type.
 * @param {number} wireType Wire type received
 * @returns {Reader} `this`
 */ Reader.prototype.skipType = function(wireType) {
    switch(wireType){
        case 0:
            this.skip();
            break;
        case 1:
            this.skip(8);
            break;
        case 2:
            this.skip(this.uint32());
            break;
        case 3:
            while((wireType = this.uint32() & 7) !== 4)this.skipType(wireType);
            break;
        case 5:
            this.skip(4);
            break;
        /* istanbul ignore next */ default:
            throw Error("invalid wire type " + wireType + " at offset " + this.pos);
    }
    return this;
};
Reader._configure = function(BufferReader_) {
    BufferReader = BufferReader_;
    Reader.create = create();
    BufferReader._configure();
    var fn = util.Long ? "toLong" : /* istanbul ignore next */ "toNumber";
    util.merge(Reader.prototype, {
        int64: function read_int64() {
            return readLongVarint.call(this)[fn](false);
        },
        uint64: function read_uint64() {
            return readLongVarint.call(this)[fn](true);
        },
        sint64: function read_sint64() {
            return readLongVarint.call(this).zzDecode()[fn](false);
        },
        fixed64: function read_fixed64() {
            return readFixed64.call(this)[fn](true);
        },
        sfixed64: function read_sfixed64() {
            return readFixed64.call(this)[fn](false);
        }
    });
};

},{"./util/minimal":"j9KH1"}],"GbpZ2":[function(require,module,exports) {
"use strict";
module.exports = BufferReader;
// extends Reader
var Reader = require("./reader");
(BufferReader.prototype = Object.create(Reader.prototype)).constructor = BufferReader;
var util = require("./util/minimal");
/**
 * Constructs a new buffer reader instance.
 * @classdesc Wire format reader using node buffers.
 * @extends Reader
 * @constructor
 * @param {Buffer} buffer Buffer to read from
 */ function BufferReader(buffer) {
    Reader.call(this, buffer);
/**
     * Read buffer.
     * @name BufferReader#buf
     * @type {Buffer}
     */ }
BufferReader._configure = function() {
    /* istanbul ignore else */ if (util.Buffer) BufferReader.prototype._slice = util.Buffer.prototype.slice;
};
/**
 * @override
 */ BufferReader.prototype.string = function read_string_buffer() {
    var len = this.uint32(); // modifies pos
    return this.buf.utf8Slice ? this.buf.utf8Slice(this.pos, this.pos = Math.min(this.pos + len, this.len)) : this.buf.toString("utf-8", this.pos, this.pos = Math.min(this.pos + len, this.len));
};
/**
 * Reads a sequence of bytes preceeded by its length as a varint.
 * @name BufferReader#bytes
 * @function
 * @returns {Buffer} Value read
 */ BufferReader._configure();

},{"./reader":"kIgj8","./util/minimal":"j9KH1"}],"sUD8u":[function(require,module,exports) {
"use strict";
/**
 * Streaming RPC helpers.
 * @namespace
 */ var rpc = exports;
/**
 * RPC implementation passed to {@link Service#create} performing a service request on network level, i.e. by utilizing http requests or websockets.
 * @typedef RPCImpl
 * @type {function}
 * @param {Method|rpc.ServiceMethod<Message<{}>,Message<{}>>} method Reflected or static method being called
 * @param {Uint8Array} requestData Request data
 * @param {RPCImplCallback} callback Callback function
 * @returns {undefined}
 * @example
 * function rpcImpl(method, requestData, callback) {
 *     if (protobuf.util.lcFirst(method.name) !== "myMethod") // compatible with static code
 *         throw Error("no such method");
 *     asynchronouslyObtainAResponse(requestData, function(err, responseData) {
 *         callback(err, responseData);
 *     });
 * }
 */ /**
 * Node-style callback as used by {@link RPCImpl}.
 * @typedef RPCImplCallback
 * @type {function}
 * @param {Error|null} error Error, if any, otherwise `null`
 * @param {Uint8Array|null} [response] Response data or `null` to signal end of stream, if there hasn't been an error
 * @returns {undefined}
 */ rpc.Service = require("./rpc/service");

},{"./rpc/service":"kFOpF"}],"kFOpF":[function(require,module,exports) {
"use strict";
module.exports = Service;
var util = require("../util/minimal");
// Extends EventEmitter
(Service.prototype = Object.create(util.EventEmitter.prototype)).constructor = Service;
/**
 * A service method callback as used by {@link rpc.ServiceMethod|ServiceMethod}.
 *
 * Differs from {@link RPCImplCallback} in that it is an actual callback of a service method which may not return `response = null`.
 * @typedef rpc.ServiceMethodCallback
 * @template TRes extends Message<TRes>
 * @type {function}
 * @param {Error|null} error Error, if any
 * @param {TRes} [response] Response message
 * @returns {undefined}
 */ /**
 * A service method part of a {@link rpc.Service} as created by {@link Service.create}.
 * @typedef rpc.ServiceMethod
 * @template TReq extends Message<TReq>
 * @template TRes extends Message<TRes>
 * @type {function}
 * @param {TReq|Properties<TReq>} request Request message or plain object
 * @param {rpc.ServiceMethodCallback<TRes>} [callback] Node-style callback called with the error, if any, and the response message
 * @returns {Promise<Message<TRes>>} Promise if `callback` has been omitted, otherwise `undefined`
 */ /**
 * Constructs a new RPC service instance.
 * @classdesc An RPC service as returned by {@link Service#create}.
 * @exports rpc.Service
 * @extends util.EventEmitter
 * @constructor
 * @param {RPCImpl} rpcImpl RPC implementation
 * @param {boolean} [requestDelimited=false] Whether requests are length-delimited
 * @param {boolean} [responseDelimited=false] Whether responses are length-delimited
 */ function Service(rpcImpl, requestDelimited, responseDelimited) {
    if (typeof rpcImpl !== "function") throw TypeError("rpcImpl must be a function");
    util.EventEmitter.call(this);
    /**
     * RPC implementation. Becomes `null` once the service is ended.
     * @type {RPCImpl|null}
     */ this.rpcImpl = rpcImpl;
    /**
     * Whether requests are length-delimited.
     * @type {boolean}
     */ this.requestDelimited = Boolean(requestDelimited);
    /**
     * Whether responses are length-delimited.
     * @type {boolean}
     */ this.responseDelimited = Boolean(responseDelimited);
}
/**
 * Calls a service method through {@link rpc.Service#rpcImpl|rpcImpl}.
 * @param {Method|rpc.ServiceMethod<TReq,TRes>} method Reflected or static method
 * @param {Constructor<TReq>} requestCtor Request constructor
 * @param {Constructor<TRes>} responseCtor Response constructor
 * @param {TReq|Properties<TReq>} request Request message or plain object
 * @param {rpc.ServiceMethodCallback<TRes>} callback Service callback
 * @returns {undefined}
 * @template TReq extends Message<TReq>
 * @template TRes extends Message<TRes>
 */ Service.prototype.rpcCall = function rpcCall(method, requestCtor, responseCtor, request, callback) {
    if (!request) throw TypeError("request must be specified");
    var self = this;
    if (!callback) return util.asPromise(rpcCall, self, method, requestCtor, responseCtor, request);
    if (!self.rpcImpl) {
        setTimeout(function() {
            callback(Error("already ended"));
        }, 0);
        return undefined;
    }
    try {
        return self.rpcImpl(method, requestCtor[self.requestDelimited ? "encodeDelimited" : "encode"](request).finish(), function rpcCallback(err, response) {
            if (err) {
                self.emit("error", err, method);
                return callback(err);
            }
            if (response === null) {
                self.end(/* endedByRPC */ true);
                return undefined;
            }
            if (!(response instanceof responseCtor)) try {
                response = responseCtor[self.responseDelimited ? "decodeDelimited" : "decode"](response);
            } catch (err1) {
                self.emit("error", err1, method);
                return callback(err1);
            }
            self.emit("data", response, method);
            return callback(null, response);
        });
    } catch (err) {
        self.emit("error", err, method);
        setTimeout(function() {
            callback(err);
        }, 0);
        return undefined;
    }
};
/**
 * Ends this service and emits the `end` event.
 * @param {boolean} [endedByRPC=false] Whether the service has been ended by the RPC implementation.
 * @returns {rpc.Service} `this`
 */ Service.prototype.end = function end(endedByRPC) {
    if (this.rpcImpl) {
        if (!endedByRPC) this.rpcImpl(null, null, null);
        this.rpcImpl = null;
        this.emit("end").off();
    }
    return this;
};

},{"../util/minimal":"j9KH1"}],"enPZC":[function(require,module,exports) {
"use strict";
module.exports = {
}; /**
 * Named roots.
 * This is where pbjs stores generated structures (the option `-r, --root` specifies a name).
 * Can also be used manually to make roots available accross modules.
 * @name roots
 * @type {Object.<string,Root>}
 * @example
 * // pbjs -r myroot -o compiled.js ...
 *
 * // in another module:
 * require("./compiled.js");
 *
 * // in any subsequent module:
 * var root = protobuf.roots["myroot"];
 */ 

},{}],"e9gy2":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
var pbDecode = require('./pb-decode.js');
var pbEncode = require('./pb-encode.js');
var util = require('./util.js');
const name = 'dag-pb';
const code = 112;
function encode(node) {
    util.validate(node);
    const pbn = {
    };
    if (node.Links) pbn.Links = node.Links.map((l)=>{
        const link = {
        };
        if (l.Hash) link.Hash = l.Hash.bytes;
        if (l.Name !== undefined) link.Name = l.Name;
        if (l.Tsize !== undefined) link.Tsize = l.Tsize;
        return link;
    });
    if (node.Data) pbn.Data = node.Data;
    return pbEncode.encodeNode(pbn);
}
function decode(bytes) {
    const pbn = pbDecode.decodeNode(bytes);
    const node = {
    };
    if (pbn.Data) node.Data = pbn.Data;
    if (pbn.Links) node.Links = pbn.Links.map((l)=>{
        const link = {
        };
        try {
            link.Hash = cid.CID.decode(l.Hash);
        } catch (e) {
        }
        if (!link.Hash) throw new Error('Invalid Hash field found in link, expected CID');
        if (l.Name !== undefined) link.Name = l.Name;
        if (l.Tsize !== undefined) link.Tsize = l.Tsize;
        return link;
    });
    return node;
}
exports.createLink = util.createLink;
exports.createNode = util.createNode;
exports.prepare = util.prepare;
exports.validate = util.validate;
exports.code = code;
exports.decode = decode;
exports.encode = encode;
exports.name = name;

},{"multiformats/cid":"fJJnW","./pb-decode.js":"hDIMN","./pb-encode.js":"gBGpm","./util.js":"4tLhM"}],"fJJnW":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var varint = require('./varint.js');
var digest = require('./hashes/digest.js');
var base58 = require('./bases/base58.js');
var base32 = require('./bases/base32.js');
var bytes3 = require('./bytes.js');
class CID {
    constructor(version1, code3, multihash1, bytes1){
        this.code = code3;
        this.version = version1;
        this.multihash = multihash1;
        this.bytes = bytes1;
        this.byteOffset = bytes1.byteOffset;
        this.byteLength = bytes1.byteLength;
        this.asCID = this;
        this._baseCache = new Map();
        Object.defineProperties(this, {
            byteOffset: hidden,
            byteLength: hidden,
            code: readonly,
            version: readonly,
            multihash: readonly,
            bytes: readonly,
            _baseCache: hidden,
            asCID: hidden
        });
    }
    toV0() {
        switch(this.version){
            case 0:
                return this;
            default:
                {
                    const { code , multihash  } = this;
                    if (code !== DAG_PB_CODE) throw new Error('Cannot convert a non dag-pb CID to CIDv0');
                    if (multihash.code !== SHA_256_CODE) throw new Error('Cannot convert non sha2-256 multihash CID to CIDv0');
                    return CID.createV0(multihash);
                }
        }
    }
    toV1() {
        switch(this.version){
            case 0:
                {
                    const { code , digest: digest$1  } = this.multihash;
                    const multihash = digest.create(code, digest$1);
                    return CID.createV1(this.code, multihash);
                }
            case 1:
                return this;
            default:
                throw Error(`Can not convert CID version ${this.version} to version 0. This is a bug please report`);
        }
    }
    equals(other) {
        return other && this.code === other.code && this.version === other.version && digest.equals(this.multihash, other.multihash);
    }
    toString(base2) {
        const { bytes , version , _baseCache  } = this;
        switch(version){
            case 0:
                return toStringV0(bytes, _baseCache, base2 || base58.base58btc.encoder);
            default:
                return toStringV1(bytes, _baseCache, base2 || base32.base32.encoder);
        }
    }
    toJSON() {
        return {
            code: this.code,
            version: this.version,
            hash: this.multihash.bytes
        };
    }
    get [Symbol.toStringTag]() {
        return 'CID';
    }
    [Symbol.for('nodejs.util.inspect.custom')]() {
        return 'CID(' + this.toString() + ')';
    }
    static isCID(value) {
        deprecate(/^0\.0/, IS_CID_DEPRECATION);
        return !!(value && (value[cidSymbol] || value.asCID === value));
    }
    get toBaseEncodedString() {
        throw new Error('Deprecated, use .toString()');
    }
    get codec() {
        throw new Error('"codec" property is deprecated, use integer "code" property instead');
    }
    get buffer() {
        throw new Error('Deprecated .buffer property, use .bytes to get Uint8Array instead');
    }
    get multibaseName() {
        throw new Error('"multibaseName" property is deprecated');
    }
    get prefix() {
        throw new Error('"prefix" property is deprecated');
    }
    static asCID(value1) {
        if (value1 instanceof CID) return value1;
        else if (value1 != null && value1.asCID === value1) {
            const { version , code , multihash , bytes  } = value1;
            return new CID(version, code, multihash, bytes || encodeCID(version, code, multihash.bytes));
        } else if (value1 != null && value1[cidSymbol] === true) {
            const { version , multihash , code  } = value1;
            const digest$1 = digest.decode(multihash);
            return CID.create(version, code, digest$1);
        } else return null;
    }
    static create(version2, code1, digest1) {
        if (typeof code1 !== 'number') throw new Error('String codecs are no longer supported');
        switch(version2){
            case 0:
                if (code1 !== DAG_PB_CODE) throw new Error(`Version 0 CID must use dag-pb (code: ${DAG_PB_CODE}) block encoding`);
                else return new CID(version2, code1, digest1, digest1.bytes);
            case 1:
                {
                    const bytes = encodeCID(version2, code1, digest1.bytes);
                    return new CID(version2, code1, digest1, bytes);
                }
            default:
                throw new Error('Invalid version');
        }
    }
    static createV0(digest2) {
        return CID.create(0, DAG_PB_CODE, digest2);
    }
    static createV1(code2, digest3) {
        return CID.create(1, code2, digest3);
    }
    static decode(bytes2) {
        const [cid, remainder] = CID.decodeFirst(bytes2);
        if (remainder.length) throw new Error('Incorrect length');
        return cid;
    }
    static decodeFirst(bytes$1) {
        const specs = CID.inspectBytes(bytes$1);
        const prefixSize = specs.size - specs.multihashSize;
        const multihashBytes = bytes3.coerce(bytes$1.subarray(prefixSize, prefixSize + specs.multihashSize));
        if (multihashBytes.byteLength !== specs.multihashSize) throw new Error('Incorrect length');
        const digestBytes = multihashBytes.subarray(specs.multihashSize - specs.digestSize);
        const digest$1 = new digest.Digest(specs.multihashCode, specs.digestSize, digestBytes, multihashBytes);
        const cid = specs.version === 0 ? CID.createV0(digest$1) : CID.createV1(specs.codec, digest$1);
        return [
            cid,
            bytes$1.subarray(specs.size)
        ];
    }
    static inspectBytes(initialBytes) {
        let offset = 0;
        const next = ()=>{
            const [i, length] = varint.decode(initialBytes.subarray(offset));
            offset += length;
            return i;
        };
        let version = next();
        let codec = DAG_PB_CODE;
        if (version === 18) {
            version = 0;
            offset = 0;
        } else if (version === 1) codec = next();
        if (version !== 0 && version !== 1) throw new RangeError(`Invalid CID version ${version}`);
        const prefixSize = offset;
        const multihashCode = next();
        const digestSize = next();
        const size = offset + digestSize;
        const multihashSize = size - prefixSize;
        return {
            version,
            codec,
            multihashCode,
            digestSize,
            multihashSize,
            size
        };
    }
    static parse(source1, base1) {
        const [prefix, bytes] = parseCIDtoBytes(source1, base1);
        const cid = CID.decode(bytes);
        cid._baseCache.set(prefix, source1);
        return cid;
    }
}
const parseCIDtoBytes = (source, base)=>{
    switch(source[0]){
        case 'Q':
            {
                const decoder = base || base58.base58btc;
                return [
                    base58.base58btc.prefix,
                    decoder.decode(`${base58.base58btc.prefix}${source}`)
                ];
            }
        case base58.base58btc.prefix:
            {
                const decoder = base || base58.base58btc;
                return [
                    base58.base58btc.prefix,
                    decoder.decode(source)
                ];
            }
        case base32.base32.prefix:
            {
                const decoder = base || base32.base32;
                return [
                    base32.base32.prefix,
                    decoder.decode(source)
                ];
            }
        default:
            if (base == null) throw Error('To parse non base32 or base58btc encoded CID multibase decoder must be provided');
            return [
                source[0],
                base.decode(source)
            ];
    }
};
const toStringV0 = (bytes, cache, base)=>{
    const { prefix  } = base;
    if (prefix !== base58.base58btc.prefix) throw Error(`Cannot string encode V0 in ${base.name} encoding`);
    const cid = cache.get(prefix);
    if (cid == null) {
        const cid = base.encode(bytes).slice(1);
        cache.set(prefix, cid);
        return cid;
    } else return cid;
};
const toStringV1 = (bytes, cache, base)=>{
    const { prefix  } = base;
    const cid = cache.get(prefix);
    if (cid == null) {
        const cid = base.encode(bytes);
        cache.set(prefix, cid);
        return cid;
    } else return cid;
};
const DAG_PB_CODE = 112;
const SHA_256_CODE = 18;
const encodeCID = (version, code, multihash)=>{
    const codeOffset = varint.encodingLength(version);
    const hashOffset = codeOffset + varint.encodingLength(code);
    const bytes = new Uint8Array(hashOffset + multihash.byteLength);
    varint.encodeTo(version, bytes, 0);
    varint.encodeTo(code, bytes, codeOffset);
    bytes.set(multihash, hashOffset);
    return bytes;
};
const cidSymbol = Symbol.for('@ipld/js-cid/CID');
const readonly = {
    writable: false,
    configurable: false,
    enumerable: true
};
const hidden = {
    writable: false,
    enumerable: false,
    configurable: false
};
const version3 = '0.0.0-dev';
const deprecate = (range, message)=>{
    if (range.test(version3)) console.warn(message);
    else throw new Error(message);
};
const IS_CID_DEPRECATION = `CID.isCID(v) is deprecated and will be removed in the next major release.
Following code pattern:

if (CID.isCID(value)) {
  doSomethingWithCID(value)
}

Is replaced with:

const cid = CID.asCID(value)
if (cid) {
  // Make sure to use cid instead of value
  doSomethingWithCID(cid)
}
`;
exports.CID = CID;

},{"./varint.js":"5Q7FL","./hashes/digest.js":"fkA58","./bases/base58.js":"6Rnqi","./bases/base32.js":"63xDB","./bytes.js":"7cZyj"}],"5Q7FL":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var varint$1 = require('../vendor/varint.js');
const decode = (data)=>{
    const code = varint$1.decode(data);
    return [
        code,
        varint$1.decode.bytes
    ];
};
const encodeTo = (int, target, offset = 0)=>{
    varint$1.encode(int, target, offset);
    return target;
};
const encodingLength = (int)=>{
    return varint$1.encodingLength(int);
};
exports.decode = decode;
exports.encodeTo = encodeTo;
exports.encodingLength = encodingLength;

},{"../vendor/varint.js":"cAYKY"}],"cAYKY":[function(require,module,exports) {
'use strict';
var encode_1 = encode;
var MSB = 128, REST = 127, MSBALL = ~REST, INT = Math.pow(2, 31);
function encode(num, out, offset) {
    out = out || [];
    offset = offset || 0;
    var oldOffset = offset;
    while(num >= INT){
        out[offset++] = num & 255 | MSB;
        num /= 128;
    }
    while(num & MSBALL){
        out[offset++] = num & 255 | MSB;
        num >>>= 7;
    }
    out[offset] = num | 0;
    encode.bytes = offset - oldOffset + 1;
    return out;
}
var decode = read;
var MSB$1 = 128, REST$1 = 127;
function read(buf, offset) {
    var res = 0, offset = offset || 0, shift = 0, counter = offset, b, l = buf.length;
    do {
        if (counter >= l) {
            read.bytes = 0;
            throw new RangeError('Could not decode varint');
        }
        b = buf[counter++];
        res += shift < 28 ? (b & REST$1) << shift : (b & REST$1) * Math.pow(2, shift);
        shift += 7;
    }while (b >= MSB$1)
    read.bytes = counter - offset;
    return res;
}
var N1 = Math.pow(2, 7);
var N2 = Math.pow(2, 14);
var N3 = Math.pow(2, 21);
var N4 = Math.pow(2, 28);
var N5 = Math.pow(2, 35);
var N6 = Math.pow(2, 42);
var N7 = Math.pow(2, 49);
var N8 = Math.pow(2, 56);
var N9 = Math.pow(2, 63);
var length = function(value) {
    return value < N1 ? 1 : value < N2 ? 2 : value < N3 ? 3 : value < N4 ? 4 : value < N5 ? 5 : value < N6 ? 6 : value < N7 ? 7 : value < N8 ? 8 : value < N9 ? 9 : 10;
};
var varint = {
    encode: encode_1,
    decode: decode,
    encodingLength: length
};
var _brrp_varint = varint;
var varint$1 = _brrp_varint;
module.exports = varint$1;

},{}],"fkA58":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var bytes1 = require('../bytes.js');
var varint = require('../varint.js');
const create = (code, digest)=>{
    const size = digest.byteLength;
    const sizeOffset = varint.encodingLength(code);
    const digestOffset = sizeOffset + varint.encodingLength(size);
    const bytes = new Uint8Array(digestOffset + size);
    varint.encodeTo(code, bytes, 0);
    varint.encodeTo(size, bytes, sizeOffset);
    bytes.set(digest, digestOffset);
    return new Digest(code, size, digest, bytes);
};
const decode = (multihash)=>{
    const bytes$1 = bytes1.coerce(multihash);
    const [code, sizeOffset] = varint.decode(bytes$1);
    const [size, digestOffset] = varint.decode(bytes$1.subarray(sizeOffset));
    const digest = bytes$1.subarray(sizeOffset + digestOffset);
    if (digest.byteLength !== size) throw new Error('Incorrect length');
    return new Digest(code, size, digest, bytes$1);
};
const equals = (a, b)=>{
    if (a === b) return true;
    else return a.code === b.code && a.size === b.size && bytes1.equals(a.bytes, b.bytes);
};
class Digest {
    constructor(code, size, digest, bytes){
        this.code = code;
        this.size = size;
        this.digest = digest;
        this.bytes = bytes;
    }
}
exports.Digest = Digest;
exports.create = create;
exports.decode = decode;
exports.equals = equals;

},{"../bytes.js":"7cZyj","../varint.js":"5Q7FL"}],"7cZyj":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
const empty = new Uint8Array(0);
const toHex = (d)=>d.reduce((hex, byte)=>hex + byte.toString(16).padStart(2, '0')
    , '')
;
const fromHex = (hex)=>{
    const hexes = hex.match(/../g);
    return hexes ? new Uint8Array(hexes.map((b)=>parseInt(b, 16)
    )) : empty;
};
const equals = (aa, bb)=>{
    if (aa === bb) return true;
    if (aa.byteLength !== bb.byteLength) return false;
    for(let ii = 0; ii < aa.byteLength; ii++){
        if (aa[ii] !== bb[ii]) return false;
    }
    return true;
};
const coerce = (o)=>{
    if (o instanceof Uint8Array && o.constructor.name === 'Uint8Array') return o;
    if (o instanceof ArrayBuffer) return new Uint8Array(o);
    if (ArrayBuffer.isView(o)) return new Uint8Array(o.buffer, o.byteOffset, o.byteLength);
    throw new Error('Unknown type, must be binary type');
};
const isBinary = (o)=>o instanceof ArrayBuffer || ArrayBuffer.isView(o)
;
const fromString = (str)=>new TextEncoder().encode(str)
;
const toString = (b)=>new TextDecoder().decode(b)
;
exports.coerce = coerce;
exports.empty = empty;
exports.equals = equals;
exports.fromHex = fromHex;
exports.fromString = fromString;
exports.isBinary = isBinary;
exports.toHex = toHex;
exports.toString = toString;

},{}],"6Rnqi":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var base = require('./base.js');
const base58btc = base.baseX({
    name: 'base58btc',
    prefix: 'z',
    alphabet: '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
});
const base58flickr = base.baseX({
    name: 'base58flickr',
    prefix: 'Z',
    alphabet: '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'
});
exports.base58btc = base58btc;
exports.base58flickr = base58flickr;

},{"./base.js":"aX8fr"}],"aX8fr":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var baseX$1 = require('../../vendor/base-x.js');
var bytes = require('../bytes.js');
class Encoder {
    constructor(name3, prefix3, baseEncode){
        this.name = name3;
        this.prefix = prefix3;
        this.baseEncode = baseEncode;
    }
    encode(bytes1) {
        if (bytes1 instanceof Uint8Array) return `${this.prefix}${this.baseEncode(bytes1)}`;
        else throw Error('Unknown type, must be binary type');
    }
}
class Decoder {
    constructor(name1, prefix1, baseDecode){
        this.name = name1;
        this.prefix = prefix1;
        this.baseDecode = baseDecode;
    }
    decode(text1) {
        if (typeof text1 === 'string') switch(text1[0]){
            case this.prefix:
                return this.baseDecode(text1.slice(1));
            default:
                throw Error(`Unable to decode multibase string ${JSON.stringify(text1)}, ${this.name} decoder only supports inputs prefixed with ${this.prefix}`);
        }
        else throw Error('Can only multibase decode strings');
    }
    or(decoder) {
        return or(this, decoder);
    }
}
class ComposedDecoder {
    constructor(decoders){
        this.decoders = decoders;
    }
    or(decoder1) {
        return or(this, decoder1);
    }
    decode(input3) {
        const prefix = input3[0];
        const decoder = this.decoders[prefix];
        if (decoder) return decoder.decode(input3);
        else throw RangeError(`Unable to decode multibase string ${JSON.stringify(input3)}, only inputs prefixed with ${Object.keys(this.decoders)} are supported`);
    }
}
const or = (left, right)=>new ComposedDecoder({
        ...left.decoders || {
            [left.prefix]: left
        },
        ...right.decoders || {
            [right.prefix]: right
        }
    })
;
class Codec {
    constructor(name2, prefix2, baseEncode1, baseDecode1){
        this.name = name2;
        this.prefix = prefix2;
        this.baseEncode = baseEncode1;
        this.baseDecode = baseDecode1;
        this.encoder = new Encoder(name2, prefix2, baseEncode1);
        this.decoder = new Decoder(name2, prefix2, baseDecode1);
    }
    encode(input1) {
        return this.encoder.encode(input1);
    }
    decode(input2) {
        return this.decoder.decode(input2);
    }
}
const from = ({ name , prefix , encode , decode  })=>new Codec(name, prefix, encode, decode)
;
const baseX = ({ prefix , name , alphabet  })=>{
    const { encode , decode  } = baseX$1(alphabet, name);
    return from({
        prefix,
        name,
        encode,
        decode: (text)=>bytes.coerce(decode(text))
    });
};
const decode1 = (string, alphabet, bitsPerChar, name)=>{
    const codes = {
    };
    for(let i = 0; i < alphabet.length; ++i)codes[alphabet[i]] = i;
    let end = string.length;
    while(string[end - 1] === '=')--end;
    const out = new Uint8Array(end * bitsPerChar / 8 | 0);
    let bits = 0;
    let buffer = 0;
    let written = 0;
    for(let i1 = 0; i1 < end; ++i1){
        const value = codes[string[i1]];
        if (value === undefined) throw new SyntaxError(`Non-${name} character`);
        buffer = buffer << bitsPerChar | value;
        bits += bitsPerChar;
        if (bits >= 8) {
            bits -= 8;
            out[written++] = 255 & buffer >> bits;
        }
    }
    if (bits >= bitsPerChar || 255 & buffer << 8 - bits) throw new SyntaxError('Unexpected end of data');
    return out;
};
const encode1 = (data, alphabet, bitsPerChar)=>{
    const pad = alphabet[alphabet.length - 1] === '=';
    const mask = (1 << bitsPerChar) - 1;
    let out = '';
    let bits = 0;
    let buffer = 0;
    for(let i = 0; i < data.length; ++i){
        buffer = buffer << 8 | data[i];
        bits += 8;
        while(bits > bitsPerChar){
            bits -= bitsPerChar;
            out += alphabet[mask & buffer >> bits];
        }
    }
    if (bits) out += alphabet[mask & buffer << bitsPerChar - bits];
    if (pad) while(out.length * bitsPerChar & 7)out += '=';
    return out;
};
const rfc4648 = ({ name , prefix , bitsPerChar , alphabet  })=>{
    return from({
        prefix,
        name,
        encode (input) {
            return encode1(input, alphabet, bitsPerChar);
        },
        decode (input) {
            return decode1(input, alphabet, bitsPerChar, name);
        }
    });
};
exports.Codec = Codec;
exports.baseX = baseX;
exports.from = from;
exports.or = or;
exports.rfc4648 = rfc4648;

},{"../../vendor/base-x.js":"dJz8Y","../bytes.js":"7cZyj"}],"dJz8Y":[function(require,module,exports) {
'use strict';
function base(ALPHABET, name) {
    if (ALPHABET.length >= 255) throw new TypeError('Alphabet too long');
    var BASE_MAP = new Uint8Array(256);
    for(var j = 0; j < BASE_MAP.length; j++)BASE_MAP[j] = 255;
    for(var i1 = 0; i1 < ALPHABET.length; i1++){
        var x = ALPHABET.charAt(i1);
        var xc = x.charCodeAt(0);
        if (BASE_MAP[xc] !== 255) throw new TypeError(x + ' is ambiguous');
        BASE_MAP[xc] = i1;
    }
    var BASE = ALPHABET.length;
    var LEADER = ALPHABET.charAt(0);
    var FACTOR = Math.log(BASE) / Math.log(256);
    var iFACTOR = Math.log(256) / Math.log(BASE);
    function encode(source) {
        if (source instanceof Uint8Array) ;
        else if (ArrayBuffer.isView(source)) source = new Uint8Array(source.buffer, source.byteOffset, source.byteLength);
        else if (Array.isArray(source)) source = Uint8Array.from(source);
        if (!(source instanceof Uint8Array)) throw new TypeError('Expected Uint8Array');
        if (source.length === 0) return '';
        var zeroes = 0;
        var length = 0;
        var pbegin = 0;
        var pend = source.length;
        while(pbegin !== pend && source[pbegin] === 0){
            pbegin++;
            zeroes++;
        }
        var size = (pend - pbegin) * iFACTOR + 1 >>> 0;
        var b58 = new Uint8Array(size);
        while(pbegin !== pend){
            var carry = source[pbegin];
            var i = 0;
            for(var it1 = size - 1; (carry !== 0 || i < length) && it1 !== -1; it1--, i++){
                carry += 256 * b58[it1] >>> 0;
                b58[it1] = carry % BASE >>> 0;
                carry = carry / BASE >>> 0;
            }
            if (carry !== 0) throw new Error('Non-zero carry');
            length = i;
            pbegin++;
        }
        var it2 = size - length;
        while(it2 !== size && b58[it2] === 0)it2++;
        var str = LEADER.repeat(zeroes);
        for(; it2 < size; ++it2)str += ALPHABET.charAt(b58[it2]);
        return str;
    }
    function decodeUnsafe(source) {
        if (typeof source !== 'string') throw new TypeError('Expected String');
        if (source.length === 0) return new Uint8Array();
        var psz = 0;
        if (source[psz] === ' ') return;
        var zeroes = 0;
        var length = 0;
        while(source[psz] === LEADER){
            zeroes++;
            psz++;
        }
        var size = (source.length - psz) * FACTOR + 1 >>> 0;
        var b256 = new Uint8Array(size);
        while(source[psz]){
            var carry = BASE_MAP[source.charCodeAt(psz)];
            if (carry === 255) return;
            var i = 0;
            for(var it3 = size - 1; (carry !== 0 || i < length) && it3 !== -1; it3--, i++){
                carry += BASE * b256[it3] >>> 0;
                b256[it3] = carry % 256 >>> 0;
                carry = carry / 256 >>> 0;
            }
            if (carry !== 0) throw new Error('Non-zero carry');
            length = i;
            psz++;
        }
        if (source[psz] === ' ') return;
        var it4 = size - length;
        while(it4 !== size && b256[it4] === 0)it4++;
        var vch = new Uint8Array(zeroes + (size - it4));
        var j = zeroes;
        while(it4 !== size)vch[j++] = b256[it4++];
        return vch;
    }
    function decode(string) {
        var buffer = decodeUnsafe(string);
        if (buffer) return buffer;
        throw new Error(`Non-${name} character`);
    }
    return {
        encode: encode,
        decodeUnsafe: decodeUnsafe,
        decode: decode
    };
}
var src = base;
var _brrp__multiformats_scope_baseX = src;
module.exports = _brrp__multiformats_scope_baseX;

},{}],"63xDB":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var base = require('./base.js');
const base32 = base.rfc4648({
    prefix: 'b',
    name: 'base32',
    alphabet: 'abcdefghijklmnopqrstuvwxyz234567',
    bitsPerChar: 5
});
const base32upper = base.rfc4648({
    prefix: 'B',
    name: 'base32upper',
    alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567',
    bitsPerChar: 5
});
const base32pad = base.rfc4648({
    prefix: 'c',
    name: 'base32pad',
    alphabet: 'abcdefghijklmnopqrstuvwxyz234567=',
    bitsPerChar: 5
});
const base32padupper = base.rfc4648({
    prefix: 'C',
    name: 'base32padupper',
    alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=',
    bitsPerChar: 5
});
const base32hex = base.rfc4648({
    prefix: 'v',
    name: 'base32hex',
    alphabet: '0123456789abcdefghijklmnopqrstuv',
    bitsPerChar: 5
});
const base32hexupper = base.rfc4648({
    prefix: 'V',
    name: 'base32hexupper',
    alphabet: '0123456789ABCDEFGHIJKLMNOPQRSTUV',
    bitsPerChar: 5
});
const base32hexpad = base.rfc4648({
    prefix: 't',
    name: 'base32hexpad',
    alphabet: '0123456789abcdefghijklmnopqrstuv=',
    bitsPerChar: 5
});
const base32hexpadupper = base.rfc4648({
    prefix: 'T',
    name: 'base32hexpadupper',
    alphabet: '0123456789ABCDEFGHIJKLMNOPQRSTUV=',
    bitsPerChar: 5
});
const base32z = base.rfc4648({
    prefix: 'h',
    name: 'base32z',
    alphabet: 'ybndrfg8ejkmcpqxot1uwisza345h769',
    bitsPerChar: 5
});
exports.base32 = base32;
exports.base32hex = base32hex;
exports.base32hexpad = base32hexpad;
exports.base32hexpadupper = base32hexpadupper;
exports.base32hexupper = base32hexupper;
exports.base32pad = base32pad;
exports.base32padupper = base32padupper;
exports.base32upper = base32upper;
exports.base32z = base32z;

},{"./base.js":"aX8fr"}],"hDIMN":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
const textDecoder = new TextDecoder();
function decodeVarint(bytes, offset) {
    let v = 0;
    for(let shift = 0;; shift += 7){
        if (shift >= 64) throw new Error('protobuf: varint overflow');
        if (offset >= bytes.length) throw new Error('protobuf: unexpected end of data');
        const b = bytes[offset++];
        v += shift < 28 ? (b & 127) << shift : (b & 127) * 2 ** shift;
        if (b < 128) break;
    }
    return [
        v,
        offset
    ];
}
function decodeBytes(bytes, offset) {
    let byteLen;
    [byteLen, offset] = decodeVarint(bytes, offset);
    const postOffset = offset + byteLen;
    if (byteLen < 0 || postOffset < 0) throw new Error('protobuf: invalid length');
    if (postOffset > bytes.length) throw new Error('protobuf: unexpected end of data');
    return [
        bytes.subarray(offset, postOffset),
        postOffset
    ];
}
function decodeKey(bytes, index) {
    let wire;
    [wire, index] = decodeVarint(bytes, index);
    return [
        wire & 7,
        wire >> 3,
        index
    ];
}
function decodeLink(bytes) {
    const link = {
    };
    const l = bytes.length;
    let index = 0;
    while(index < l){
        let wireType, fieldNum;
        [wireType, fieldNum, index] = decodeKey(bytes, index);
        if (fieldNum === 1) {
            if (link.Hash) throw new Error('protobuf: (PBLink) duplicate Hash section');
            if (wireType !== 2) throw new Error(`protobuf: (PBLink) wrong wireType (${wireType}) for Hash`);
            if (link.Name !== undefined) throw new Error('protobuf: (PBLink) invalid order, found Name before Hash');
            if (link.Tsize !== undefined) throw new Error('protobuf: (PBLink) invalid order, found Tsize before Hash');
            [link.Hash, index] = decodeBytes(bytes, index);
        } else if (fieldNum === 2) {
            if (link.Name !== undefined) throw new Error('protobuf: (PBLink) duplicate Name section');
            if (wireType !== 2) throw new Error(`protobuf: (PBLink) wrong wireType (${wireType}) for Name`);
            if (link.Tsize !== undefined) throw new Error('protobuf: (PBLink) invalid order, found Tsize before Name');
            let byts;
            [byts, index] = decodeBytes(bytes, index);
            link.Name = textDecoder.decode(byts);
        } else if (fieldNum === 3) {
            if (link.Tsize !== undefined) throw new Error('protobuf: (PBLink) duplicate Tsize section');
            if (wireType !== 0) throw new Error(`protobuf: (PBLink) wrong wireType (${wireType}) for Tsize`);
            [link.Tsize, index] = decodeVarint(bytes, index);
        } else throw new Error(`protobuf: (PBLink) invalid fieldNumber, expected 1, 2 or 3, got ${fieldNum}`);
    }
    if (index > l) throw new Error('protobuf: (PBLink) unexpected end of data');
    return link;
}
function decodeNode(bytes) {
    const l = bytes.length;
    let index = 0;
    let links;
    let linksBeforeData = false;
    let data;
    while(index < l){
        let wireType, fieldNum;
        [wireType, fieldNum, index] = decodeKey(bytes, index);
        if (wireType !== 2) throw new Error(`protobuf: (PBNode) invalid wireType, expected 2, got ${wireType}`);
        if (fieldNum === 1) {
            if (data) throw new Error('protobuf: (PBNode) duplicate Data section');
            [data, index] = decodeBytes(bytes, index);
            if (links) linksBeforeData = true;
        } else if (fieldNum === 2) {
            if (linksBeforeData) throw new Error('protobuf: (PBNode) duplicate Links section');
            else if (!links) links = [];
            let byts;
            [byts, index] = decodeBytes(bytes, index);
            links.push(decodeLink(byts));
        } else throw new Error(`protobuf: (PBNode) invalid fieldNumber, expected 1 or 2, got ${fieldNum}`);
    }
    if (index > l) throw new Error('protobuf: (PBNode) unexpected end of data');
    const node = {
    };
    if (data) node.Data = data;
    node.Links = links || [];
    return node;
}
exports.decodeNode = decodeNode;

},{}],"gBGpm":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
const textEncoder = new TextEncoder();
const maxInt32 = 2 ** 32;
const maxUInt32 = 2 ** 31;
function encodeLink(link, bytes) {
    let i = bytes.length;
    if (typeof link.Tsize === 'number') {
        if (link.Tsize < 0) throw new Error('Tsize cannot be negative');
        if (!Number.isSafeInteger(link.Tsize)) throw new Error('Tsize too large for encoding');
        i = encodeVarint(bytes, i, link.Tsize) - 1;
        bytes[i] = 24;
    }
    if (typeof link.Name === 'string') {
        const nameBytes = textEncoder.encode(link.Name);
        i -= nameBytes.length;
        bytes.set(nameBytes, i);
        i = encodeVarint(bytes, i, nameBytes.length) - 1;
        bytes[i] = 18;
    }
    if (link.Hash) {
        i -= link.Hash.length;
        bytes.set(link.Hash, i);
        i = encodeVarint(bytes, i, link.Hash.length) - 1;
        bytes[i] = 10;
    }
    return bytes.length - i;
}
function encodeNode(node) {
    const size = sizeNode(node);
    const bytes = new Uint8Array(size);
    let i = size;
    if (node.Data) {
        i -= node.Data.length;
        bytes.set(node.Data, i);
        i = encodeVarint(bytes, i, node.Data.length) - 1;
        bytes[i] = 10;
    }
    if (node.Links) for(let index = node.Links.length - 1; index >= 0; index--){
        const size = encodeLink(node.Links[index], bytes.subarray(0, i));
        i -= size;
        i = encodeVarint(bytes, i, size) - 1;
        bytes[i] = 18;
    }
    return bytes;
}
function sizeLink(link) {
    let n = 0;
    if (link.Hash) {
        const l = link.Hash.length;
        n += 1 + l + sov(l);
    }
    if (typeof link.Name === 'string') {
        const l = textEncoder.encode(link.Name).length;
        n += 1 + l + sov(l);
    }
    if (typeof link.Tsize === 'number') n += 1 + sov(link.Tsize);
    return n;
}
function sizeNode(node) {
    let n = 0;
    if (node.Data) {
        const l = node.Data.length;
        n += 1 + l + sov(l);
    }
    if (node.Links) for (const link of node.Links){
        const l = sizeLink(link);
        n += 1 + l + sov(l);
    }
    return n;
}
function encodeVarint(bytes, offset, v) {
    offset -= sov(v);
    const base = offset;
    while(v >= maxUInt32){
        bytes[offset++] = v & 127 | 128;
        v /= 128;
    }
    while(v >= 128){
        bytes[offset++] = v & 127 | 128;
        v >>>= 7;
    }
    bytes[offset] = v;
    return base;
}
function sov(x) {
    if (x % 2 === 0) x++;
    return Math.floor((len64(x) + 6) / 7);
}
function len64(x) {
    let n = 0;
    if (x >= maxInt32) {
        x = Math.floor(x / maxInt32);
        n = 32;
    }
    if (x >= 65536) {
        x >>>= 16;
        n += 16;
    }
    if (x >= 256) {
        x >>>= 8;
        n += 8;
    }
    return n + len8tab[x];
}
const len8tab = [
    0,
    1,
    2,
    2,
    3,
    3,
    3,
    3,
    4,
    4,
    4,
    4,
    4,
    4,
    4,
    4,
    5,
    5,
    5,
    5,
    5,
    5,
    5,
    5,
    5,
    5,
    5,
    5,
    5,
    5,
    5,
    5,
    6,
    6,
    6,
    6,
    6,
    6,
    6,
    6,
    6,
    6,
    6,
    6,
    6,
    6,
    6,
    6,
    6,
    6,
    6,
    6,
    6,
    6,
    6,
    6,
    6,
    6,
    6,
    6,
    6,
    6,
    6,
    6,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    7,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8,
    8
];
exports.encodeNode = encodeNode;

},{}],"4tLhM":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid1 = require('multiformats/cid');
const pbNodeProperties = [
    'Data',
    'Links'
];
const pbLinkProperties = [
    'Hash',
    'Name',
    'Tsize'
];
const textEncoder = new TextEncoder();
function linkComparator(a, b) {
    if (a === b) return 0;
    const abuf = a.Name ? textEncoder.encode(a.Name) : [];
    const bbuf = b.Name ? textEncoder.encode(b.Name) : [];
    let x = abuf.length;
    let y = bbuf.length;
    for(let i = 0, len = Math.min(x, y); i < len; ++i)if (abuf[i] !== bbuf[i]) {
        x = abuf[i];
        y = bbuf[i];
        break;
    }
    return x < y ? -1 : y < x ? 1 : 0;
}
function hasOnlyProperties(node, properties) {
    return !Object.keys(node).some((p)=>!properties.includes(p)
    );
}
function asLink(link) {
    if (typeof link.asCID === 'object') {
        const Hash = cid1.CID.asCID(link);
        if (!Hash) throw new TypeError('Invalid DAG-PB form');
        return {
            Hash
        };
    }
    if (typeof link !== 'object' || Array.isArray(link)) throw new TypeError('Invalid DAG-PB form');
    const pbl = {
    };
    if (link.Hash) {
        let cid$1 = cid1.CID.asCID(link.Hash);
        try {
            if (!cid$1) {
                if (typeof link.Hash === 'string') cid$1 = cid1.CID.parse(link.Hash);
                else if (link.Hash instanceof Uint8Array) cid$1 = cid1.CID.decode(link.Hash);
            }
        } catch (e) {
            throw new TypeError(`Invalid DAG-PB form: ${e.message}`);
        }
        if (cid$1) pbl.Hash = cid$1;
    }
    if (!pbl.Hash) throw new TypeError('Invalid DAG-PB form');
    if (typeof link.Name === 'string') pbl.Name = link.Name;
    if (typeof link.Tsize === 'number') pbl.Tsize = link.Tsize;
    return pbl;
}
function prepare(node) {
    if (node instanceof Uint8Array || typeof node === 'string') node = {
        Data: node
    };
    if (typeof node !== 'object' || Array.isArray(node)) throw new TypeError('Invalid DAG-PB form');
    const pbn = {
    };
    if (node.Data !== undefined) {
        if (typeof node.Data === 'string') pbn.Data = textEncoder.encode(node.Data);
        else if (node.Data instanceof Uint8Array) pbn.Data = node.Data;
        else throw new TypeError('Invalid DAG-PB form');
    }
    if (node.Links !== undefined) {
        if (Array.isArray(node.Links)) {
            pbn.Links = node.Links.map(asLink);
            pbn.Links.sort(linkComparator);
        } else throw new TypeError('Invalid DAG-PB form');
    } else pbn.Links = [];
    return pbn;
}
function validate(node) {
    if (!node || typeof node !== 'object' || Array.isArray(node)) throw new TypeError('Invalid DAG-PB form');
    if (!hasOnlyProperties(node, pbNodeProperties)) throw new TypeError('Invalid DAG-PB form (extraneous properties)');
    if (node.Data !== undefined && !(node.Data instanceof Uint8Array)) throw new TypeError('Invalid DAG-PB form (Data must be a Uint8Array)');
    if (!Array.isArray(node.Links)) throw new TypeError('Invalid DAG-PB form (Links must be an array)');
    for(let i = 0; i < node.Links.length; i++){
        const link = node.Links[i];
        if (!link || typeof link !== 'object' || Array.isArray(link)) throw new TypeError('Invalid DAG-PB form (bad link object)');
        if (!hasOnlyProperties(link, pbLinkProperties)) throw new TypeError('Invalid DAG-PB form (extraneous properties on link object)');
        if (!link.Hash) throw new TypeError('Invalid DAG-PB form (link must have a Hash)');
        if (link.Hash.asCID !== link.Hash) throw new TypeError('Invalid DAG-PB form (link Hash must be a CID)');
        if (link.Name !== undefined && typeof link.Name !== 'string') throw new TypeError('Invalid DAG-PB form (link Name must be a string)');
        if (link.Tsize !== undefined && (typeof link.Tsize !== 'number' || link.Tsize % 1 !== 0)) throw new TypeError('Invalid DAG-PB form (link Tsize must be an integer)');
        if (i > 0 && linkComparator(link, node.Links[i - 1]) === -1) throw new TypeError('Invalid DAG-PB form (links must be sorted by Name bytes)');
    }
}
function createNode(data, links = []) {
    return prepare({
        Data: data,
        Links: links
    });
}
function createLink(name, size, cid) {
    return asLink({
        Hash: cid,
        Name: name,
        Tsize: size
    });
}
exports.createLink = createLink;
exports.createNode = createNode;
exports.prepare = prepare;
exports.validate = validate;

},{"multiformats/cid":"fJJnW"}],"kSG7F":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cborg = require('cborg');
var cid = require('multiformats/cid');
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n["default"] = e;
    return Object.freeze(n);
}
var cborg__namespace = /*#__PURE__*/ _interopNamespace(cborg);
const CID_CBOR_TAG = 42;
function cidEncoder(obj) {
    if (obj.asCID !== obj) return null;
    const cid$1 = cid.CID.asCID(obj);
    if (!cid$1) return null;
    const bytes = new Uint8Array(cid$1.bytes.byteLength + 1);
    bytes.set(cid$1.bytes, 1);
    return [
        new cborg__namespace.Token(cborg__namespace.Type.tag, CID_CBOR_TAG),
        new cborg__namespace.Token(cborg__namespace.Type.bytes, bytes)
    ];
}
function undefinedEncoder() {
    throw new Error('`undefined` is not supported by the IPLD Data Model and cannot be encoded');
}
function numberEncoder(num) {
    if (Number.isNaN(num)) throw new Error('`NaN` is not supported by the IPLD Data Model and cannot be encoded');
    if (num === Infinity || num === -Infinity) throw new Error('`Infinity` and `-Infinity` is not supported by the IPLD Data Model and cannot be encoded');
    return null;
}
const encodeOptions = {
    float64: true,
    typeEncoders: {
        Object: cidEncoder,
        undefined: undefinedEncoder,
        number: numberEncoder
    }
};
function cidDecoder(bytes) {
    if (bytes[0] !== 0) throw new Error('Invalid CID for CBOR tag 42; expected leading 0x00');
    return cid.CID.decode(bytes.subarray(1));
}
const decodeOptions = {
    allowIndefinite: false,
    allowUndefined: false,
    allowNaN: false,
    allowInfinity: false,
    allowBigInt: true,
    strict: true,
    useMaps: false,
    tags: []
};
decodeOptions.tags[CID_CBOR_TAG] = cidDecoder;
const name = 'dag-cbor';
const code = 113;
const encode = (node)=>cborg__namespace.encode(node, encodeOptions)
;
const decode = (data)=>cborg__namespace.decode(data, decodeOptions)
;
exports.code = code;
exports.decode = decode;
exports.encode = encode;
exports.name = name;

},{"cborg":"6ZYxo","multiformats/cid":"fJJnW"}],"6ZYxo":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var encode = require('./lib/encode.js');
var decode = require('./lib/decode.js');
var token = require('./lib/token.js');
exports.encode = encode.encode;
exports.decode = decode.decode;
exports.Token = token.Token;
exports.Type = token.Type;

},{"./lib/encode.js":"6jVoD","./lib/decode.js":"gB1N0","./lib/token.js":"6kwVw"}],"6jVoD":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var is = require('./is.js');
var token1 = require('./token.js');
var bl = require('./bl.js');
var common = require('./common.js');
var jump = require('./jump.js');
var byteUtils = require('./byte-utils.js');
var _0uint = require('./0uint.js');
var _1negint = require('./1negint.js');
var _2bytes = require('./2bytes.js');
var _3string = require('./3string.js');
var _4array = require('./4array.js');
var _5map = require('./5map.js');
var _6tag = require('./6tag.js');
var _7float = require('./7float.js');
const defaultEncodeOptions = {
    float64: false,
    mapSorter,
    quickEncodeToken: jump.quickEncodeToken
};
const cborEncoders = [];
cborEncoders[token1.Type.uint.major] = _0uint.encodeUint;
cborEncoders[token1.Type.negint.major] = _1negint.encodeNegint;
cborEncoders[token1.Type.bytes.major] = _2bytes.encodeBytes;
cborEncoders[token1.Type.string.major] = _3string.encodeString;
cborEncoders[token1.Type.array.major] = _4array.encodeArray;
cborEncoders[token1.Type.map.major] = _5map.encodeMap;
cborEncoders[token1.Type.tag.major] = _6tag.encodeTag;
cborEncoders[token1.Type.float.major] = _7float.encodeFloat;
const buf1 = new bl.Bl();
class Ref {
    constructor(obj3, parent){
        this.obj = obj3;
        this.parent = parent;
    }
    includes(obj1) {
        let p = this;
        do {
            if (p.obj === obj1) return true;
        }while (p = p.parent)
        return false;
    }
    static createCheck(stack, obj2) {
        if (stack && stack.includes(obj2)) throw new Error(`${common.encodeErrPrefix} object contains circular references`);
        return new Ref(obj2, stack);
    }
}
const simpleTokens = {
    null: new token1.Token(token1.Type.null, null),
    undefined: new token1.Token(token1.Type.undefined, undefined),
    true: new token1.Token(token1.Type.true, true),
    false: new token1.Token(token1.Type.false, false),
    emptyArray: new token1.Token(token1.Type.array, 0),
    emptyMap: new token1.Token(token1.Type.map, 0)
};
const typeEncoders = {
    number (obj, _typ, _options, _refStack) {
        if (!Number.isInteger(obj) || !Number.isSafeInteger(obj)) return new token1.Token(token1.Type.float, obj);
        else if (obj >= 0) return new token1.Token(token1.Type.uint, obj);
        else return new token1.Token(token1.Type.negint, obj);
    },
    bigint (obj, _typ, _options, _refStack) {
        if (obj >= BigInt(0)) return new token1.Token(token1.Type.uint, obj);
        else return new token1.Token(token1.Type.negint, obj);
    },
    Uint8Array (obj, _typ, _options, _refStack) {
        return new token1.Token(token1.Type.bytes, obj);
    },
    string (obj, _typ, _options, _refStack) {
        return new token1.Token(token1.Type.string, obj);
    },
    boolean (obj, _typ, _options, _refStack) {
        return obj ? simpleTokens.true : simpleTokens.false;
    },
    null (_obj, _typ, _options, _refStack) {
        return simpleTokens.null;
    },
    undefined (_obj, _typ, _options, _refStack) {
        return simpleTokens.undefined;
    },
    ArrayBuffer (obj, _typ, _options, _refStack) {
        return new token1.Token(token1.Type.bytes, new Uint8Array(obj));
    },
    DataView (obj, _typ, _options, _refStack) {
        return new token1.Token(token1.Type.bytes, new Uint8Array(obj.buffer, obj.byteOffset, obj.byteLength));
    },
    Array (obj, _typ, options, refStack) {
        if (!obj.length) {
            if (options.addBreakTokens === true) return [
                simpleTokens.emptyArray,
                new token1.Token(token1.Type.break)
            ];
            return simpleTokens.emptyArray;
        }
        refStack = Ref.createCheck(refStack, obj);
        const entries = [];
        let i = 0;
        for (const e of obj)entries[i++] = objectToTokens(e, options, refStack);
        if (options.addBreakTokens) return [
            new token1.Token(token1.Type.array, obj.length),
            entries,
            new token1.Token(token1.Type.break)
        ];
        return [
            new token1.Token(token1.Type.array, obj.length),
            entries
        ];
    },
    Object (obj, typ, options, refStack) {
        const isMap = typ !== 'Object';
        const keys = isMap ? obj.keys() : Object.keys(obj);
        const length = isMap ? obj.size : keys.length;
        if (!length) {
            if (options.addBreakTokens === true) return [
                simpleTokens.emptyMap,
                new token1.Token(token1.Type.break)
            ];
            return simpleTokens.emptyMap;
        }
        refStack = Ref.createCheck(refStack, obj);
        const entries = [];
        let i = 0;
        for (const key of keys)entries[i++] = [
            objectToTokens(key, options, refStack),
            objectToTokens(isMap ? obj.get(key) : obj[key], options, refStack)
        ];
        sortMapEntries(entries, options);
        if (options.addBreakTokens) return [
            new token1.Token(token1.Type.map, length),
            entries,
            new token1.Token(token1.Type.break)
        ];
        return [
            new token1.Token(token1.Type.map, length),
            entries
        ];
    }
};
typeEncoders.Map = typeEncoders.Object;
typeEncoders.Buffer = typeEncoders.Uint8Array;
for (const typ1 of 'Uint8Clamped Uint16 Uint32 Int8 Int16 Int32 BigUint64 BigInt64 Float32 Float64'.split(' '))typeEncoders[`${typ1}Array`] = typeEncoders.DataView;
function objectToTokens(obj, options = {
}, refStack) {
    const typ = is.is(obj);
    const customTypeEncoder = options && options.typeEncoders && options.typeEncoders[typ] || typeEncoders[typ];
    if (typeof customTypeEncoder === 'function') {
        const tokens = customTypeEncoder(obj, typ, options, refStack);
        if (tokens != null) return tokens;
    }
    const typeEncoder = typeEncoders[typ];
    if (!typeEncoder) throw new Error(`${common.encodeErrPrefix} unsupported type: ${typ}`);
    return typeEncoder(obj, typ, options, refStack);
}
function sortMapEntries(entries, options) {
    if (options.mapSorter) entries.sort(options.mapSorter);
}
function mapSorter(e1, e2) {
    const keyToken1 = Array.isArray(e1[0]) ? e1[0][0] : e1[0];
    const keyToken2 = Array.isArray(e2[0]) ? e2[0][0] : e2[0];
    if (keyToken1.type !== keyToken2.type) return keyToken1.type.compare(keyToken2.type);
    const major = keyToken1.type.major;
    const tcmp = cborEncoders[major].compareTokens(keyToken1, keyToken2);
    if (tcmp === 0) console.warn('WARNING: complex key types used, CBOR key sorting guarantees are gone');
    return tcmp;
}
function tokensToEncoded(buf, tokens, encoders, options) {
    if (Array.isArray(tokens)) for (const token of tokens)tokensToEncoded(buf, token, encoders, options);
    else encoders[tokens.type.major](buf, tokens, options);
}
function encodeCustom(data, encoders, options) {
    const tokens = objectToTokens(data, options);
    if (!Array.isArray(tokens) && options.quickEncodeToken) {
        const quickBytes = options.quickEncodeToken(tokens);
        if (quickBytes) return quickBytes;
        const encoder = encoders[tokens.type.major];
        if (encoder.encodedSize) {
            const size = encoder.encodedSize(tokens, options);
            const buf = new bl.Bl(size);
            encoder(buf, tokens, options);
            if (buf.chunks.length !== 1) throw new Error(`Unexpected error: pre-calculated length for ${tokens} was wrong`);
            return byteUtils.asU8A(buf.chunks[0]);
        }
    }
    tokensToEncoded(buf1, tokens, encoders, options);
    return buf1.toBytes(true);
}
function encode(data, options) {
    options = Object.assign({
    }, defaultEncodeOptions, options);
    return encodeCustom(data, cborEncoders, options);
}
exports.Ref = Ref;
exports.encode = encode;
exports.encodeCustom = encodeCustom;
exports.objectToTokens = objectToTokens;

},{"./is.js":"jVCAA","./token.js":"6kwVw","./bl.js":"gON52","./common.js":"6SV2V","./jump.js":"boLQN","./byte-utils.js":"akZGX","./0uint.js":"9GKB7","./1negint.js":"fYEM6","./2bytes.js":"4MD8k","./3string.js":"20od8","./4array.js":"7uu23","./5map.js":"59MxO","./6tag.js":"dlZcd","./7float.js":"2cl9I"}],"jVCAA":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
const typeofs = [
    'string',
    'number',
    'bigint',
    'symbol'
];
const objectTypeNames = [
    'Function',
    'Generator',
    'AsyncGenerator',
    'GeneratorFunction',
    'AsyncGeneratorFunction',
    'AsyncFunction',
    'Observable',
    'Array',
    'Buffer',
    'Object',
    'RegExp',
    'Date',
    'Error',
    'Map',
    'Set',
    'WeakMap',
    'WeakSet',
    'ArrayBuffer',
    'SharedArrayBuffer',
    'DataView',
    'Promise',
    'URL',
    'HTMLElement',
    'Int8Array',
    'Uint8Array',
    'Uint8ClampedArray',
    'Int16Array',
    'Uint16Array',
    'Int32Array',
    'Uint32Array',
    'Float32Array',
    'Float64Array',
    'BigInt64Array',
    'BigUint64Array'
];
function is(value) {
    if (value === null) return 'null';
    if (value === undefined) return 'undefined';
    if (value === true || value === false) return 'boolean';
    const typeOf = typeof value;
    if (typeofs.includes(typeOf)) return typeOf;
    if (typeOf === 'function') return 'Function';
    if (Array.isArray(value)) return 'Array';
    if (isBuffer(value)) return 'Buffer';
    const objectType = getObjectType(value);
    if (objectType) return objectType;
    return 'Object';
}
function isBuffer(value) {
    return value && value.constructor && value.constructor.isBuffer && value.constructor.isBuffer.call(null, value);
}
function getObjectType(value) {
    const objectTypeName = Object.prototype.toString.call(value).slice(8, -1);
    if (objectTypeNames.includes(objectTypeName)) return objectTypeName;
    return undefined;
}
exports.is = is;

},{}],"6kwVw":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
class Type {
    constructor(major, name, terminal){
        this.major = major;
        this.majorEncoded = major << 5;
        this.name = name;
        this.terminal = terminal;
    }
    toString() {
        return `Type[${this.major}].${this.name}`;
    }
    compare(typ) {
        return this.major < typ.major ? -1 : this.major > typ.major ? 1 : 0;
    }
}
Type.uint = new Type(0, 'uint', true);
Type.negint = new Type(1, 'negint', true);
Type.bytes = new Type(2, 'bytes', true);
Type.string = new Type(3, 'string', true);
Type.array = new Type(4, 'array', false);
Type.map = new Type(5, 'map', false);
Type.tag = new Type(6, 'tag', false);
Type.float = new Type(7, 'float', true);
Type.false = new Type(7, 'false', true);
Type.true = new Type(7, 'true', true);
Type.null = new Type(7, 'null', true);
Type.undefined = new Type(7, 'undefined', true);
Type.break = new Type(7, 'break', true);
class Token {
    constructor(type, value, encodedLength){
        this.type = type;
        this.value = value;
        this.encodedLength = encodedLength;
        this.encodedBytes = undefined;
    }
    toString() {
        return `Token[${this.type}].${this.value}`;
    }
}
exports.Token = Token;
exports.Type = Type;

},{}],"gON52":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var byteUtils = require('./byte-utils.js');
const defaultChunkSize = 256;
class Bl {
    constructor(chunkSize = defaultChunkSize){
        this.chunkSize = chunkSize;
        this.cursor = 0;
        this.maxCursor = -1;
        this.chunks = [];
        this._initReuseChunk = null;
    }
    reset() {
        this.chunks = [];
        this.cursor = 0;
        this.maxCursor = -1;
        if (this._initReuseChunk !== null) {
            this.chunks.push(this._initReuseChunk);
            this.maxCursor = this._initReuseChunk.length - 1;
        }
    }
    push(bytes) {
        let topChunk = this.chunks[this.chunks.length - 1];
        const newMax = this.cursor + bytes.length;
        if (newMax <= this.maxCursor + 1) {
            const chunkPos = topChunk.length - (this.maxCursor - this.cursor) - 1;
            topChunk.set(bytes, chunkPos);
        } else {
            if (topChunk) {
                const chunkPos = topChunk.length - (this.maxCursor - this.cursor) - 1;
                if (chunkPos < topChunk.length) {
                    this.chunks[this.chunks.length - 1] = topChunk.subarray(0, chunkPos);
                    this.maxCursor = this.cursor - 1;
                }
            }
            if (bytes.length < 64 && bytes.length < this.chunkSize) {
                topChunk = byteUtils.alloc(this.chunkSize);
                this.chunks.push(topChunk);
                this.maxCursor += topChunk.length;
                if (this._initReuseChunk === null) this._initReuseChunk = topChunk;
                topChunk.set(bytes, 0);
            } else {
                this.chunks.push(bytes);
                this.maxCursor += bytes.length;
            }
        }
        this.cursor += bytes.length;
    }
    toBytes(reset = false) {
        let byts;
        if (this.chunks.length === 1) {
            const chunk = this.chunks[0];
            if (reset && this.cursor > chunk.length / 2) {
                byts = this.cursor === chunk.length ? chunk : chunk.subarray(0, this.cursor);
                this._initReuseChunk = null;
                this.chunks = [];
            } else byts = byteUtils.slice(chunk, 0, this.cursor);
        } else byts = byteUtils.concat(this.chunks, this.cursor);
        if (reset) this.reset();
        return byts;
    }
}
exports.Bl = Bl;

},{"./byte-utils.js":"akZGX"}],"akZGX":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
const useBuffer = globalThis.process && !globalThis.process.browser && globalThis.Buffer && typeof globalThis.Buffer.isBuffer === 'function';
const textDecoder = new TextDecoder();
const textEncoder = new TextEncoder();
function isBuffer(buf) {
    return useBuffer && globalThis.Buffer.isBuffer(buf);
}
function asU8A(buf) {
    if (!(buf instanceof Uint8Array)) return Uint8Array.from(buf);
    return isBuffer(buf) ? new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength) : buf;
}
const toString = useBuffer ? (bytes, start, end)=>{
    return end - start > 64 ? globalThis.Buffer.from(bytes.subarray(start, end)).toString('utf8') : utf8Slice(bytes, start, end);
} : (bytes, start, end)=>{
    return end - start > 64 ? textDecoder.decode(bytes.subarray(start, end)) : utf8Slice(bytes, start, end);
};
const fromString = useBuffer ? (string)=>{
    return string.length > 64 ? globalThis.Buffer.from(string) : utf8ToBytes(string);
} : (string)=>{
    return string.length > 64 ? textEncoder.encode(string) : utf8ToBytes(string);
};
const fromArray = (arr)=>{
    return Uint8Array.from(arr);
};
const slice = useBuffer ? (bytes, start, end)=>{
    if (isBuffer(bytes)) return new Uint8Array(bytes.subarray(start, end));
    return bytes.slice(start, end);
} : (bytes, start, end)=>{
    return bytes.slice(start, end);
};
const concat = useBuffer ? (chunks, length)=>{
    chunks = chunks.map((c)=>c instanceof Uint8Array ? c : globalThis.Buffer.from(c)
    );
    return asU8A(globalThis.Buffer.concat(chunks, length));
} : (chunks, length)=>{
    const out = new Uint8Array(length);
    let off = 0;
    for (let b of chunks){
        if (off + b.length > out.length) b = b.subarray(0, out.length - off);
        out.set(b, off);
        off += b.length;
    }
    return out;
};
const alloc = useBuffer ? (size)=>{
    return globalThis.Buffer.allocUnsafe(size);
} : (size)=>{
    return new Uint8Array(size);
};
const toHex = useBuffer ? (d)=>{
    if (typeof d === 'string') return d;
    return globalThis.Buffer.from(toBytes(d)).toString('hex');
} : (d)=>{
    if (typeof d === 'string') return d;
    return Array.prototype.reduce.call(toBytes(d), (p, c)=>`${p}${c.toString(16).padStart(2, '0')}`
    , '');
};
const fromHex = useBuffer ? (hex)=>{
    if (hex instanceof Uint8Array) return hex;
    return globalThis.Buffer.from(hex, 'hex');
} : (hex)=>{
    if (hex instanceof Uint8Array) return hex;
    if (!hex.length) return new Uint8Array(0);
    return new Uint8Array(hex.split('').map((c, i, d)=>i % 2 === 0 ? `0x${c}${d[i + 1]}` : ''
    ).filter(Boolean).map((e)=>parseInt(e, 16)
    ));
};
function toBytes(obj) {
    if (obj instanceof Uint8Array && obj.constructor.name === 'Uint8Array') return obj;
    if (obj instanceof ArrayBuffer) return new Uint8Array(obj);
    if (ArrayBuffer.isView(obj)) return new Uint8Array(obj.buffer, obj.byteOffset, obj.byteLength);
    throw new Error('Unknown type, must be binary type');
}
function compare(b1, b2) {
    if (isBuffer(b1) && isBuffer(b2)) return b1.compare(b2);
    for(let i = 0; i < b1.length; i++){
        if (b1[i] === b2[i]) continue;
        return b1[i] < b2[i] ? -1 : 1;
    }
    return 0;
}
function utf8ToBytes(string, units = Infinity) {
    let codePoint;
    const length = string.length;
    let leadSurrogate = null;
    const bytes = [];
    for(let i = 0; i < length; ++i){
        codePoint = string.charCodeAt(i);
        if (codePoint > 55295 && codePoint < 57344) {
            if (!leadSurrogate) {
                if (codePoint > 56319) {
                    if ((units -= 3) > -1) bytes.push(239, 191, 189);
                    continue;
                } else if (i + 1 === length) {
                    if ((units -= 3) > -1) bytes.push(239, 191, 189);
                    continue;
                }
                leadSurrogate = codePoint;
                continue;
            }
            if (codePoint < 56320) {
                if ((units -= 3) > -1) bytes.push(239, 191, 189);
                leadSurrogate = codePoint;
                continue;
            }
            codePoint = (leadSurrogate - 55296 << 10 | codePoint - 56320) + 65536;
        } else if (leadSurrogate) {
            if ((units -= 3) > -1) bytes.push(239, 191, 189);
        }
        leadSurrogate = null;
        if (codePoint < 128) {
            if ((units -= 1) < 0) break;
            bytes.push(codePoint);
        } else if (codePoint < 2048) {
            if ((units -= 2) < 0) break;
            bytes.push(codePoint >> 6 | 192, codePoint & 63 | 128);
        } else if (codePoint < 65536) {
            if ((units -= 3) < 0) break;
            bytes.push(codePoint >> 12 | 224, codePoint >> 6 & 63 | 128, codePoint & 63 | 128);
        } else if (codePoint < 1114112) {
            if ((units -= 4) < 0) break;
            bytes.push(codePoint >> 18 | 240, codePoint >> 12 & 63 | 128, codePoint >> 6 & 63 | 128, codePoint & 63 | 128);
        } else throw new Error('Invalid code point');
    }
    return bytes;
}
function utf8Slice(buf, offset, end) {
    const res = [];
    while(offset < end){
        const firstByte = buf[offset];
        let codePoint = null;
        let bytesPerSequence = firstByte > 239 ? 4 : firstByte > 223 ? 3 : firstByte > 191 ? 2 : 1;
        if (offset + bytesPerSequence <= end) {
            let secondByte, thirdByte, fourthByte, tempCodePoint;
            switch(bytesPerSequence){
                case 1:
                    if (firstByte < 128) codePoint = firstByte;
                    break;
                case 2:
                    secondByte = buf[offset + 1];
                    if ((secondByte & 192) === 128) {
                        tempCodePoint = (firstByte & 31) << 6 | secondByte & 63;
                        if (tempCodePoint > 127) codePoint = tempCodePoint;
                    }
                    break;
                case 3:
                    secondByte = buf[offset + 1];
                    thirdByte = buf[offset + 2];
                    if ((secondByte & 192) === 128 && (thirdByte & 192) === 128) {
                        tempCodePoint = (firstByte & 15) << 12 | (secondByte & 63) << 6 | thirdByte & 63;
                        if (tempCodePoint > 2047 && (tempCodePoint < 55296 || tempCodePoint > 57343)) codePoint = tempCodePoint;
                    }
                    break;
                case 4:
                    secondByte = buf[offset + 1];
                    thirdByte = buf[offset + 2];
                    fourthByte = buf[offset + 3];
                    if ((secondByte & 192) === 128 && (thirdByte & 192) === 128 && (fourthByte & 192) === 128) {
                        tempCodePoint = (firstByte & 15) << 18 | (secondByte & 63) << 12 | (thirdByte & 63) << 6 | fourthByte & 63;
                        if (tempCodePoint > 65535 && tempCodePoint < 1114112) codePoint = tempCodePoint;
                    }
            }
        }
        if (codePoint === null) {
            codePoint = 65533;
            bytesPerSequence = 1;
        } else if (codePoint > 65535) {
            codePoint -= 65536;
            res.push(codePoint >>> 10 & 1023 | 55296);
            codePoint = 56320 | codePoint & 1023;
        }
        res.push(codePoint);
        offset += bytesPerSequence;
    }
    return decodeCodePointsArray(res);
}
const MAX_ARGUMENTS_LENGTH = 4096;
function decodeCodePointsArray(codePoints) {
    const len = codePoints.length;
    if (len <= MAX_ARGUMENTS_LENGTH) return String.fromCharCode.apply(String, codePoints);
    let res = '';
    let i = 0;
    while(i < len)res += String.fromCharCode.apply(String, codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH));
    return res;
}
exports.alloc = alloc;
exports.asU8A = asU8A;
exports.compare = compare;
exports.concat = concat;
exports.decodeCodePointsArray = decodeCodePointsArray;
exports.fromArray = fromArray;
exports.fromHex = fromHex;
exports.fromString = fromString;
exports.slice = slice;
exports.toHex = toHex;
exports.toString = toString;
exports.useBuffer = useBuffer;

},{}],"6SV2V":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
const decodeErrPrefix = 'CBOR decode error:';
const encodeErrPrefix = 'CBOR encode error:';
const uintMinorPrefixBytes = [];
uintMinorPrefixBytes[23] = 1;
uintMinorPrefixBytes[24] = 2;
uintMinorPrefixBytes[25] = 3;
uintMinorPrefixBytes[26] = 5;
uintMinorPrefixBytes[27] = 9;
function assertEnoughData(data, pos, need) {
    if (data.length - pos < need) throw new Error(`${decodeErrPrefix} not enough data for type`);
}
exports.assertEnoughData = assertEnoughData;
exports.decodeErrPrefix = decodeErrPrefix;
exports.encodeErrPrefix = encodeErrPrefix;
exports.uintMinorPrefixBytes = uintMinorPrefixBytes;

},{}],"boLQN":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var token = require('./token.js');
var _0uint = require('./0uint.js');
var _1negint = require('./1negint.js');
var _2bytes = require('./2bytes.js');
var _3string = require('./3string.js');
var _4array = require('./4array.js');
var _5map = require('./5map.js');
var _6tag = require('./6tag.js');
var _7float = require('./7float.js');
var common = require('./common.js');
var byteUtils = require('./byte-utils.js');
function invalidMinor(data, pos, minor) {
    throw new Error(`${common.decodeErrPrefix} encountered invalid minor (${minor}) for major ${data[pos] >>> 5}`);
}
function errorer(msg) {
    return ()=>{
        throw new Error(`${common.decodeErrPrefix} ${msg}`);
    };
}
const jump = [];
for(let i = 0; i <= 23; i++)jump[i] = invalidMinor;
jump[24] = _0uint.decodeUint8;
jump[25] = _0uint.decodeUint16;
jump[26] = _0uint.decodeUint32;
jump[27] = _0uint.decodeUint64;
jump[28] = invalidMinor;
jump[29] = invalidMinor;
jump[30] = invalidMinor;
jump[31] = invalidMinor;
for(let i1 = 32; i1 <= 55; i1++)jump[i1] = invalidMinor;
jump[56] = _1negint.decodeNegint8;
jump[57] = _1negint.decodeNegint16;
jump[58] = _1negint.decodeNegint32;
jump[59] = _1negint.decodeNegint64;
jump[60] = invalidMinor;
jump[61] = invalidMinor;
jump[62] = invalidMinor;
jump[63] = invalidMinor;
for(let i2 = 64; i2 <= 87; i2++)jump[i2] = _2bytes.decodeBytesCompact;
jump[88] = _2bytes.decodeBytes8;
jump[89] = _2bytes.decodeBytes16;
jump[90] = _2bytes.decodeBytes32;
jump[91] = _2bytes.decodeBytes64;
jump[92] = invalidMinor;
jump[93] = invalidMinor;
jump[94] = invalidMinor;
jump[95] = errorer('indefinite length bytes/strings are not supported');
for(let i3 = 96; i3 <= 119; i3++)jump[i3] = _3string.decodeStringCompact;
jump[120] = _3string.decodeString8;
jump[121] = _3string.decodeString16;
jump[122] = _3string.decodeString32;
jump[123] = _3string.decodeString64;
jump[124] = invalidMinor;
jump[125] = invalidMinor;
jump[126] = invalidMinor;
jump[127] = errorer('indefinite length bytes/strings are not supported');
for(let i4 = 128; i4 <= 151; i4++)jump[i4] = _4array.decodeArrayCompact;
jump[152] = _4array.decodeArray8;
jump[153] = _4array.decodeArray16;
jump[154] = _4array.decodeArray32;
jump[155] = _4array.decodeArray64;
jump[156] = invalidMinor;
jump[157] = invalidMinor;
jump[158] = invalidMinor;
jump[159] = _4array.decodeArrayIndefinite;
for(let i5 = 160; i5 <= 183; i5++)jump[i5] = _5map.decodeMapCompact;
jump[184] = _5map.decodeMap8;
jump[185] = _5map.decodeMap16;
jump[186] = _5map.decodeMap32;
jump[187] = _5map.decodeMap64;
jump[188] = invalidMinor;
jump[189] = invalidMinor;
jump[190] = invalidMinor;
jump[191] = _5map.decodeMapIndefinite;
for(let i6 = 192; i6 <= 215; i6++)jump[i6] = _6tag.decodeTagCompact;
jump[216] = _6tag.decodeTag8;
jump[217] = _6tag.decodeTag16;
jump[218] = _6tag.decodeTag32;
jump[219] = _6tag.decodeTag64;
jump[220] = invalidMinor;
jump[221] = invalidMinor;
jump[222] = invalidMinor;
jump[223] = invalidMinor;
for(let i7 = 224; i7 <= 243; i7++)jump[i7] = errorer('simple values are not supported');
jump[244] = invalidMinor;
jump[245] = invalidMinor;
jump[246] = invalidMinor;
jump[247] = _7float.decodeUndefined;
jump[248] = errorer('simple values are not supported');
jump[249] = _7float.decodeFloat16;
jump[250] = _7float.decodeFloat32;
jump[251] = _7float.decodeFloat64;
jump[252] = invalidMinor;
jump[253] = invalidMinor;
jump[254] = invalidMinor;
jump[255] = _7float.decodeBreak;
const quick = [];
for(let i8 = 0; i8 < 24; i8++)quick[i8] = new token.Token(token.Type.uint, i8, 1);
for(let i9 = -1; i9 >= -24; i9--)quick[31 - i9] = new token.Token(token.Type.negint, i9, 1);
quick[64] = new token.Token(token.Type.bytes, new Uint8Array(0), 1);
quick[96] = new token.Token(token.Type.string, '', 1);
quick[128] = new token.Token(token.Type.array, 0, 1);
quick[160] = new token.Token(token.Type.map, 0, 1);
quick[244] = new token.Token(token.Type.false, false, 1);
quick[245] = new token.Token(token.Type.true, true, 1);
quick[246] = new token.Token(token.Type.null, null, 1);
function quickEncodeToken(token$1) {
    switch(token$1.type){
        case token.Type.false:
            return byteUtils.fromArray([
                244
            ]);
        case token.Type.true:
            return byteUtils.fromArray([
                245
            ]);
        case token.Type.null:
            return byteUtils.fromArray([
                246
            ]);
        case token.Type.bytes:
            if (!token$1.value.length) return byteUtils.fromArray([
                64
            ]);
            return;
        case token.Type.string:
            if (token$1.value === '') return byteUtils.fromArray([
                96
            ]);
            return;
        case token.Type.array:
            if (token$1.value === 0) return byteUtils.fromArray([
                128
            ]);
            return;
        case token.Type.map:
            if (token$1.value === 0) return byteUtils.fromArray([
                160
            ]);
            return;
        case token.Type.uint:
            if (token$1.value < 24) return byteUtils.fromArray([
                Number(token$1.value)
            ]);
            return;
        case token.Type.negint:
            if (token$1.value >= -24) return byteUtils.fromArray([
                31 - Number(token$1.value)
            ]);
    }
}
exports.jump = jump;
exports.quick = quick;
exports.quickEncodeToken = quickEncodeToken;

},{"./token.js":"6kwVw","./0uint.js":"9GKB7","./1negint.js":"fYEM6","./2bytes.js":"4MD8k","./3string.js":"20od8","./4array.js":"7uu23","./5map.js":"59MxO","./6tag.js":"dlZcd","./7float.js":"2cl9I","./common.js":"6SV2V","./byte-utils.js":"akZGX"}],"9GKB7":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var token1 = require('./token.js');
var common = require('./common.js');
const uintBoundaries = [
    24,
    256,
    65536,
    4294967296,
    BigInt('18446744073709551616')
];
function readUint8(data, offset, options) {
    common.assertEnoughData(data, offset, 1);
    const value = data[offset];
    if (options.strict === true && value < uintBoundaries[0]) throw new Error(`${common.decodeErrPrefix} integer encoded in more bytes than necessary (strict decode)`);
    return value;
}
function readUint16(data, offset, options) {
    common.assertEnoughData(data, offset, 2);
    const value = data[offset] << 8 | data[offset + 1];
    if (options.strict === true && value < uintBoundaries[1]) throw new Error(`${common.decodeErrPrefix} integer encoded in more bytes than necessary (strict decode)`);
    return value;
}
function readUint32(data, offset, options) {
    common.assertEnoughData(data, offset, 4);
    const value = data[offset] * 16777216 + (data[offset + 1] << 16) + (data[offset + 2] << 8) + data[offset + 3];
    if (options.strict === true && value < uintBoundaries[2]) throw new Error(`${common.decodeErrPrefix} integer encoded in more bytes than necessary (strict decode)`);
    return value;
}
function readUint64(data, offset, options) {
    common.assertEnoughData(data, offset, 8);
    const hi = data[offset] * 16777216 + (data[offset + 1] << 16) + (data[offset + 2] << 8) + data[offset + 3];
    const lo = data[offset + 4] * 16777216 + (data[offset + 5] << 16) + (data[offset + 6] << 8) + data[offset + 7];
    const value = (BigInt(hi) << BigInt(32)) + BigInt(lo);
    if (options.strict === true && value < uintBoundaries[3]) throw new Error(`${common.decodeErrPrefix} integer encoded in more bytes than necessary (strict decode)`);
    if (value <= Number.MAX_SAFE_INTEGER) return Number(value);
    if (options.allowBigInt === true) return value;
    throw new Error(`${common.decodeErrPrefix} integers outside of the safe integer range are not supported`);
}
function decodeUint8(data, pos, _minor, options) {
    return new token1.Token(token1.Type.uint, readUint8(data, pos + 1, options), 2);
}
function decodeUint16(data, pos, _minor, options) {
    return new token1.Token(token1.Type.uint, readUint16(data, pos + 1, options), 3);
}
function decodeUint32(data, pos, _minor, options) {
    return new token1.Token(token1.Type.uint, readUint32(data, pos + 1, options), 5);
}
function decodeUint64(data, pos, _minor, options) {
    return new token1.Token(token1.Type.uint, readUint64(data, pos + 1, options), 9);
}
function encodeUint(buf, token) {
    return encodeUintValue(buf, 0, token.value);
}
function encodeUintValue(buf, major, uint) {
    if (uint < uintBoundaries[0]) {
        const nuint = Number(uint);
        buf.push([
            major | nuint
        ]);
    } else if (uint < uintBoundaries[1]) {
        const nuint = Number(uint);
        buf.push([
            major | 24,
            nuint
        ]);
    } else if (uint < uintBoundaries[2]) {
        const nuint = Number(uint);
        buf.push([
            major | 25,
            nuint >>> 8,
            nuint & 255
        ]);
    } else if (uint < uintBoundaries[3]) {
        const nuint = Number(uint);
        buf.push([
            major | 26,
            nuint >>> 24 & 255,
            nuint >>> 16 & 255,
            nuint >>> 8 & 255,
            nuint & 255
        ]);
    } else {
        const buint = BigInt(uint);
        if (buint < uintBoundaries[4]) {
            const set = [
                major | 27,
                0,
                0,
                0,
                0,
                0,
                0,
                0
            ];
            let lo = Number(buint & BigInt(4294967295));
            let hi = Number(buint >> BigInt(32) & BigInt(4294967295));
            set[8] = lo & 255;
            lo = lo >> 8;
            set[7] = lo & 255;
            lo = lo >> 8;
            set[6] = lo & 255;
            lo = lo >> 8;
            set[5] = lo & 255;
            set[4] = hi & 255;
            hi = hi >> 8;
            set[3] = hi & 255;
            hi = hi >> 8;
            set[2] = hi & 255;
            hi = hi >> 8;
            set[1] = hi & 255;
            buf.push(set);
        } else throw new Error(`${common.decodeErrPrefix} encountered BigInt larger than allowable range`);
    }
}
encodeUint.encodedSize = function encodedSize(token) {
    return encodeUintValue.encodedSize(token.value);
};
encodeUintValue.encodedSize = function encodedSize(uint) {
    if (uint < uintBoundaries[0]) return 1;
    if (uint < uintBoundaries[1]) return 2;
    if (uint < uintBoundaries[2]) return 3;
    if (uint < uintBoundaries[3]) return 5;
    return 9;
};
encodeUint.compareTokens = function compareTokens(tok1, tok2) {
    return tok1.value < tok2.value ? -1 : tok1.value > tok2.value ? 1 : 0;
};
exports.decodeUint16 = decodeUint16;
exports.decodeUint32 = decodeUint32;
exports.decodeUint64 = decodeUint64;
exports.decodeUint8 = decodeUint8;
exports.encodeUint = encodeUint;
exports.encodeUintValue = encodeUintValue;
exports.readUint16 = readUint16;
exports.readUint32 = readUint32;
exports.readUint64 = readUint64;
exports.readUint8 = readUint8;
exports.uintBoundaries = uintBoundaries;

},{"./token.js":"6kwVw","./common.js":"6SV2V"}],"fYEM6":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var token1 = require('./token.js');
var _0uint = require('./0uint.js');
var common = require('./common.js');
function decodeNegint8(data, pos, _minor, options) {
    return new token1.Token(token1.Type.negint, -1 - _0uint.readUint8(data, pos + 1, options), 2);
}
function decodeNegint16(data, pos, _minor, options) {
    return new token1.Token(token1.Type.negint, -1 - _0uint.readUint16(data, pos + 1, options), 3);
}
function decodeNegint32(data, pos, _minor, options) {
    return new token1.Token(token1.Type.negint, -1 - _0uint.readUint32(data, pos + 1, options), 5);
}
const neg1b = BigInt(-1);
const pos1b = BigInt(1);
function decodeNegint64(data, pos, _minor, options) {
    const int = _0uint.readUint64(data, pos + 1, options);
    if (typeof int !== 'bigint') {
        const value = -1 - int;
        if (value >= Number.MIN_SAFE_INTEGER) return new token1.Token(token1.Type.negint, value, 9);
    }
    if (options.allowBigInt !== true) throw new Error(`${common.decodeErrPrefix} integers outside of the safe integer range are not supported`);
    return new token1.Token(token1.Type.negint, neg1b - BigInt(int), 9);
}
function encodeNegint(buf, token) {
    const negint = token.value;
    const unsigned = typeof negint === 'bigint' ? negint * neg1b - pos1b : negint * -1 - 1;
    _0uint.encodeUintValue(buf, token.type.majorEncoded, unsigned);
}
encodeNegint.encodedSize = function encodedSize(token) {
    const negint = token.value;
    const unsigned = typeof negint === 'bigint' ? negint * neg1b - pos1b : negint * -1 - 1;
    if (unsigned < _0uint.uintBoundaries[0]) return 1;
    if (unsigned < _0uint.uintBoundaries[1]) return 2;
    if (unsigned < _0uint.uintBoundaries[2]) return 3;
    if (unsigned < _0uint.uintBoundaries[3]) return 5;
    return 9;
};
encodeNegint.compareTokens = function compareTokens(tok1, tok2) {
    return tok1.value < tok2.value ? 1 : tok1.value > tok2.value ? -1 : 0;
};
exports.decodeNegint16 = decodeNegint16;
exports.decodeNegint32 = decodeNegint32;
exports.decodeNegint64 = decodeNegint64;
exports.decodeNegint8 = decodeNegint8;
exports.encodeNegint = encodeNegint;

},{"./token.js":"6kwVw","./0uint.js":"9GKB7","./common.js":"6SV2V"}],"4MD8k":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var token1 = require('./token.js');
var common = require('./common.js');
var _0uint = require('./0uint.js');
var byteUtils = require('./byte-utils.js');
function toToken(data, pos, prefix, length) {
    common.assertEnoughData(data, pos, prefix + length);
    const buf = byteUtils.slice(data, pos + prefix, pos + prefix + length);
    return new token1.Token(token1.Type.bytes, buf, prefix + length);
}
function decodeBytesCompact(data, pos, minor, _options) {
    return toToken(data, pos, 1, minor);
}
function decodeBytes8(data, pos, _minor, options) {
    return toToken(data, pos, 2, _0uint.readUint8(data, pos + 1, options));
}
function decodeBytes16(data, pos, _minor, options) {
    return toToken(data, pos, 3, _0uint.readUint16(data, pos + 1, options));
}
function decodeBytes32(data, pos, _minor, options) {
    return toToken(data, pos, 5, _0uint.readUint32(data, pos + 1, options));
}
function decodeBytes64(data, pos, _minor, options) {
    const l = _0uint.readUint64(data, pos + 1, options);
    if (typeof l === 'bigint') throw new Error(`${common.decodeErrPrefix} 64-bit integer bytes lengths not supported`);
    return toToken(data, pos, 9, l);
}
function tokenBytes(token$1) {
    if (token$1.encodedBytes === undefined) token$1.encodedBytes = token$1.type === token1.Type.string ? byteUtils.fromString(token$1.value) : token$1.value;
    return token$1.encodedBytes;
}
function encodeBytes(buf, token) {
    const bytes = tokenBytes(token);
    _0uint.encodeUintValue(buf, token.type.majorEncoded, bytes.length);
    buf.push(bytes);
}
encodeBytes.encodedSize = function encodedSize(token) {
    const bytes = tokenBytes(token);
    return _0uint.encodeUintValue.encodedSize(bytes.length) + bytes.length;
};
encodeBytes.compareTokens = function compareTokens(tok1, tok2) {
    return compareBytes(tokenBytes(tok1), tokenBytes(tok2));
};
function compareBytes(b1, b2) {
    return b1.length < b2.length ? -1 : b1.length > b2.length ? 1 : byteUtils.compare(b1, b2);
}
exports.compareBytes = compareBytes;
exports.decodeBytes16 = decodeBytes16;
exports.decodeBytes32 = decodeBytes32;
exports.decodeBytes64 = decodeBytes64;
exports.decodeBytes8 = decodeBytes8;
exports.decodeBytesCompact = decodeBytesCompact;
exports.encodeBytes = encodeBytes;

},{"./token.js":"6kwVw","./common.js":"6SV2V","./0uint.js":"9GKB7","./byte-utils.js":"akZGX"}],"20od8":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var token = require('./token.js');
var common = require('./common.js');
var _0uint = require('./0uint.js');
var _2bytes = require('./2bytes.js');
var byteUtils = require('./byte-utils.js');
function toToken(data, pos, prefix, length) {
    const totLength = prefix + length;
    common.assertEnoughData(data, pos, totLength);
    return new token.Token(token.Type.string, byteUtils.toString(data, pos + prefix, pos + totLength), totLength);
}
function decodeStringCompact(data, pos, minor, _options) {
    return toToken(data, pos, 1, minor);
}
function decodeString8(data, pos, _minor, options) {
    return toToken(data, pos, 2, _0uint.readUint8(data, pos + 1, options));
}
function decodeString16(data, pos, _minor, options) {
    return toToken(data, pos, 3, _0uint.readUint16(data, pos + 1, options));
}
function decodeString32(data, pos, _minor, options) {
    return toToken(data, pos, 5, _0uint.readUint32(data, pos + 1, options));
}
function decodeString64(data, pos, _minor, options) {
    const l = _0uint.readUint64(data, pos + 1, options);
    if (typeof l === 'bigint') throw new Error(`${common.decodeErrPrefix} 64-bit integer string lengths not supported`);
    return toToken(data, pos, 9, l);
}
const encodeString = _2bytes.encodeBytes;
exports.decodeString16 = decodeString16;
exports.decodeString32 = decodeString32;
exports.decodeString64 = decodeString64;
exports.decodeString8 = decodeString8;
exports.decodeStringCompact = decodeStringCompact;
exports.encodeString = encodeString;

},{"./token.js":"6kwVw","./common.js":"6SV2V","./0uint.js":"9GKB7","./2bytes.js":"4MD8k","./byte-utils.js":"akZGX"}],"7uu23":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var token = require('./token.js');
var _0uint = require('./0uint.js');
var common = require('./common.js');
function toToken(_data, _pos, prefix, length) {
    return new token.Token(token.Type.array, length, prefix);
}
function decodeArrayCompact(data, pos, minor, _options) {
    return toToken(data, pos, 1, minor);
}
function decodeArray8(data, pos, _minor, options) {
    return toToken(data, pos, 2, _0uint.readUint8(data, pos + 1, options));
}
function decodeArray16(data, pos, _minor, options) {
    return toToken(data, pos, 3, _0uint.readUint16(data, pos + 1, options));
}
function decodeArray32(data, pos, _minor, options) {
    return toToken(data, pos, 5, _0uint.readUint32(data, pos + 1, options));
}
function decodeArray64(data, pos, _minor, options) {
    const l = _0uint.readUint64(data, pos + 1, options);
    if (typeof l === 'bigint') throw new Error(`${common.decodeErrPrefix} 64-bit integer array lengths not supported`);
    return toToken(data, pos, 9, l);
}
function decodeArrayIndefinite(data, pos, _minor, options) {
    if (options.allowIndefinite === false) throw new Error(`${common.decodeErrPrefix} indefinite length items not allowed`);
    return toToken(data, pos, 1, Infinity);
}
function encodeArray(buf, token$1) {
    _0uint.encodeUintValue(buf, token.Type.array.majorEncoded, token$1.value);
}
encodeArray.compareTokens = _0uint.encodeUint.compareTokens;
exports.decodeArray16 = decodeArray16;
exports.decodeArray32 = decodeArray32;
exports.decodeArray64 = decodeArray64;
exports.decodeArray8 = decodeArray8;
exports.decodeArrayCompact = decodeArrayCompact;
exports.decodeArrayIndefinite = decodeArrayIndefinite;
exports.encodeArray = encodeArray;

},{"./token.js":"6kwVw","./0uint.js":"9GKB7","./common.js":"6SV2V"}],"59MxO":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var token = require('./token.js');
var _0uint = require('./0uint.js');
var common = require('./common.js');
function toToken(_data, _pos, prefix, length) {
    return new token.Token(token.Type.map, length, prefix);
}
function decodeMapCompact(data, pos, minor, _options) {
    return toToken(data, pos, 1, minor);
}
function decodeMap8(data, pos, _minor, options) {
    return toToken(data, pos, 2, _0uint.readUint8(data, pos + 1, options));
}
function decodeMap16(data, pos, _minor, options) {
    return toToken(data, pos, 3, _0uint.readUint16(data, pos + 1, options));
}
function decodeMap32(data, pos, _minor, options) {
    return toToken(data, pos, 5, _0uint.readUint32(data, pos + 1, options));
}
function decodeMap64(data, pos, _minor, options) {
    const l = _0uint.readUint64(data, pos + 1, options);
    if (typeof l === 'bigint') throw new Error(`${common.decodeErrPrefix} 64-bit integer map lengths not supported`);
    return toToken(data, pos, 9, l);
}
function decodeMapIndefinite(data, pos, _minor, options) {
    if (options.allowIndefinite === false) throw new Error(`${common.decodeErrPrefix} indefinite length items not allowed`);
    return toToken(data, pos, 1, Infinity);
}
function encodeMap(buf, token$1) {
    _0uint.encodeUintValue(buf, token.Type.map.majorEncoded, token$1.value);
}
encodeMap.compareTokens = _0uint.encodeUint.compareTokens;
exports.decodeMap16 = decodeMap16;
exports.decodeMap32 = decodeMap32;
exports.decodeMap64 = decodeMap64;
exports.decodeMap8 = decodeMap8;
exports.decodeMapCompact = decodeMapCompact;
exports.decodeMapIndefinite = decodeMapIndefinite;
exports.encodeMap = encodeMap;

},{"./token.js":"6kwVw","./0uint.js":"9GKB7","./common.js":"6SV2V"}],"dlZcd":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var token = require('./token.js');
var _0uint = require('./0uint.js');
function decodeTagCompact(_data, _pos, minor, _options) {
    return new token.Token(token.Type.tag, minor, 1);
}
function decodeTag8(data, pos, _minor, options) {
    return new token.Token(token.Type.tag, _0uint.readUint8(data, pos + 1, options), 2);
}
function decodeTag16(data, pos, _minor, options) {
    return new token.Token(token.Type.tag, _0uint.readUint16(data, pos + 1, options), 3);
}
function decodeTag32(data, pos, _minor, options) {
    return new token.Token(token.Type.tag, _0uint.readUint32(data, pos + 1, options), 5);
}
function decodeTag64(data, pos, _minor, options) {
    return new token.Token(token.Type.tag, _0uint.readUint64(data, pos + 1, options), 9);
}
function encodeTag(buf, token$1) {
    _0uint.encodeUintValue(buf, token.Type.tag.majorEncoded, token$1.value);
}
encodeTag.compareTokens = _0uint.encodeUint.compareTokens;
exports.decodeTag16 = decodeTag16;
exports.decodeTag32 = decodeTag32;
exports.decodeTag64 = decodeTag64;
exports.decodeTag8 = decodeTag8;
exports.decodeTagCompact = decodeTagCompact;
exports.encodeTag = encodeTag;

},{"./token.js":"6kwVw","./0uint.js":"9GKB7"}],"2cl9I":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var token1 = require('./token.js');
var common = require('./common.js');
var _0uint = require('./0uint.js');
const MINOR_FALSE = 20;
const MINOR_TRUE = 21;
const MINOR_NULL = 22;
const MINOR_UNDEFINED = 23;
function decodeUndefined(_data, _pos, _minor, options) {
    if (options.allowUndefined === false) throw new Error(`${common.decodeErrPrefix} undefined values are not supported`);
    return new token1.Token(token1.Type.undefined, undefined, 1);
}
function decodeBreak(_data, _pos, _minor, options) {
    if (options.allowIndefinite === false) throw new Error(`${common.decodeErrPrefix} indefinite length items not allowed`);
    return new token1.Token(token1.Type.break, undefined, 1);
}
function createToken(value, bytes, options) {
    if (options) {
        if (options.allowNaN === false && Number.isNaN(value)) throw new Error(`${common.decodeErrPrefix} NaN values are not supported`);
        if (options.allowInfinity === false && (value === Infinity || value === -Infinity)) throw new Error(`${common.decodeErrPrefix} Infinity values are not supported`);
    }
    return new token1.Token(token1.Type.float, value, bytes);
}
function decodeFloat16(data, pos, _minor, options) {
    return createToken(readFloat16(data, pos + 1), 3, options);
}
function decodeFloat32(data, pos, _minor, options) {
    return createToken(readFloat32(data, pos + 1), 5, options);
}
function decodeFloat64(data, pos, _minor, options) {
    return createToken(readFloat64(data, pos + 1), 9, options);
}
function encodeFloat(buf, token$1, options) {
    const float = token$1.value;
    if (float === false) buf.push([
        token1.Type.float.majorEncoded | MINOR_FALSE
    ]);
    else if (float === true) buf.push([
        token1.Type.float.majorEncoded | MINOR_TRUE
    ]);
    else if (float === null) buf.push([
        token1.Type.float.majorEncoded | MINOR_NULL
    ]);
    else if (float === undefined) buf.push([
        token1.Type.float.majorEncoded | MINOR_UNDEFINED
    ]);
    else {
        let decoded;
        let success = false;
        if (!options || options.float64 !== true) {
            encodeFloat16(float);
            decoded = readFloat16(ui8a1, 1);
            if (float === decoded || Number.isNaN(float)) {
                ui8a1[0] = 249;
                buf.push(ui8a1.slice(0, 3));
                success = true;
            } else {
                encodeFloat32(float);
                decoded = readFloat32(ui8a1, 1);
                if (float === decoded) {
                    ui8a1[0] = 250;
                    buf.push(ui8a1.slice(0, 5));
                    success = true;
                }
            }
        }
        if (!success) {
            encodeFloat64(float);
            decoded = readFloat64(ui8a1, 1);
            ui8a1[0] = 251;
            buf.push(ui8a1.slice(0, 9));
        }
    }
}
encodeFloat.encodedSize = function encodedSize(token, options) {
    const float = token.value;
    if (float === false || float === true || float === null || float === undefined) return 1;
    let decoded;
    if (!options || options.float64 !== true) {
        encodeFloat16(float);
        decoded = readFloat16(ui8a1, 1);
        if (float === decoded || Number.isNaN(float)) return 3;
        encodeFloat32(float);
        decoded = readFloat32(ui8a1, 1);
        if (float === decoded) return 5;
    }
    return 9;
};
const buffer = new ArrayBuffer(9);
const dataView = new DataView(buffer, 1);
const ui8a1 = new Uint8Array(buffer, 0);
function encodeFloat16(inp) {
    if (inp === Infinity) dataView.setUint16(0, 31744, false);
    else if (inp === -Infinity) dataView.setUint16(0, 64512, false);
    else if (Number.isNaN(inp)) dataView.setUint16(0, 32256, false);
    else {
        dataView.setFloat32(0, inp);
        const valu32 = dataView.getUint32(0);
        const exponent = (valu32 & 2139095040) >> 23;
        const mantissa = valu32 & 8388607;
        if (exponent === 255) dataView.setUint16(0, 31744, false);
        else if (exponent === 0) dataView.setUint16(0, (inp & 2147483648) >> 16 | mantissa >> 13, false);
        else {
            const logicalExponent = exponent - 127;
            if (logicalExponent < -24) dataView.setUint16(0, 0);
            else if (logicalExponent < -14) dataView.setUint16(0, (valu32 & 2147483648) >> 16 | 1 << 24 + logicalExponent, false);
            else dataView.setUint16(0, (valu32 & 2147483648) >> 16 | logicalExponent + 15 << 10 | mantissa >> 13, false);
        }
    }
}
function readFloat16(ui8a, pos) {
    if (ui8a.length - pos < 2) throw new Error(`${common.decodeErrPrefix} not enough data for float16`);
    const half = (ui8a[pos] << 8) + ui8a[pos + 1];
    if (half === 31744) return Infinity;
    if (half === 64512) return -Infinity;
    if (half === 32256) return NaN;
    const exp = half >> 10 & 31;
    const mant = half & 1023;
    let val;
    if (exp === 0) val = mant * 2 ** -24;
    else if (exp !== 31) val = (mant + 1024) * 2 ** (exp - 25);
    else val = mant === 0 ? Infinity : NaN;
    return half & 32768 ? -val : val;
}
function encodeFloat32(inp) {
    dataView.setFloat32(0, inp, false);
}
function readFloat32(ui8a, pos) {
    if (ui8a.length - pos < 4) throw new Error(`${common.decodeErrPrefix} not enough data for float32`);
    const offset = (ui8a.byteOffset || 0) + pos;
    return new DataView(ui8a.buffer, offset, 4).getFloat32(0, false);
}
function encodeFloat64(inp) {
    dataView.setFloat64(0, inp, false);
}
function readFloat64(ui8a, pos) {
    if (ui8a.length - pos < 8) throw new Error(`${common.decodeErrPrefix} not enough data for float64`);
    const offset = (ui8a.byteOffset || 0) + pos;
    return new DataView(ui8a.buffer, offset, 8).getFloat64(0, false);
}
encodeFloat.compareTokens = _0uint.encodeUint.compareTokens;
exports.decodeBreak = decodeBreak;
exports.decodeFloat16 = decodeFloat16;
exports.decodeFloat32 = decodeFloat32;
exports.decodeFloat64 = decodeFloat64;
exports.decodeUndefined = decodeUndefined;
exports.encodeFloat = encodeFloat;

},{"./token.js":"6kwVw","./common.js":"6SV2V","./0uint.js":"9GKB7"}],"gB1N0":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var common = require('./common.js');
var token1 = require('./token.js');
var jump = require('./jump.js');
const defaultDecodeOptions = {
    strict: false,
    allowIndefinite: true,
    allowUndefined: true,
    allowBigInt: true
};
class Tokeniser {
    constructor(data1, options1 = {
    }){
        this.pos = 0;
        this.data = data1;
        this.options = options1;
    }
    done() {
        return this.pos >= this.data.length;
    }
    next() {
        const byt = this.data[this.pos];
        let token = jump.quick[byt];
        if (token === undefined) {
            const decoder = jump.jump[byt];
            if (!decoder) throw new Error(`${common.decodeErrPrefix} no decoder for major type ${byt >>> 5} (byte 0x${byt.toString(16).padStart(2, '0')})`);
            const minor = byt & 31;
            token = decoder(this.data, this.pos, minor, this.options);
        }
        this.pos += token.encodedLength;
        return token;
    }
}
const DONE = Symbol.for('DONE');
const BREAK = Symbol.for('BREAK');
function tokenToArray(token, tokeniser, options) {
    const arr = [];
    for(let i = 0; i < token.value; i++){
        const value = tokensToObject(tokeniser, options);
        if (value === BREAK) {
            if (token.value === Infinity) break;
            throw new Error(`${common.decodeErrPrefix} got unexpected break to lengthed array`);
        }
        if (value === DONE) throw new Error(`${common.decodeErrPrefix} found array but not enough entries (got ${i}, expected ${token.value})`);
        arr[i] = value;
    }
    return arr;
}
function tokenToMap(token, tokeniser, options) {
    const useMaps = options.useMaps === true;
    const obj = useMaps ? undefined : {
    };
    const m = useMaps ? new Map() : undefined;
    for(let i = 0; i < token.value; i++){
        const key = tokensToObject(tokeniser, options);
        if (key === BREAK) {
            if (token.value === Infinity) break;
            throw new Error(`${common.decodeErrPrefix} got unexpected break to lengthed map`);
        }
        if (key === DONE) throw new Error(`${common.decodeErrPrefix} found map but not enough entries (got ${i} [no key], expected ${token.value})`);
        if (useMaps !== true && typeof key !== 'string') throw new Error(`${common.decodeErrPrefix} non-string keys not supported (got ${typeof key})`);
        const value = tokensToObject(tokeniser, options);
        if (value === DONE) throw new Error(`${common.decodeErrPrefix} found map but not enough entries (got ${i} [no value], expected ${token.value})`);
        if (useMaps) m.set(key, value);
        else obj[key] = value;
    }
    return useMaps ? m : obj;
}
function tokensToObject(tokeniser, options) {
    if (tokeniser.done()) return DONE;
    const token$1 = tokeniser.next();
    if (token$1.type === token1.Type.break) return BREAK;
    if (token$1.type.terminal) return token$1.value;
    if (token$1.type === token1.Type.array) return tokenToArray(token$1, tokeniser, options);
    if (token$1.type === token1.Type.map) return tokenToMap(token$1, tokeniser, options);
    if (token$1.type === token1.Type.tag) {
        if (options.tags && typeof options.tags[token$1.value] === 'function') {
            const tagged = tokensToObject(tokeniser, options);
            return options.tags[token$1.value](tagged);
        }
        throw new Error(`${common.decodeErrPrefix} tag not supported (${token$1.value})`);
    }
    throw new Error('unsupported');
}
function decode(data, options) {
    if (!(data instanceof Uint8Array)) throw new Error(`${common.decodeErrPrefix} data to decode must be a Uint8Array`);
    options = Object.assign({
    }, defaultDecodeOptions, options);
    const tokeniser = options.tokenizer || new Tokeniser(data, options);
    const decoded = tokensToObject(tokeniser, options);
    if (decoded === DONE) throw new Error(`${common.decodeErrPrefix} did not find any content to decode`);
    if (decoded === BREAK) throw new Error(`${common.decodeErrPrefix} got unexpected break`);
    if (!tokeniser.done()) throw new Error(`${common.decodeErrPrefix} too many terminals, data makes no sense`);
    return decoded;
}
exports.Tokeniser = Tokeniser;
exports.decode = decode;
exports.tokensToObject = tokensToObject;

},{"./common.js":"6SV2V","./token.js":"6kwVw","./jump.js":"boLQN"}],"7Cndu":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var hasher = require('./hasher.js');
var bytes = require('../bytes.js');
const identity = hasher.from({
    name: 'identity',
    code: 0,
    encode: (input)=>bytes.coerce(input)
});
exports.identity = identity;

},{"./hasher.js":"cjNRZ","../bytes.js":"7cZyj"}],"cjNRZ":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var digest = require('./digest.js');
const from = ({ name , code , encode  })=>new Hasher(name, code, encode)
;
class Hasher {
    constructor(name, code, encode){
        this.name = name;
        this.code = code;
        this.encode = encode;
    }
    async digest(input) {
        if (input instanceof Uint8Array) {
            const digest$1 = await this.encode(input);
            return digest.create(this.code, digest$1);
        } else throw Error('Unknown type, must be binary type');
    }
}
exports.Hasher = Hasher;
exports.from = from;

},{"./digest.js":"fkA58"}],"7w1HC":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var identity = require('./bases/identity.js');
var base2 = require('./bases/base2.js');
var base8 = require('./bases/base8.js');
var base10 = require('./bases/base10.js');
var base16 = require('./bases/base16.js');
var base32 = require('./bases/base32.js');
var base36 = require('./bases/base36.js');
var base58 = require('./bases/base58.js');
var base64 = require('./bases/base64.js');
var sha2 = require('./hashes/sha2.js');
var identity$1 = require('./hashes/identity.js');
var raw = require('./codecs/raw.js');
var json = require('./codecs/json.js');
require('./index.js');
var cid = require('./cid.js');
var hasher = require('./hashes/hasher.js');
var digest = require('./hashes/digest.js');
var varint = require('./varint.js');
var bytes = require('./bytes.js');
const bases = {
    ...identity,
    ...base2,
    ...base8,
    ...base10,
    ...base16,
    ...base32,
    ...base36,
    ...base58,
    ...base64
};
const hashes = {
    ...sha2,
    ...identity$1
};
const codecs = {
    raw,
    json
};
exports.CID = cid.CID;
exports.hasher = hasher;
exports.digest = digest;
exports.varint = varint;
exports.bytes = bytes;
exports.bases = bases;
exports.codecs = codecs;
exports.hashes = hashes;

},{"./bases/identity.js":"3EZv7","./bases/base2.js":"h3Ahx","./bases/base8.js":"66LtK","./bases/base10.js":"dEg1P","./bases/base16.js":"kDDoG","./bases/base32.js":"63xDB","./bases/base36.js":"iaopc","./bases/base58.js":"6Rnqi","./bases/base64.js":"7Lo1j","./hashes/sha2.js":"i8JnP","./hashes/identity.js":"7Cndu","./codecs/raw.js":"dkcyY","./codecs/json.js":"jwb79","./index.js":"8T5ng","./cid.js":"fJJnW","./hashes/hasher.js":"cjNRZ","./hashes/digest.js":"fkA58","./varint.js":"5Q7FL","./bytes.js":"7cZyj"}],"3EZv7":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var base = require('./base.js');
var bytes = require('../bytes.js');
const identity = base.from({
    prefix: '\0',
    name: 'identity',
    encode: (buf)=>bytes.toString(buf)
    ,
    decode: (str)=>bytes.fromString(str)
});
exports.identity = identity;

},{"./base.js":"aX8fr","../bytes.js":"7cZyj"}],"h3Ahx":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var base = require('./base.js');
const base2 = base.rfc4648({
    prefix: '0',
    name: 'base2',
    alphabet: '01',
    bitsPerChar: 1
});
exports.base2 = base2;

},{"./base.js":"aX8fr"}],"66LtK":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var base = require('./base.js');
const base8 = base.rfc4648({
    prefix: '7',
    name: 'base8',
    alphabet: '01234567',
    bitsPerChar: 3
});
exports.base8 = base8;

},{"./base.js":"aX8fr"}],"dEg1P":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var base = require('./base.js');
const base10 = base.baseX({
    prefix: '9',
    name: 'base10',
    alphabet: '0123456789'
});
exports.base10 = base10;

},{"./base.js":"aX8fr"}],"kDDoG":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var base = require('./base.js');
const base16 = base.rfc4648({
    prefix: 'f',
    name: 'base16',
    alphabet: '0123456789abcdef',
    bitsPerChar: 4
});
const base16upper = base.rfc4648({
    prefix: 'F',
    name: 'base16upper',
    alphabet: '0123456789ABCDEF',
    bitsPerChar: 4
});
exports.base16 = base16;
exports.base16upper = base16upper;

},{"./base.js":"aX8fr"}],"iaopc":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var base = require('./base.js');
const base36 = base.baseX({
    prefix: 'k',
    name: 'base36',
    alphabet: '0123456789abcdefghijklmnopqrstuvwxyz'
});
const base36upper = base.baseX({
    prefix: 'K',
    name: 'base36upper',
    alphabet: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
});
exports.base36 = base36;
exports.base36upper = base36upper;

},{"./base.js":"aX8fr"}],"7Lo1j":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var base = require('./base.js');
const base64 = base.rfc4648({
    prefix: 'm',
    name: 'base64',
    alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
    bitsPerChar: 6
});
const base64pad = base.rfc4648({
    prefix: 'M',
    name: 'base64pad',
    alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
    bitsPerChar: 6
});
const base64url = base.rfc4648({
    prefix: 'u',
    name: 'base64url',
    alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_',
    bitsPerChar: 6
});
const base64urlpad = base.rfc4648({
    prefix: 'U',
    name: 'base64urlpad',
    alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_=',
    bitsPerChar: 6
});
exports.base64 = base64;
exports.base64pad = base64pad;
exports.base64url = base64url;
exports.base64urlpad = base64urlpad;

},{"./base.js":"aX8fr"}],"i8JnP":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var hasher = require('./hasher.js');
const sha = (name)=>async (data)=>new Uint8Array(await crypto.subtle.digest(name, data))
;
const sha256 = hasher.from({
    name: 'sha2-256',
    code: 18,
    encode: sha('SHA-256')
});
const sha512 = hasher.from({
    name: 'sha2-512',
    code: 19,
    encode: sha('SHA-512')
});
exports.sha256 = sha256;
exports.sha512 = sha512;

},{"./hasher.js":"cjNRZ"}],"dkcyY":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var bytes = require('../bytes.js');
const name = 'raw';
const code = 85;
const encode = (node)=>bytes.coerce(node)
;
const decode = (data)=>bytes.coerce(data)
;
exports.code = code;
exports.decode = decode;
exports.encode = encode;
exports.name = name;

},{"../bytes.js":"7cZyj"}],"jwb79":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
const textEncoder = new TextEncoder();
const textDecoder = new TextDecoder();
const name = 'json';
const code = 512;
const encode = (node)=>textEncoder.encode(JSON.stringify(node))
;
const decode = (data)=>JSON.parse(textDecoder.decode(data))
;
exports.code = code;
exports.decode = decode;
exports.encode = encode;
exports.name = name;

},{}],"8T5ng":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('./cid.js');
var varint = require('./varint.js');
var bytes = require('./bytes.js');
var hasher = require('./hashes/hasher.js');
var digest = require('./hashes/digest.js');
exports.CID = cid.CID;
exports.varint = varint;
exports.bytes = bytes;
exports.hasher = hasher;
exports.digest = digest;

},{"./cid.js":"fJJnW","./varint.js":"5Q7FL","./bytes.js":"7cZyj","./hashes/hasher.js":"cjNRZ","./hashes/digest.js":"fkA58"}],"7SacM":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
function initAssets() {
}
exports.initAssets = initAssets;

},{}],"itpk8":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
class NotInitializedError extends Error {
    constructor(message = 'not initialized'){
        super(message);
        this.name = 'NotInitializedError';
        this.code = NotInitializedError.code;
    }
}
NotInitializedError.code = 'ERR_NOT_INITIALIZED';
class AlreadyInitializingError extends Error {
    constructor(message1 = 'cannot initialize an initializing node'){
        super(message1);
        this.name = 'AlreadyInitializingError';
        this.code = AlreadyInitializedError.code;
    }
}
AlreadyInitializingError.code = 'ERR_ALREADY_INITIALIZING';
class AlreadyInitializedError extends Error {
    constructor(message2 = 'cannot re-initialize an initialized node'){
        super(message2);
        this.name = 'AlreadyInitializedError';
        this.code = AlreadyInitializedError.code;
    }
}
AlreadyInitializedError.code = 'ERR_ALREADY_INITIALIZED';
class NotStartedError extends Error {
    constructor(message3 = 'not started'){
        super(message3);
        this.name = 'NotStartedError';
        this.code = NotStartedError.code;
    }
}
NotStartedError.code = 'ERR_NOT_STARTED';
class AlreadyStartingError extends Error {
    constructor(message4 = 'cannot start, already startin'){
        super(message4);
        this.name = 'AlreadyStartingError';
        this.code = AlreadyStartingError.code;
    }
}
AlreadyStartingError.code = 'ERR_ALREADY_STARTING';
class AlreadyStartedError extends Error {
    constructor(message5 = 'cannot start, already started'){
        super(message5);
        this.name = 'AlreadyStartedError';
        this.code = AlreadyStartedError.code;
    }
}
AlreadyStartedError.code = 'ERR_ALREADY_STARTED';
class NotEnabledError extends Error {
    constructor(message6 = 'not enabled'){
        super(message6);
        this.name = 'NotEnabledError';
        this.code = NotEnabledError.code;
    }
}
NotEnabledError.code = 'ERR_NOT_ENABLED';
exports.AlreadyInitializedError = AlreadyInitializedError;
exports.AlreadyInitializingError = AlreadyInitializingError;
exports.AlreadyStartedError = AlreadyStartedError;
exports.AlreadyStartingError = AlreadyStartingError;
exports.NotEnabledError = NotEnabledError;
exports.NotInitializedError = NotInitializedError;
exports.NotStartedError = NotStartedError;

},{}],"lo45E":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var bases = require('./util/bases.js');
function fromString(string, encoding = 'utf8') {
    const base = bases[encoding];
    if (!base) throw new Error(`Unsupported encoding "${encoding}"`);
    return base.decoder.decode(`${base.prefix}${string}`);
}
exports.fromString = fromString;

},{"./util/bases.js":"cV2Md"}],"cV2Md":[function(require,module,exports) {
'use strict';
var basics = require('multiformats/basics');
function createCodec(name, prefix, encode, decode) {
    return {
        name,
        prefix,
        encoder: {
            name,
            prefix,
            encode
        },
        decoder: {
            decode
        }
    };
}
const string1 = createCodec('utf8', 'u', (buf)=>{
    const decoder = new TextDecoder('utf8');
    return 'u' + decoder.decode(buf);
}, (str)=>{
    const encoder = new TextEncoder();
    return encoder.encode(str.substring(1));
});
const ascii = createCodec('ascii', 'a', (buf)=>{
    let string = 'a';
    for(let i = 0; i < buf.length; i++)string += String.fromCharCode(buf[i]);
    return string;
}, (str)=>{
    str = str.substring(1);
    const buf = new Uint8Array(str.length);
    for(let i = 0; i < str.length; i++)buf[i] = str.charCodeAt(i);
    return buf;
});
const BASES = {
    utf8: string1,
    'utf-8': string1,
    hex: basics.bases.base16,
    latin1: ascii,
    ascii: ascii,
    binary: ascii,
    ...basics.bases
};
module.exports = BASES;

},{"multiformats/basics":"7w1HC"}],"2jhMT":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var service = require('../utils/service.js');
function createStart({ network , preload , peerId , keychain , repo , ipns , mfsPreload , print , options  }) {
    const start = async ()=>{
        const { libp2p  } = await service.Service.start(network, {
            peerId,
            repo,
            print,
            options
        });
        await Promise.all([
            ipns.startOnline({
                keychain,
                libp2p,
                peerId,
                repo
            }),
            preload.start(),
            mfsPreload.start()
        ]);
    };
    return start;
}
exports.createStart = createStart;

},{"../utils/service.js":"e1v7I"}],"e1v7I":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var errors = require('../errors.js');
var utils = require('../utils.js');
class Service {
    static create({ start , stop  }) {
        return new Service(start, stop);
    }
    static async start(service, options) {
        const { state , activate  } = service;
        switch(state.status){
            case 'stopped':
                try {
                    const promise = activate(options);
                    service.state = {
                        status: 'starting',
                        ready: promise
                    };
                    const result = await promise;
                    service.state = {
                        status: 'started',
                        value: result
                    };
                    return result;
                } catch (error) {
                    service.state = {
                        status: 'stopped'
                    };
                    throw error;
                }
            case 'starting':
                throw new errors.AlreadyStartingError();
            case 'started':
                throw new errors.AlreadyStartedError();
            case 'stopping':
                await state.ready;
                return await Service.start(service, options);
            default:
                return Service.panic(service);
        }
    }
    static async stop(service1) {
        const { state , deactivate  } = service1;
        switch(state.status){
            case 'stopped':
                break;
            case 'starting':
                try {
                    await state.ready;
                } catch (_) {
                }
                return await Service.stop(service1);
            case 'stopping':
                return await state.ready;
            case 'started':
                if (deactivate) await deactivate(state.value);
                service1.state = {
                    status: 'stopped'
                };
                break;
            default:
                Service.panic(state);
        }
    }
    static try({ state  }) {
        switch(state.status){
            case 'started':
                return state.value;
            default:
                return null;
        }
    }
    static async use({ state: state1  }, options1) {
        switch(state1.status){
            case 'started':
                return state1.value;
            case 'starting':
                return await utils.withTimeout(state1.ready, options1);
            default:
                throw new errors.NotStartedError();
        }
    }
    static panic({ state: state2  }) {
        const status = JSON.stringify({
            status: state2.status
        });
        throw RangeError(`Service in invalid state ${status}, should never happen if you see this please report a bug`);
    }
    constructor(activate, deactivate){
        this.activate = activate;
        this.deactivate = deactivate;
        this.state = {
            status: 'stopped'
        };
    }
    async use(options2) {
        return await Service.use(this, options2);
    }
    try() {
        return Service.try(this);
    }
}
exports.Service = Service;

},{"../errors.js":"itpk8","../utils.js":"4LLx8"}],"4LLx8":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var isIpfs = require('is-ipfs');
var cid1 = require('multiformats/cid');
var key1 = require('interface-datastore/key');
var errCode = require('err-code');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
var toCidAndPath = require('ipfs-core-utils/to-cid-and-path');
var dagPB = require('@ipld/dag-pb');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n['default'] = e;
    return Object.freeze(n);
}
var isIpfs__default = /*#__PURE__*/ _interopDefaultLegacy(isIpfs);
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
var dagPB__namespace = /*#__PURE__*/ _interopNamespace(dagPB);
const ERR_BAD_PATH = 'ERR_BAD_PATH';
const OFFLINE_ERROR = 'This command must be run in online mode. Try running \'ipfs daemon\' first.';
const MFS_ROOT_KEY = new key1.Key('/local/filesroot');
const MFS_MAX_CHUNK_SIZE = 262144;
const MFS_MAX_LINKS = 174;
const normalizePath = (pathStr)=>{
    const cid$1 = cid1.CID.asCID(pathStr);
    if (cid$1) return `/ipfs/${pathStr}`;
    const str = pathStr.toString();
    try {
        return `/ipfs/${cid1.CID.parse(str)}`;
    } catch  {
    }
    if (isIpfs__default['default'].path(str)) return str;
    else throw errCode__default['default'](new Error(`invalid path: ${pathStr}`), ERR_BAD_PATH);
};
const normalizeCidPath = (path)=>{
    if (path instanceof Uint8Array) return cid1.CID.decode(path).toString();
    path = path.toString();
    if (path.indexOf('/ipfs/') === 0) path = path.substring(6);
    if (path.charAt(path.length - 1) === '/') path = path.substring(0, path.length - 1);
    return path;
};
const resolvePath = async function(repo, codecs, ipfsPath, options = {
}) {
    const { cid: cid$1 , path  } = toCidAndPath.toCidAndPath(ipfsPath);
    if (path) options.path = path;
    let lastCid = cid$1;
    let lastRemainderPath = options.path || '';
    if (lastRemainderPath.startsWith('/')) lastRemainderPath = lastRemainderPath.substring(1);
    if (options.path) try {
        for await (const { value , remainderPath  } of resolve(cid$1, options.path, codecs, repo, {
            signal: options.signal
        })){
            if (!cid1.CID.asCID(value)) break;
            lastRemainderPath = remainderPath;
            lastCid = value;
        }
    } catch (err) {
        if (err.message.startsWith('Object has no property')) {
            err.message = `no link named "${lastRemainderPath.split('/')[0]}" under ${lastCid}`;
            err.code = 'ERR_NO_LINK';
        }
        throw err;
    }
    return {
        cid: lastCid,
        remainderPath: lastRemainderPath || ''
    };
};
const mapFile = (file)=>{
    if (file.type !== 'file' && file.type !== 'directory' && file.type !== 'raw') throw new Error(`Unknown node type '${file.type}'`);
    const output = {
        cid: file.cid,
        path: file.path,
        name: file.name,
        size: file.size,
        type: 'file'
    };
    if (file.type === 'directory') output.type = 'dir';
    if (file.type === 'file') output.size = file.unixfs.fileSize();
    if (file.type === 'file' || file.type === 'directory') {
        output.mode = file.unixfs.mode;
        if (file.unixfs.mtime !== undefined) output.mtime = file.unixfs.mtime;
    }
    return output;
};
const withTimeout = withTimeoutOption.withTimeoutOption(async (promise, _options)=>await promise
);
const resolve = async function*(cid$1, path, codecs, repo, options) {
    const load = async (cid)=>{
        const codec = await codecs.getCodec(cid.code);
        const block = await repo.blocks.get(cid, options);
        return codec.decode(block);
    };
    const parts = path.split('/').filter(Boolean);
    let value = await load(cid$1);
    let lastCid = cid$1;
    if (!parts.length) yield {
        value,
        remainderPath: ''
    };
    while(parts.length){
        const key = parts.shift();
        if (!key) throw errCode__default['default'](new Error(`Could not resolve path "${path}"`), 'ERR_INVALID_PATH');
        if (cid$1.code === dagPB__namespace.code && Array.isArray(value.Links)) {
            const link = value.Links.find((l)=>l.Name === key
            );
            if (link) {
                yield {
                    value: link.Hash,
                    remainderPath: parts.join('/')
                };
                value = await load(link.Hash);
                lastCid = link.Hash;
                continue;
            }
        }
        if (Object.prototype.hasOwnProperty.call(value, key)) {
            value = value[key];
            yield {
                value,
                remainderPath: parts.join('/')
            };
        } else throw errCode__default['default'](new Error(`no link named "${key}" under ${lastCid}`), 'ERR_NO_LINK');
        if (cid1.CID.asCID(value)) {
            lastCid = value;
            value = await load(value);
        }
    }
};
exports.MFS_MAX_CHUNK_SIZE = MFS_MAX_CHUNK_SIZE;
exports.MFS_MAX_LINKS = MFS_MAX_LINKS;
exports.MFS_ROOT_KEY = MFS_ROOT_KEY;
exports.OFFLINE_ERROR = OFFLINE_ERROR;
exports.mapFile = mapFile;
exports.normalizeCidPath = normalizeCidPath;
exports.normalizePath = normalizePath;
exports.resolve = resolve;
exports.resolvePath = resolvePath;
exports.withTimeout = withTimeout;

},{"is-ipfs":"2Nskw","multiformats/cid":"fJJnW","interface-datastore/key":"ccQWS","err-code":"eQvyh","ipfs-core-utils/with-timeout-option":"5AiVw","ipfs-core-utils/to-cid-and-path":"5zZPz","@ipld/dag-pb":"e9gy2"}],"2Nskw":[function(require,module,exports) {
'use strict';
const { base58btc  } = require('multiformats/bases/base58');
const { base32  } = require('multiformats/bases/base32');
const Digest = require('multiformats/hashes/digest');
const { Multiaddr  } = require('multiaddr');
const mafmt = require('mafmt');
const { CID  } = require('multiformats/cid');
const { URL  } = require('iso-url');
const { toString: uint8ArrayToString  } = require('uint8arrays/to-string');
const pathGatewayPattern = /^https?:\/\/[^/]+\/(ip[fn]s)\/([^/?#]+)/;
const pathPattern = /^\/(ip[fn]s)\/([^/?#]+)/;
const defaultProtocolMatch = 1;
const defaultHashMath = 2;
// CID, libp2p-key or DNSLink
const subdomainGatewayPattern = /^https?:\/\/([^/]+)\.(ip[fn]s)\.[^/?]+/;
const subdomainIdMatch = 1;
const subdomainProtocolMatch = 2;
// Fully qualified domain name (FQDN) that has an explicit .tld suffix
const fqdnWithTld = /^(([a-z0-9]|[a-z0-9][a-z0-9-]*[a-z0-9])\.)+([a-z0-9]|[a-z0-9][a-z0-9-]*[a-z0-9])$/;
/**
 * @param {*} hash
 */ function isMultihash(hash) {
    const formatted = convertToString(hash);
    try {
        Digest.decode(base58btc.decode('z' + formatted));
    } catch  {
        return false;
    }
    return true;
}
/**
 * @param {*} hash
 */ function isBase32EncodedMultibase(hash) {
    try {
        base32.decode(hash);
    } catch  {
        return false;
    }
    return true;
}
/**
 * @param {*} hash
 */ function isCID(hash) {
    try {
        if (typeof hash === 'string') return Boolean(CID.parse(hash));
        if (hash instanceof Uint8Array) return Boolean(CID.decode(hash));
        return Boolean(CID.asCID(hash)) // eslint-disable-line no-new
        ;
    } catch (e) {
        return false;
    }
}
/**
 * @param {*} input
 */ function isMultiaddr(input) {
    if (!input) return false;
    if (Multiaddr.isMultiaddr(input)) return true;
    try {
        new Multiaddr(input) // eslint-disable-line no-new
        ;
        return true;
    } catch (e) {
        return false;
    }
}
/**
 * @param {string | Uint8Array | Multiaddr} input
 */ function isPeerMultiaddr(input) {
    return isMultiaddr(input) && mafmt.P2P.matches(input);
}
/**
 * @param {string | Uint8Array} input
 * @param {RegExp | string} pattern
 * @param {number} [protocolMatch=1]
 * @param {number} [hashMatch=2]
 */ function isIpfs(input, pattern, protocolMatch = defaultProtocolMatch, hashMatch = defaultHashMath) {
    const formatted = convertToString(input);
    if (!formatted) return false;
    const match = formatted.match(pattern);
    if (!match) return false;
    if (match[protocolMatch] !== 'ipfs') return false;
    let hash = match[hashMatch];
    if (hash && pattern === subdomainGatewayPattern) // when doing checks for subdomain context
    // ensure hash is case-insensitive
    // (browsers force-lowercase authority component anyway)
    hash = hash.toLowerCase();
    return isCID(hash);
}
/**
 *
 * @param {string | Uint8Array} input
 * @param {string | RegExp} pattern
 * @param {number} [protocolMatch=1]
 * @param {number} [hashMatch=1]
 */ function isIpns(input, pattern, protocolMatch = defaultProtocolMatch, hashMatch = defaultHashMath) {
    const formatted = convertToString(input);
    if (!formatted) return false;
    const match = formatted.match(pattern);
    if (!match) return false;
    if (match[protocolMatch] !== 'ipns') return false;
    let ipnsId = match[hashMatch];
    if (ipnsId && pattern === subdomainGatewayPattern) {
        // when doing checks for subdomain context
        // ensure ipnsId is case-insensitive
        // (browsers force-lowercase authority compotent anyway)
        ipnsId = ipnsId.toLowerCase();
        // Check if it is cidv1
        if (isCID(ipnsId)) return true;
        // Check if it looks like FQDN
        try {
            if (!ipnsId.includes('.') && ipnsId.includes('-')) // name without tld, assuming its inlined into a single DNS label
            // (https://github.com/ipfs/in-web-browsers/issues/169)
            // en-wikipedia--on--ipfs-org → en.wikipedia-on-ipfs.org
            ipnsId = ipnsId.replace(/--/g, '@').replace(/-/g, '.').replace(/@/g, '-');
            // URL implementation in web browsers forces lowercase of the hostname
            const { hostname  } = new URL(`http://${ipnsId}`) // eslint-disable-line no-new
            ;
            // Check if potential FQDN has an explicit TLD
            return fqdnWithTld.test(hostname);
        } catch (e) {
            return false;
        }
    }
    return true;
}
/**
 * @param {any} input
 */ function isString(input) {
    return typeof input === 'string';
}
/**
 * @param {Uint8Array | string} input
 */ function convertToString(input) {
    if (input instanceof Uint8Array) return uint8ArrayToString(input, 'base58btc');
    if (isString(input)) return input;
    return false;
}
/**
 * @param {string | Uint8Array} url
 */ const ipfsSubdomain = (url)=>isIpfs(url, subdomainGatewayPattern, subdomainProtocolMatch, subdomainIdMatch)
;
/**
 * @param {string | Uint8Array} url
 */ const ipnsSubdomain = (url)=>isIpns(url, subdomainGatewayPattern, subdomainProtocolMatch, subdomainIdMatch)
;
/**
 * @param {string | Uint8Array} url
 */ const subdomain = (url)=>ipfsSubdomain(url) || ipnsSubdomain(url)
;
/**
 * @param {string | Uint8Array} url
 */ const ipfsUrl = (url)=>isIpfs(url, pathGatewayPattern) || ipfsSubdomain(url)
;
/**
 * @param {string | Uint8Array} url
 */ const ipnsUrl = (url)=>isIpns(url, pathGatewayPattern) || ipnsSubdomain(url)
;
/**
 * @param {string | Uint8Array} url
 */ const url1 = (url)=>ipfsUrl(url) || ipnsUrl(url) || subdomain(url)
;
/**
 * @param {string | Uint8Array} path
 */ const path1 = (path)=>isIpfs(path, pathPattern) || isIpns(path, pathPattern)
;
module.exports = {
    multihash: isMultihash,
    multiaddr: isMultiaddr,
    peerMultiaddr: isPeerMultiaddr,
    cid: isCID,
    /**
   * @param {CID | string | Uint8Array} cid
   */ base32cid: (cid)=>isBase32EncodedMultibase(cid) && isCID(cid)
    ,
    ipfsSubdomain,
    ipnsSubdomain,
    subdomain,
    subdomainGatewayPattern,
    ipfsUrl,
    ipnsUrl,
    url: url1,
    pathGatewayPattern: pathGatewayPattern,
    /**
   * @param {string | Uint8Array} path
   */ ipfsPath: (path)=>isIpfs(path, pathPattern)
    ,
    /**
   * @param {string | Uint8Array} path
   */ ipnsPath: (path)=>isIpns(path, pathPattern)
    ,
    path: path1,
    pathPattern,
    /**
   * @param {string | Uint8Array} x
   */ urlOrPath: (x)=>url1(x) || path1(x)
    ,
    /**
   * @param {string | Uint8Array | CID} path
   */ cidPath: (path)=>isString(path) && !isCID(path) && isIpfs(`/ipfs/${path}`, pathPattern)
};

},{"multiformats/bases/base58":"6Rnqi","multiformats/bases/base32":"63xDB","multiformats/hashes/digest":"fkA58","multiaddr":"kOPrF","mafmt":"hdtcj","multiformats/cid":"fJJnW","iso-url":"9XZNu","uint8arrays/to-string":"g3mCQ"}],"kOPrF":[function(require,module,exports) {
'use strict';
const codec = require('./codec');
const protocols = require('./protocols-table');
const varint = require('varint');
const { CID  } = require('multiformats/cid');
const { base58btc  } = require('multiformats/bases/base58');
const errCode = require('err-code');
const inspect = Symbol.for('nodejs.util.inspect.custom');
const { toString: uint8ArrayToString  } = require('uint8arrays/to-string');
const { equals: uint8ArrayEquals  } = require('uint8arrays/equals');
/**
 * @typedef {(addr: Multiaddr) => Promise<string[]>} Resolver
 * @typedef {string | Multiaddr | Uint8Array | null} MultiaddrInput
 * @typedef {import('./types').MultiaddrObject} MultiaddrObject
 * @typedef {import('./types').Protocol} Protocol
 */ /** @type {Map<string, Resolver>} */ const resolvers = new Map();
const symbol = Symbol.for('@multiformats/js-multiaddr/multiaddr');
/**
 * Creates a [multiaddr](https://github.com/multiformats/multiaddr) from
 * a Uint8Array, String or another Multiaddr instance
 * public key.
 *
 */ class Multiaddr {
    /**
   * @example
   * ```js
   * new Multiaddr('/ip4/127.0.0.1/tcp/4001')
   * // <Multiaddr 047f000001060fa1 - /ip4/127.0.0.1/tcp/4001>
   * ```
   *
   * @param {MultiaddrInput} [addr] - If String or Uint8Array, needs to adhere to the address format of a [multiaddr](https://github.com/multiformats/multiaddr#string-format)
   */ constructor(addr7){
        // default
        if (addr7 == null) addr7 = '';
        // Define symbol
        Object.defineProperty(this, symbol, {
            value: true
        });
        if (addr7 instanceof Uint8Array) /** @type {Uint8Array} - The raw bytes representing this multiaddress */ this.bytes = codec.fromBytes(addr7);
        else if (typeof addr7 === 'string') {
            if (addr7.length > 0 && addr7.charAt(0) !== '/') throw new Error(`multiaddr "${addr7}" must start with a "/"`);
            this.bytes = codec.fromString(addr7);
        } else if (Multiaddr.isMultiaddr(addr7)) this.bytes = codec.fromBytes(addr7.bytes) // validate + copy buffer
        ;
        else throw new Error('addr must be a string, Buffer, or another Multiaddr');
    }
    /**
   * Returns Multiaddr as a String
   *
   * @example
   * ```js
   * new Multiaddr('/ip4/127.0.0.1/tcp/4001').toString()
   * // '/ip4/127.0.0.1/tcp/4001'
   * ```
   */ toString() {
        return codec.bytesToString(this.bytes);
    }
    /**
   * Returns Multiaddr as a JSON encoded object
   *
   * @example
   * ```js
   * JSON.stringify(new Multiaddr('/ip4/127.0.0.1/tcp/4001'))
   * // '/ip4/127.0.0.1/tcp/4001'
   * ```
   */ toJSON() {
        return this.toString();
    }
    /**
   * Returns Multiaddr as a convinient options object to be used with net.createConnection
   *
   * @example
   * ```js
   * new Multiaddr('/ip4/127.0.0.1/tcp/4001').toOptions()
   * // { family: 4, host: '127.0.0.1', transport: 'tcp', port: 4001 }
   * ```
   */ toOptions() {
        /** @type {MultiaddrObject} */ const opts = {
        };
        const parsed = this.toString().split('/');
        opts.family = parsed[1] === 'ip4' ? 4 : 6;
        opts.host = parsed[2];
        opts.transport = parsed[3];
        opts.port = parseInt(parsed[4]);
        return opts;
    }
    /**
   * Returns the protocols the Multiaddr is defined with, as an array of objects, in
   * left-to-right order. Each object contains the protocol code, protocol name,
   * and the size of its address space in bits.
   * [See list of protocols](https://github.com/multiformats/multiaddr/blob/master/protocols.csv)
   *
   * @example
   * ```js
   * new Multiaddr('/ip4/127.0.0.1/tcp/4001').protos()
   * // [ { code: 4, size: 32, name: 'ip4' },
   * //   { code: 6, size: 16, name: 'tcp' } ]
   * ```
   *
   * @returns {Protocol[]} protocols - All the protocols the address is composed of
   */ protos() {
        return this.protoCodes().map((code)=>Object.assign({
            }, protocols(code))
        );
    }
    /**
   * Returns the codes of the protocols in left-to-right order.
   * [See list of protocols](https://github.com/multiformats/multiaddr/blob/master/protocols.csv)
   *
   * @example
   * ```js
   * Multiaddr('/ip4/127.0.0.1/tcp/4001').protoCodes()
   * // [ 4, 6 ]
   * ```
   *
   * @returns {number[]} protocol codes
   */ protoCodes() {
        const codes = [];
        const buf = this.bytes;
        let i = 0;
        while(i < buf.length){
            const code = varint.decode(buf, i);
            const n = varint.decode.bytes;
            const p = protocols(code);
            const size = codec.sizeForAddr(p, buf.slice(i + n));
            i += size + n;
            codes.push(code);
        }
        return codes;
    }
    /**
   * Returns the names of the protocols in left-to-right order.
   * [See list of protocols](https://github.com/multiformats/multiaddr/blob/master/protocols.csv)
   *
   * @example
   * ```js
   * new Multiaddr('/ip4/127.0.0.1/tcp/4001').protoNames()
   * // [ 'ip4', 'tcp' ]
   * ```
   *
   * @returns {string[]} protocol names
   */ protoNames() {
        return this.protos().map((proto)=>proto.name
        );
    }
    /**
   * Returns a tuple of parts
   *
   * @example
   * ```js
   * new Multiaddr("/ip4/127.0.0.1/tcp/4001").tuples()
   * // [ [ 4, <Buffer 7f 00 00 01> ], [ 6, <Buffer 0f a1> ] ]
   * ```
   */ tuples() {
        return codec.bytesToTuples(this.bytes);
    }
    /**
   * Returns a tuple of string/number parts
   * - tuples[][0] = code of protocol
   * - tuples[][1] = contents of address
   *
   * @example
   * ```js
   * new Multiaddr("/ip4/127.0.0.1/tcp/4001").stringTuples()
   * // [ [ 4, '127.0.0.1' ], [ 6, '4001' ] ]
   * ```
   */ stringTuples() {
        const t = codec.bytesToTuples(this.bytes);
        return codec.tuplesToStringTuples(t);
    }
    /**
   * Encapsulates a Multiaddr in another Multiaddr
   *
   * @example
   * ```js
   * const mh1 = new Multiaddr('/ip4/8.8.8.8/tcp/1080')
   * // <Multiaddr 0408080808060438 - /ip4/8.8.8.8/tcp/1080>
   *
   * const mh2 = new Multiaddr('/ip4/127.0.0.1/tcp/4001')
   * // <Multiaddr 047f000001060fa1 - /ip4/127.0.0.1/tcp/4001>
   *
   * const mh3 = mh1.encapsulate(mh2)
   * // <Multiaddr 0408080808060438047f000001060fa1 - /ip4/8.8.8.8/tcp/1080/ip4/127.0.0.1/tcp/4001>
   *
   * mh3.toString()
   * // '/ip4/8.8.8.8/tcp/1080/ip4/127.0.0.1/tcp/4001'
   * ```
   *
   * @param {MultiaddrInput} addr - Multiaddr to add into this Multiaddr
   */ encapsulate(addr1) {
        addr1 = new Multiaddr(addr1);
        return new Multiaddr(this.toString() + addr1.toString());
    }
    /**
   * Decapsulates a Multiaddr from another Multiaddr
   *
   * @example
   * ```js
   * const mh1 = new Multiaddr('/ip4/8.8.8.8/tcp/1080')
   * // <Multiaddr 0408080808060438 - /ip4/8.8.8.8/tcp/1080>
   *
   * const mh2 = new Multiaddr('/ip4/127.0.0.1/tcp/4001')
   * // <Multiaddr 047f000001060fa1 - /ip4/127.0.0.1/tcp/4001>
   *
   * const mh3 = mh1.encapsulate(mh2)
   * // <Multiaddr 0408080808060438047f000001060fa1 - /ip4/8.8.8.8/tcp/1080/ip4/127.0.0.1/tcp/4001>
   *
   * mh3.decapsulate(mh2).toString()
   * // '/ip4/8.8.8.8/tcp/1080'
   * ```
   *
   * @param {Multiaddr | string} addr - Multiaddr to remove from this Multiaddr
   * @returns {Multiaddr}
   */ decapsulate(addr2) {
        const addrString = addr2.toString();
        const s = this.toString();
        const i = s.lastIndexOf(addrString);
        if (i < 0) throw new Error('Address ' + this + ' does not contain subaddress: ' + addr2);
        return new Multiaddr(s.slice(0, i));
    }
    /**
   * A more reliable version of `decapsulate` if you are targeting a
   * specific code, such as 421 (the `p2p` protocol code). The last index of the code
   * will be removed from the `Multiaddr`, and a new instance will be returned.
   * If the code is not present, the original `Multiaddr` is returned.
   *
   * @example
   * ```js
   * const addr = new Multiaddr('/ip4/0.0.0.0/tcp/8080/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC')
   * // <Multiaddr 0400... - /ip4/0.0.0.0/tcp/8080/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC>
   *
   * addr.decapsulateCode(421).toString()
   * // '/ip4/0.0.0.0/tcp/8080'
   *
   * new Multiaddr('/ip4/127.0.0.1/tcp/8080').decapsulateCode(421).toString()
   * // '/ip4/127.0.0.1/tcp/8080'
   * ```
   *
   * @param {number} code - The code of the protocol to decapsulate from this Multiaddr
   * @returns {Multiaddr}
   */ decapsulateCode(code) {
        const tuples = this.tuples();
        for(let i = tuples.length - 1; i >= 0; i--){
            if (tuples[i][0] === code) return new Multiaddr(codec.tuplesToBytes(tuples.slice(0, i)));
        }
        return this;
    }
    /**
   * Extract the peerId if the multiaddr contains one
   *
   * @example
   * ```js
   * const mh1 = new Multiaddr('/ip4/8.8.8.8/tcp/1080/ipfs/QmValidBase58string')
   * // <Multiaddr 0408080808060438 - /ip4/8.8.8.8/tcp/1080/ipfs/QmValidBase58string>
   *
   * // should return QmValidBase58string or null if the id is missing or invalid
   * const peerId = mh1.getPeerId()
   * ```
   *
   * @returns {string | null} peerId - The id of the peer or null if invalid or missing from the ma
   */ getPeerId() {
        try {
            const tuples = this.stringTuples().filter((tuple)=>{
                if (tuple[0] === protocols.names.ipfs.code) return true;
                return false;
            });
            // Get the last ipfs tuple ['ipfs', 'peerid string']
            const tuple1 = tuples.pop();
            if (tuple1 && tuple1[1]) {
                const peerIdStr = tuple1[1];
                // peer id is base58btc encoded string but not multibase encoded so add the `z`
                // prefix so we can validate that it is correctly encoded
                if (peerIdStr[0] === 'Q' || peerIdStr[0] === '1') return uint8ArrayToString(base58btc.decode(`z${peerIdStr}`), 'base58btc');
                // try to parse peer id as CID
                return uint8ArrayToString(CID.parse(peerIdStr).multihash.bytes, 'base58btc');
            }
            return null;
        } catch (e) {
            return null;
        }
    }
    /**
   * Extract the path if the multiaddr contains one
   *
   * @example
   * ```js
   * const mh1 = new Multiaddr('/ip4/8.8.8.8/tcp/1080/unix/tmp/p2p.sock')
   * // <Multiaddr 0408080808060438 - /ip4/8.8.8.8/tcp/1080/unix/tmp/p2p.sock>
   *
   * // should return utf8 string or null if the id is missing or invalid
   * const path = mh1.getPath()
   * ```js
   *
   * @returns {string | null} path - The path of the multiaddr, or null if no path protocol is present
   */ getPath() {
        let path = null;
        try {
            path = this.stringTuples().filter((tuple)=>{
                const proto = protocols(tuple[0]);
                if (proto.path) return true;
                return false;
            })[0][1];
            if (!path) path = null;
        } catch (e) {
            path = null;
        }
        return path;
    }
    /**
   * Checks if two Multiaddrs are the same
   *
   * @example
   * ```js
   * const mh1 = new Multiaddr('/ip4/8.8.8.8/tcp/1080')
   * // <Multiaddr 0408080808060438 - /ip4/8.8.8.8/tcp/1080>
   *
   * const mh2 = new Multiaddr('/ip4/127.0.0.1/tcp/4001')
   * // <Multiaddr 047f000001060fa1 - /ip4/127.0.0.1/tcp/4001>
   *
   * mh1.equals(mh1)
   * // true
   *
   * mh1.equals(mh2)
   * // false
   * ```
   *
   * @param {Multiaddr} addr
   * @returns {boolean}
   */ equals(addr3) {
        return uint8ArrayEquals(this.bytes, addr3.bytes);
    }
    /**
   * Resolve multiaddr if containing resolvable hostname.
   *
   * @example
   * ```js
   * Multiaddr.resolvers.set('dnsaddr', resolverFunction)
   * const mh1 = new Multiaddr('/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb')
   * const resolvedMultiaddrs = await mh1.resolve()
   * // [
   * //   <Multiaddr 04934b5353060fa1a503221220c10f9319dac35c270a6b74cd644cb3acfc1f6efc8c821f8eb282599fd1814f64 - /ip4/147.75.83.83/tcp/4001/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb>,
   * //   <Multiaddr 04934b53530601bbde03a503221220c10f9319dac35c270a6b74cd644cb3acfc1f6efc8c821f8eb282599fd1814f64 - /ip4/147.75.83.83/tcp/443/wss/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb>,
   * //   <Multiaddr 04934b535391020fa1cc03a503221220c10f9319dac35c270a6b74cd644cb3acfc1f6efc8c821f8eb282599fd1814f64 - /ip4/147.75.83.83/udp/4001/quic/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb>
   * // ]
   * ```
   *
   * @returns {Promise<Array<Multiaddr>>}
   */ async resolve() {
        const resolvableProto = this.protos().find((p)=>p.resolvable
        );
        // Multiaddr is not resolvable?
        if (!resolvableProto) return [
            this
        ];
        const resolver = resolvers.get(resolvableProto.name);
        if (!resolver) throw errCode(new Error(`no available resolver for ${resolvableProto.name}`), 'ERR_NO_AVAILABLE_RESOLVER');
        const addresses = await resolver(this);
        return addresses.map((a)=>new Multiaddr(a)
        );
    }
    /**
   * Gets a Multiaddrs node-friendly address object. Note that protocol information
   * is left out: in Node (and most network systems) the protocol is unknowable
   * given only the address.
   *
   * Has to be a ThinWaist Address, otherwise throws error
   *
   * @example
   * ```js
   * new Multiaddr('/ip4/127.0.0.1/tcp/4001').nodeAddress()
   * // {family: 4, address: '127.0.0.1', port: 4001}
   * ```
   *
   * @returns {{family: 4 | 6, address: string, port: number}}
   * @throws {Error} Throws error if Multiaddr is not a Thin Waist address
   */ nodeAddress() {
        const codes = this.protoCodes();
        const names = this.protoNames();
        const parts = this.toString().split('/').slice(1);
        if (parts.length < 4) throw new Error('multiaddr must have a valid format: "/{ip4, ip6, dns4, dns6}/{address}/{tcp, udp}/{port}".');
        else if (codes[0] !== 4 && codes[0] !== 41 && codes[0] !== 54 && codes[0] !== 55) throw new Error(`no protocol with name: "'${names[0]}'". Must have a valid family name: "{ip4, ip6, dns4, dns6}".`);
        else if (parts[2] !== 'tcp' && parts[2] !== 'udp') throw new Error(`no protocol with name: "'${names[1]}'". Must have a valid transport protocol: "{tcp, udp}".`);
        return {
            family: codes[0] === 41 || codes[0] === 55 ? 6 : 4,
            address: parts[1],
            port: parseInt(parts[3]) // tcp or udp port
        };
    }
    /**
   * Returns if a Multiaddr is a Thin Waist address or not.
   *
   * Thin Waist is if a Multiaddr adheres to the standard combination of:
   *
   * `{IPv4, IPv6}/{TCP, UDP}`
   *
   * @example
   * ```js
   * const mh1 = new Multiaddr('/ip4/127.0.0.1/tcp/4001')
   * // <Multiaddr 047f000001060fa1 - /ip4/127.0.0.1/tcp/4001>
   * const mh2 = new Multiaddr('/ip4/192.168.2.1/tcp/5001')
   * // <Multiaddr 04c0a80201061389 - /ip4/192.168.2.1/tcp/5001>
   * const mh3 = mh1.encapsulate(mh2)
   * // <Multiaddr 047f000001060fa104c0a80201061389 - /ip4/127.0.0.1/tcp/4001/ip4/192.168.2.1/tcp/5001>
   * const mh4 = new Multiaddr('/ip4/127.0.0.1/tcp/2000/wss/p2p-webrtc-star/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSooo2a')
   * // <Multiaddr 047f0000010607d0de039302a503221220d52ebb89d85b02a284948203a62ff28389c57c9f42beec4ec20db76a64835843 - /ip4/127.0.0.1/tcp/2000/wss/p2p-webrtc-star/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSooo2a>
   * mh1.isThinWaistAddress()
   * // true
   * mh2.isThinWaistAddress()
   * // true
   * mh3.isThinWaistAddress()
   * // false
   * mh4.isThinWaistAddress()
   * // false
   * ```
   *
   * @param {Multiaddr} [addr] - Defaults to using `this` instance
   */ isThinWaistAddress(addr4) {
        const protos = (addr4 || this).protos();
        if (protos.length !== 2) return false;
        if (protos[0].code !== 4 && protos[0].code !== 41) return false;
        if (protos[1].code !== 6 && protos[1].code !== 273) return false;
        return true;
    }
    /**
   * Creates a Multiaddr from a node-friendly address object
   *
   * @example
   * ```js
   * Multiaddr.fromNodeAddress({address: '127.0.0.1', port: '4001'}, 'tcp')
   * // <Multiaddr 047f000001060fa1 - /ip4/127.0.0.1/tcp/4001>
   * ```
   *
   * @param {{family: 4 | 6, address: string, port: number}} addr
   * @param {string} transport
   */ static fromNodeAddress(addr5, transport) {
        if (!addr5) throw new Error('requires node address object');
        if (!transport) throw new Error('requires transport protocol');
        let ip;
        switch(addr5.family){
            case 4:
                ip = 'ip4';
                break;
            case 6:
                ip = 'ip6';
                break;
            default:
                throw Error(`Invalid addr family. Got '${addr5.family}' instead of 4 or 6`);
        }
        return new Multiaddr('/' + [
            ip,
            addr5.address,
            transport,
            addr5.port
        ].join('/'));
    }
    /**
   * Returns if something is a Multiaddr that is a name
   *
   * @param {Multiaddr} addr
   * @returns {boolean} isName
   */ static isName(addr6) {
        if (!Multiaddr.isMultiaddr(addr6)) return false;
        // if a part of the multiaddr is resolvable, then return true
        return addr6.protos().some((proto)=>proto.resolvable
        );
    }
    /**
   * Check if object is a CID instance
   *
   * @param {any} value
   * @returns {value is Multiaddr}
   */ static isMultiaddr(value) {
        return value instanceof Multiaddr || Boolean(value && value[symbol]);
    }
    /**
   * Returns Multiaddr as a human-readable string.
   * For post Node.js v10.0.0.
   * https://nodejs.org/api/deprecations.html#deprecations_dep0079_custom_inspection_function_on_objects_via_inspect
   *
   * @example
   * ```js
   * console.log(new Multiaddr('/ip4/127.0.0.1/tcp/4001'))
   * // '<Multiaddr 047f000001060fa1 - /ip4/127.0.0.1/tcp/4001>'
   * ```
   *
   * @returns {string}
   */ [inspect]() {
        return '<Multiaddr ' + uint8ArrayToString(this.bytes, 'base16') + ' - ' + codec.bytesToString(this.bytes) + '>';
    }
    /**
   * Returns Multiaddr as a human-readable string.
   * Fallback for pre Node.js v10.0.0.
   * https://nodejs.org/api/deprecations.html#deprecations_dep0079_custom_inspection_function_on_objects_via_inspect
   *
   * @example
   * ```js
   * new Multiaddr('/ip4/127.0.0.1/tcp/4001').inspect()
   * // '<Multiaddr 047f000001060fa1 - /ip4/127.0.0.1/tcp/4001>'
   * ```
   *
   * @returns {string}
   */ inspect() {
        return '<Multiaddr ' + uint8ArrayToString(this.bytes, 'base16') + ' - ' + codec.bytesToString(this.bytes) + '>';
    }
}
/**
 * Object containing table, names and codes of all supported protocols.
 * To get the protocol values from a Multiaddr, you can use
 * [`.protos()`](#multiaddrprotos),
 * [`.protoCodes()`](#multiaddrprotocodes) or
 * [`.protoNames()`](#multiaddrprotonames)
 *
 * @returns {{table: Array, names: Object, codes: Object}}
 */ Multiaddr.protocols = protocols;
Multiaddr.resolvers = resolvers;
/**
 * Static factory
 *
 * @param {MultiaddrInput} addr
 */ function multiaddr(addr) {
    return new Multiaddr(addr);
}
module.exports = {
    Multiaddr,
    multiaddr,
    protocols,
    resolvers
};

},{"./codec":"bMXg7","./protocols-table":"5rCcx","varint":"l84uL","multiformats/cid":"fJJnW","multiformats/bases/base58":"6Rnqi","err-code":"eQvyh","uint8arrays/to-string":"g3mCQ","uint8arrays/equals":"fjLeN"}],"bMXg7":[function(require,module,exports) {
'use strict';
const convert = require('./convert');
const protocols = require('./protocols-table');
const varint = require('varint');
const { concat: uint8ArrayConcat  } = require('uint8arrays/concat');
const { toString: uint8ArrayToString  } = require('uint8arrays/to-string');
// export codec
module.exports = {
    stringToStringTuples,
    stringTuplesToString,
    tuplesToStringTuples,
    stringTuplesToTuples,
    bytesToTuples,
    tuplesToBytes,
    bytesToString,
    stringToBytes,
    fromString,
    fromBytes,
    validateBytes,
    isValidBytes,
    cleanPath,
    ParseError,
    protoFromTuple,
    sizeForAddr
};
// string -> [[str name, str addr]... ]
/**
 * @param {string} str
 */ function stringToStringTuples(str) {
    const tuples = [];
    const parts = str.split('/').slice(1) // skip first empty elem
    ;
    if (parts.length === 1 && parts[0] === '') return [];
    for(let p = 0; p < parts.length; p++){
        const part = parts[p];
        const proto = protocols(part);
        if (proto.size === 0) {
            tuples.push([
                part
            ]);
            continue;
        }
        p++ // advance addr part
        ;
        if (p >= parts.length) throw ParseError('invalid address: ' + str);
        // if it's a path proto, take the rest
        if (proto.path) {
            tuples.push([
                part,
                // TODO: should we need to check each path part to see if it's a proto?
                // This would allow for other protocols to be added after a unix path,
                // however it would have issues if the path had a protocol name in the path
                cleanPath(parts.slice(p).join('/'))
            ]);
            break;
        }
        tuples.push([
            part,
            parts[p]
        ]);
    }
    return tuples;
}
// [[str name, str addr]... ] -> string
/**
 * @param {[number, string?][]} tuples
 */ function stringTuplesToString(tuples) {
    /** @type {Array<string | undefined>} */ const parts = [];
    tuples.map((tup)=>{
        const proto = protoFromTuple(tup);
        parts.push(proto.name);
        if (tup.length > 1) parts.push(tup[1]);
        return null;
    });
    return cleanPath(parts.join('/'));
}
// [[str name, str addr]... ] -> [[int code, Uint8Array]... ]
/**
 * @param {Array<string[] | string >} tuples
 * @returns {[number , Uint8Array?][]}
 */ function stringTuplesToTuples(tuples) {
    return tuples.map((tup)=>{
        if (!Array.isArray(tup)) tup = [
            tup
        ];
        const proto = protoFromTuple(tup);
        if (tup.length > 1) return [
            proto.code,
            convert.toBytes(proto.code, tup[1])
        ];
        return [
            proto.code
        ];
    });
}
/**
 * Convert tuples to string tuples
 *
 * [[int code, Uint8Array]... ] -> [[int code, str addr]... ]
 *
 * @param {Array<[number, Uint8Array?]>} tuples
 * @returns {Array<[number, string?]>}
 */ function tuplesToStringTuples(tuples) {
    return tuples.map((tup)=>{
        const proto = protoFromTuple(tup);
        if (tup[1]) return [
            proto.code,
            convert.toString(proto.code, tup[1])
        ];
        return [
            proto.code
        ];
    });
}
// [[int code, Uint8Array ]... ] -> Uint8Array
/**
 * @param {[number, Uint8Array?][]} tuples
 */ function tuplesToBytes(tuples) {
    return fromBytes(uint8ArrayConcat(tuples.map((/** @type {any[]} */ tup)=>{
        const proto = protoFromTuple(tup);
        let buf = Uint8Array.from(varint.encode(proto.code));
        if (tup.length > 1) buf = uint8ArrayConcat([
            buf,
            tup[1]
        ]) // add address buffer
        ;
        return buf;
    })));
}
/**
 * @param {import("./types").Protocol} p
 * @param {Uint8Array | number[]} addr
 */ function sizeForAddr(p, addr) {
    if (p.size > 0) return p.size / 8;
    else if (p.size === 0) return 0;
    else {
        const size = varint.decode(addr);
        return size + varint.decode.bytes;
    }
}
/**
 *
 * @param {Uint8Array} buf
 * @returns {Array<[number, Uint8Array?]>}
 */ function bytesToTuples(buf) {
    /** @type {Array<[number, Uint8Array?]>} */ const tuples = [];
    let i = 0;
    while(i < buf.length){
        const code = varint.decode(buf, i);
        const n = varint.decode.bytes;
        const p = protocols(code);
        const size = sizeForAddr(p, buf.slice(i + n));
        if (size === 0) {
            tuples.push([
                code
            ]);
            i += n;
            continue;
        }
        const addr = buf.slice(i + n, i + n + size);
        i += size + n;
        if (i > buf.length) throw ParseError('Invalid address Uint8Array: ' + uint8ArrayToString(buf, 'base16'));
        // ok, tuple seems good.
        tuples.push([
            code,
            addr
        ]);
    }
    return tuples;
}
// Uint8Array -> String
/**
 * @param {Uint8Array} buf
 */ function bytesToString(buf) {
    const a = bytesToTuples(buf);
    const b = tuplesToStringTuples(a);
    return stringTuplesToString(b);
}
// String -> Uint8Array
/**
 * @param {string} str
 */ function stringToBytes(str) {
    str = cleanPath(str);
    const a = stringToStringTuples(str);
    const b = stringTuplesToTuples(a);
    return tuplesToBytes(b);
}
// String -> Uint8Array
/**
 * @param {string} str
 */ function fromString(str) {
    return stringToBytes(str);
}
// Uint8Array -> Uint8Array
/**
 * @param {Uint8Array} buf
 */ function fromBytes(buf) {
    const err = validateBytes(buf);
    if (err) throw err;
    return Uint8Array.from(buf) // copy
    ;
}
/**
 * @param {Uint8Array} buf
 */ function validateBytes(buf) {
    try {
        bytesToTuples(buf) // try to parse. will throw if breaks
        ;
    } catch (err) {
        return err;
    }
}
/**
 * @param {Uint8Array} buf
 */ function isValidBytes(buf) {
    return validateBytes(buf) === undefined;
}
/**
 * @param {string} str
 */ function cleanPath(str) {
    return '/' + str.trim().split('/').filter((/** @type {any} */ a)=>a
    ).join('/');
}
/**
 * @param {string} str
 */ function ParseError(str) {
    return new Error('Error parsing address: ' + str);
}
/**
 * @param {any[]} tup
 */ function protoFromTuple(tup) {
    const proto = protocols(tup[0]);
    return proto;
}

},{"./convert":"qvwHL","./protocols-table":"5rCcx","varint":"l84uL","uint8arrays/concat":"fLIrL","uint8arrays/to-string":"g3mCQ"}],"qvwHL":[function(require,module,exports) {
'use strict';
const ip = require('./ip');
const protocols = require('./protocols-table');
const { CID  } = require('multiformats/cid');
const { base32  } = require('multiformats/bases/base32');
const { base58btc  } = require('multiformats/bases/base58');
const Digest = require('multiformats/hashes/digest');
const varint = require('varint');
const { toString: uint8ArrayToString  } = require('uint8arrays/to-string');
const { fromString: uint8ArrayFromString  } = require('uint8arrays/from-string');
const { concat: uint8ArrayConcat  } = require('uint8arrays/concat');
module.exports = Convert;
// converts (serializes) addresses
/**
 * @param {string} proto
 * @param {string | Uint8Array} a
 */ function Convert(proto, a) {
    if (a instanceof Uint8Array) return Convert.toString(proto, a);
    else return Convert.toBytes(proto, a);
}
/**
 * Convert [code,Uint8Array] to string
 *
 * @param {number|string} proto
 * @param {Uint8Array} buf
 * @returns {string}
 */ Convert.toString = function convertToString(proto, buf) {
    const protocol = protocols(proto);
    switch(protocol.code){
        case 4:
        case 41:
            return bytes2ip(buf);
        case 6:
        case 273:
        case 33:
        case 132:
            return bytes2port(buf).toString();
        case 53:
        case 54:
        case 55:
        case 56:
        case 400:
        case 777:
            return bytes2str(buf);
        case 421:
            return bytes2mh(buf);
        case 444:
            return bytes2onion(buf);
        case 445:
            return bytes2onion(buf);
        default:
            return uint8ArrayToString(buf, 'base16') // no clue. convert to hex
            ;
    }
};
Convert.toBytes = function convertToBytes(/** @type {string | number } */ proto, /** @type {string} */ str) {
    const protocol = protocols(proto);
    switch(protocol.code){
        case 4:
            return ip2bytes(str);
        case 41:
            return ip2bytes(str);
        case 6:
        case 273:
        case 33:
        case 132:
            return port2bytes(parseInt(str, 10));
        case 53:
        case 54:
        case 55:
        case 56:
        case 400:
        case 777:
            return str2bytes(str);
        case 421:
            return mh2bytes(str);
        case 444:
            return onion2bytes(str);
        case 445:
            return onion32bytes(str);
        default:
            return uint8ArrayFromString(str, 'base16') // no clue. convert from hex
            ;
    }
};
/**
 * @param {string} ipString
 */ function ip2bytes(ipString) {
    if (!ip.isIP(ipString)) throw new Error('invalid ip address');
    return ip.toBytes(ipString);
}
/**
 * @param {Uint8Array} ipBuff
 */ function bytes2ip(ipBuff) {
    const ipString = ip.toString(ipBuff);
    if (!ipString || !ip.isIP(ipString)) throw new Error('invalid ip address');
    return ipString;
}
/**
 * @param {number} port
 */ function port2bytes(port) {
    const buf = new ArrayBuffer(2);
    const view = new DataView(buf);
    view.setUint16(0, port);
    return new Uint8Array(buf);
}
/**
 * @param {Uint8Array} buf
 */ function bytes2port(buf) {
    const view = new DataView(buf.buffer);
    return view.getUint16(buf.byteOffset);
}
/**
 * @param {string} str
 */ function str2bytes(str) {
    const buf = uint8ArrayFromString(str);
    const size = Uint8Array.from(varint.encode(buf.length));
    return uint8ArrayConcat([
        size,
        buf
    ], size.length + buf.length);
}
/**
 * @param {Uint8Array} buf
 */ function bytes2str(buf) {
    const size = varint.decode(buf);
    buf = buf.slice(varint.decode.bytes);
    if (buf.length !== size) throw new Error('inconsistent lengths');
    return uint8ArrayToString(buf);
}
/**
 * @param {string} hash - base58btc string
 */ function mh2bytes(hash) {
    let mh;
    if (hash[0] === 'Q' || hash[0] === '1') mh = Digest.decode(base58btc.decode(`z${hash}`)).bytes;
    else mh = CID.parse(hash).multihash.bytes;
    // the address is a varint prefixed multihash string representation
    const size = Uint8Array.from(varint.encode(mh.length));
    return uint8ArrayConcat([
        size,
        mh
    ], size.length + mh.length);
}
/**
 * Converts bytes to bas58btc string
 *
 * @param {Uint8Array} buf
 * @returns {string} base58btc string
 */ function bytes2mh(buf) {
    const size = varint.decode(buf);
    const address = buf.slice(varint.decode.bytes);
    if (address.length !== size) throw new Error('inconsistent lengths');
    return uint8ArrayToString(address, 'base58btc');
}
/**
 * @param {string} str
 */ function onion2bytes(str) {
    const addr = str.split(':');
    if (addr.length !== 2) throw new Error('failed to parse onion addr: ' + addr + ' does not contain a port number');
    if (addr[0].length !== 16) throw new Error('failed to parse onion addr: ' + addr[0] + ' not a Tor onion address.');
    // onion addresses do not include the multibase prefix, add it before decoding
    const buf = base32.decode('b' + addr[0]);
    // onion port number
    const port = parseInt(addr[1], 10);
    if (port < 1 || port > 65536) throw new Error('Port number is not in range(1, 65536)');
    const portBuf = port2bytes(port);
    return uint8ArrayConcat([
        buf,
        portBuf
    ], buf.length + portBuf.length);
}
/**
 * @param {string} str
 */ function onion32bytes(str) {
    const addr = str.split(':');
    if (addr.length !== 2) throw new Error('failed to parse onion addr: ' + addr + ' does not contain a port number');
    if (addr[0].length !== 56) throw new Error('failed to parse onion addr: ' + addr[0] + ' not a Tor onion3 address.');
    // onion addresses do not include the multibase prefix, add it before decoding
    const buf = base32.decode('b' + addr[0]);
    // onion port number
    const port = parseInt(addr[1], 10);
    if (port < 1 || port > 65536) throw new Error('Port number is not in range(1, 65536)');
    const portBuf = port2bytes(port);
    return uint8ArrayConcat([
        buf,
        portBuf
    ], buf.length + portBuf.length);
}
/**
 * @param {Uint8Array} buf
 */ function bytes2onion(buf) {
    const addrBytes = buf.slice(0, buf.length - 2);
    const portBytes = buf.slice(buf.length - 2);
    const addr = uint8ArrayToString(addrBytes, 'base32');
    const port = bytes2port(portBytes);
    return addr + ':' + port;
}

},{"./ip":"48EtF","./protocols-table":"5rCcx","multiformats/cid":"fJJnW","multiformats/bases/base32":"63xDB","multiformats/bases/base58":"6Rnqi","multiformats/hashes/digest":"fkA58","varint":"l84uL","uint8arrays/to-string":"g3mCQ","uint8arrays/from-string":"lo45E","uint8arrays/concat":"fLIrL"}],"48EtF":[function(require,module,exports) {
'use strict';
const isIp = require('is-ip');
const { toString: uint8ArrayToString  } = require('uint8arrays/to-string');
const isIP = isIp;
const isV4 = isIp.v4;
const isV6 = isIp.v6;
// Copied from https://github.com/indutny/node-ip/blob/master/lib/ip.js#L7
// @ts-ignore - this is copied from the link above better to keep it the same
const toBytes = function(ip, buff, offset) {
    offset = ~~offset;
    let result;
    if (isV4(ip)) {
        result = buff || new Uint8Array(offset + 4);
        // @ts-ignore
        // eslint-disable-next-line array-callback-return
        ip.split(/\./g).map(function(byte) {
            result[offset++] = parseInt(byte, 10) & 255;
        });
    } else if (isV6(ip)) {
        const sections = ip.split(':', 8);
        let i;
        for(i = 0; i < sections.length; i++){
            const isv4 = isV4(sections[i]);
            let v4Buffer;
            if (isv4) {
                v4Buffer = toBytes(sections[i]);
                sections[i] = uint8ArrayToString(v4Buffer.slice(0, 2), 'base16');
            }
            if (v4Buffer && ++i < 8) sections.splice(i, 0, uint8ArrayToString(v4Buffer.slice(2, 4), 'base16'));
        }
        if (sections[0] === '') while(sections.length < 8)sections.unshift('0');
        else if (sections[sections.length - 1] === '') while(sections.length < 8)sections.push('0');
        else if (sections.length < 8) {
            for(i = 0; i < sections.length && sections[i] !== ''; i++);
            const argv = [
                i,
                '1'
            ];
            for(i = 9 - sections.length; i > 0; i--)argv.push('0');
            sections.splice.apply(sections, argv);
        }
        result = buff || new Uint8Array(offset + 16);
        for(i = 0; i < sections.length; i++){
            const word = parseInt(sections[i], 16);
            result[offset++] = word >> 8 & 255;
            result[offset++] = word & 255;
        }
    }
    if (!result) throw Error('Invalid ip address: ' + ip);
    return result;
};
// Copied from https://github.com/indutny/node-ip/blob/master/lib/ip.js#L63
// @ts-ignore - this is copied from the link above better to keep it the same
const toString = function(buff, offset, length) {
    offset = ~~offset;
    length = length || buff.length - offset;
    const result = [];
    let string;
    const view = new DataView(buff.buffer);
    if (length === 4) {
        // IPv4
        for(let i = 0; i < length; i++)result.push(buff[offset + i]);
        string = result.join('.');
    } else if (length === 16) {
        // IPv6
        for(let i = 0; i < length; i += 2)result.push(view.getUint16(offset + i).toString(16));
        string = result.join(':');
        string = string.replace(/(^|:)0(:0)*:0(:|$)/, '$1::$3');
        string = string.replace(/:{3,4}/, '::');
    }
    return string;
};
module.exports = {
    isIP,
    isV4,
    isV6,
    toBytes,
    toString
};

},{"is-ip":"fEoXA","uint8arrays/to-string":"g3mCQ"}],"fEoXA":[function(require,module,exports) {
'use strict';
const ipRegex = require('ip-regex');
const isIp = (string)=>ipRegex({
        exact: true
    }).test(string)
;
isIp.v4 = (string)=>ipRegex.v4({
        exact: true
    }).test(string)
;
isIp.v6 = (string)=>ipRegex.v6({
        exact: true
    }).test(string)
;
isIp.version = (string)=>isIp(string) ? isIp.v4(string) ? 4 : 6 : undefined
;
module.exports = isIp;

},{"ip-regex":"36RLZ"}],"36RLZ":[function(require,module,exports) {
'use strict';
const word = '[a-fA-F\\d:]';
const b = (options)=>options && options.includeBoundaries ? `(?:(?<=\\s|^)(?=${word})|(?<=${word})(?=\\s|$))` : ''
;
const v4 = '(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}';
const v6seg = '[a-fA-F\\d]{1,4}';
const v6 = `
(?:
(?:${v6seg}:){7}(?:${v6seg}|:)|                                    // 1:2:3:4:5:6:7::  1:2:3:4:5:6:7:8
(?:${v6seg}:){6}(?:${v4}|:${v6seg}|:)|                             // 1:2:3:4:5:6::    1:2:3:4:5:6::8   1:2:3:4:5:6::8  1:2:3:4:5:6::1.2.3.4
(?:${v6seg}:){5}(?::${v4}|(?::${v6seg}){1,2}|:)|                   // 1:2:3:4:5::      1:2:3:4:5::7:8   1:2:3:4:5::8    1:2:3:4:5::7:1.2.3.4
(?:${v6seg}:){4}(?:(?::${v6seg}){0,1}:${v4}|(?::${v6seg}){1,3}|:)| // 1:2:3:4::        1:2:3:4::6:7:8   1:2:3:4::8      1:2:3:4::6:7:1.2.3.4
(?:${v6seg}:){3}(?:(?::${v6seg}){0,2}:${v4}|(?::${v6seg}){1,4}|:)| // 1:2:3::          1:2:3::5:6:7:8   1:2:3::8        1:2:3::5:6:7:1.2.3.4
(?:${v6seg}:){2}(?:(?::${v6seg}){0,3}:${v4}|(?::${v6seg}){1,5}|:)| // 1:2::            1:2::4:5:6:7:8   1:2::8          1:2::4:5:6:7:1.2.3.4
(?:${v6seg}:){1}(?:(?::${v6seg}){0,4}:${v4}|(?::${v6seg}){1,6}|:)| // 1::              1::3:4:5:6:7:8   1::8            1::3:4:5:6:7:1.2.3.4
(?::(?:(?::${v6seg}){0,5}:${v4}|(?::${v6seg}){1,7}|:))             // ::2:3:4:5:6:7:8  ::2:3:4:5:6:7:8  ::8             ::1.2.3.4
)(?:%[0-9a-zA-Z]{1,})?                                             // %eth0            %1
`.replace(/\s*\/\/.*$/gm, '').replace(/\n/g, '').trim();
// Pre-compile only the exact regexes because adding a global flag make regexes stateful
const v46Exact = new RegExp(`(?:^${v4}$)|(?:^${v6}$)`);
const v4exact = new RegExp(`^${v4}$`);
const v6exact = new RegExp(`^${v6}$`);
const ip = (options)=>options && options.exact ? v46Exact : new RegExp(`(?:${b(options)}${v4}${b(options)})|(?:${b(options)}${v6}${b(options)})`, 'g')
;
ip.v4 = (options)=>options && options.exact ? v4exact : new RegExp(`${b(options)}${v4}${b(options)}`, 'g')
;
ip.v6 = (options)=>options && options.exact ? v6exact : new RegExp(`${b(options)}${v6}${b(options)}`, 'g')
;
module.exports = ip;

},{}],"g3mCQ":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var bases = require('./util/bases.js');
function toString(array, encoding = 'utf8') {
    const base = bases[encoding];
    if (!base) throw new Error(`Unsupported encoding "${encoding}"`);
    return base.encoder.encode(array).substring(1);
}
exports.toString = toString;

},{"./util/bases.js":"cV2Md"}],"5rCcx":[function(require,module,exports) {
'use strict';
/** @typedef {import("./types").Protocol} Protocol */ /**
 * Protocols
 *
 * @param {number | string} proto
 * @returns {Protocol}
 */ function Protocols(proto) {
    if (typeof proto === 'number') {
        if (Protocols.codes[proto]) return Protocols.codes[proto];
        throw new Error('no protocol with code: ' + proto);
    } else if (typeof proto === 'string') {
        if (Protocols.names[proto]) return Protocols.names[proto];
        throw new Error('no protocol with name: ' + proto);
    }
    throw new Error('invalid protocol id type: ' + proto);
}
const V = -1;
Protocols.lengthPrefixedVarSize = V;
Protocols.V = V;
/** @type {Array<[number, number, string, (string|boolean)?, string?]>} */ Protocols.table = [
    [
        4,
        32,
        'ip4'
    ],
    [
        6,
        16,
        'tcp'
    ],
    [
        33,
        16,
        'dccp'
    ],
    [
        41,
        128,
        'ip6'
    ],
    [
        42,
        V,
        'ip6zone'
    ],
    [
        53,
        V,
        'dns',
        'resolvable'
    ],
    [
        54,
        V,
        'dns4',
        'resolvable'
    ],
    [
        55,
        V,
        'dns6',
        'resolvable'
    ],
    [
        56,
        V,
        'dnsaddr',
        'resolvable'
    ],
    [
        132,
        16,
        'sctp'
    ],
    [
        273,
        16,
        'udp'
    ],
    [
        275,
        0,
        'p2p-webrtc-star'
    ],
    [
        276,
        0,
        'p2p-webrtc-direct'
    ],
    [
        277,
        0,
        'p2p-stardust'
    ],
    [
        290,
        0,
        'p2p-circuit'
    ],
    [
        301,
        0,
        'udt'
    ],
    [
        302,
        0,
        'utp'
    ],
    [
        400,
        V,
        'unix',
        false,
        'path'
    ],
    // `ipfs` is added before `p2p` for legacy support.
    // All text representations will default to `p2p`, but `ipfs` will
    // still be supported
    [
        421,
        V,
        'ipfs'
    ],
    // `p2p` is the preferred name for 421, and is now the default
    [
        421,
        V,
        'p2p'
    ],
    [
        443,
        0,
        'https'
    ],
    [
        444,
        96,
        'onion'
    ],
    [
        445,
        296,
        'onion3'
    ],
    [
        446,
        V,
        'garlic64'
    ],
    [
        460,
        0,
        'quic'
    ],
    [
        477,
        0,
        'ws'
    ],
    [
        478,
        0,
        'wss'
    ],
    [
        479,
        0,
        'p2p-websocket-star'
    ],
    [
        480,
        0,
        'http'
    ],
    [
        777,
        V,
        'memory'
    ]
];
/** @type {Record<string,Protocol>} */ Protocols.names = {
};
/** @type {Record<number,Protocol>} */ Protocols.codes = {
};
// populate tables
Protocols.table.map((row)=>{
    const proto = p.apply(null, row);
    Protocols.codes[proto.code] = proto;
    Protocols.names[proto.name] = proto;
    return null;
});
Protocols.object = p;
/**
 *
 * Create a protocol
 *
 * @param {number} code
 * @param {number} size
 * @param {string} name
 * @param {any} [resolvable]
 * @param {any} [path]
 * @returns {Protocol}
 */ function p(code, size, name, resolvable, path) {
    return {
        code,
        size,
        name,
        resolvable: Boolean(resolvable),
        path: Boolean(path)
    };
}
module.exports = Protocols;

},{}],"l84uL":[function(require,module,exports) {
module.exports = {
    encode: require('./encode.js'),
    decode: require('./decode.js'),
    encodingLength: require('./length.js')
};

},{"./encode.js":"iVl0f","./decode.js":"aiRfY","./length.js":"3c9Hu"}],"iVl0f":[function(require,module,exports) {
module.exports = encode;
var MSB = 128, REST = 127, MSBALL = ~REST, INT = Math.pow(2, 31);
function encode(num, out, offset) {
    if (Number.MAX_SAFE_INTEGER && num > Number.MAX_SAFE_INTEGER) {
        encode.bytes = 0;
        throw new RangeError('Could not encode varint');
    }
    out = out || [];
    offset = offset || 0;
    var oldOffset = offset;
    while(num >= INT){
        out[offset++] = num & 255 | MSB;
        num /= 128;
    }
    while(num & MSBALL){
        out[offset++] = num & 255 | MSB;
        num >>>= 7;
    }
    out[offset] = num | 0;
    encode.bytes = offset - oldOffset + 1;
    return out;
}

},{}],"aiRfY":[function(require,module,exports) {
module.exports = read;
var MSB = 128, REST = 127;
function read(buf, offset) {
    var res = 0, offset = offset || 0, shift = 0, counter = offset, b, l = buf.length;
    do {
        if (counter >= l || shift > 49) {
            read.bytes = 0;
            throw new RangeError('Could not decode varint');
        }
        b = buf[counter++];
        res += shift < 28 ? (b & REST) << shift : (b & REST) * Math.pow(2, shift);
        shift += 7;
    }while (b >= MSB)
    read.bytes = counter - offset;
    return res;
}

},{}],"3c9Hu":[function(require,module,exports) {
var N1 = Math.pow(2, 7);
var N2 = Math.pow(2, 14);
var N3 = Math.pow(2, 21);
var N4 = Math.pow(2, 28);
var N5 = Math.pow(2, 35);
var N6 = Math.pow(2, 42);
var N7 = Math.pow(2, 49);
var N8 = Math.pow(2, 56);
var N9 = Math.pow(2, 63);
module.exports = function(value) {
    return value < N1 ? 1 : value < N2 ? 2 : value < N3 ? 3 : value < N4 ? 4 : value < N5 ? 5 : value < N6 ? 6 : value < N7 ? 7 : value < N8 ? 8 : value < N9 ? 9 : 10;
};

},{}],"fLIrL":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
function concat(arrays, length) {
    if (!length) length = arrays.reduce((acc, curr)=>acc + curr.length
    , 0);
    const output = new Uint8Array(length);
    let offset = 0;
    for (const arr of arrays){
        output.set(arr, offset);
        offset += arr.length;
    }
    return output;
}
exports.concat = concat;

},{}],"fjLeN":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
function equals(a, b) {
    if (a === b) return true;
    if (a.byteLength !== b.byteLength) return false;
    for(let i = 0; i < a.byteLength; i++){
        if (a[i] !== b[i]) return false;
    }
    return true;
}
exports.equals = equals;

},{}],"hdtcj":[function(require,module,exports) {
'use strict';
const { Multiaddr  } = require('multiaddr');
/**
 * @typedef {import('./types').MatchesFunction} MatchesFunction
 * @typedef {import('./types').PartialMatchesFunction} PartialMatchesFunction
 * @typedef {import('./types').Mafmt} Mafmt
 */ /*
 * Valid combinations
 */ const DNS4 = base('dns4');
const DNS6 = base('dns6');
const DNSADDR = base('dnsaddr');
const DNS = or(base('dns'), DNSADDR, DNS4, DNS6);
const IP = or(base('ip4'), base('ip6'));
const TCP = or(and(IP, base('tcp')), and(DNS, base('tcp')));
const UDP = and(IP, base('udp'));
const UTP = and(UDP, base('utp'));
const QUIC = and(UDP, base('quic'));
const WebSockets = or(and(TCP, base('ws')), and(DNS, base('ws')));
const WebSocketsSecure = or(and(TCP, base('wss')), and(DNS, base('wss')));
const HTTP = or(and(TCP, base('http')), and(IP, base('http')), and(DNS, base('http')));
const HTTPS = or(and(TCP, base('https')), and(IP, base('https')), and(DNS, base('https')));
const WebRTCStar = or(and(WebSockets, base('p2p-webrtc-star'), base('p2p')), and(WebSocketsSecure, base('p2p-webrtc-star'), base('p2p')), and(WebSockets, base('p2p-webrtc-star')), and(WebSocketsSecure, base('p2p-webrtc-star')));
const WebSocketStar = or(and(WebSockets, base('p2p-websocket-star'), base('p2p')), and(WebSocketsSecure, base('p2p-websocket-star'), base('p2p')), and(WebSockets, base('p2p-websocket-star')), and(WebSocketsSecure, base('p2p-websocket-star')));
const WebRTCDirect = or(and(HTTP, base('p2p-webrtc-direct'), base('p2p')), and(HTTPS, base('p2p-webrtc-direct'), base('p2p')), and(HTTP, base('p2p-webrtc-direct')), and(HTTPS, base('p2p-webrtc-direct')));
const Reliable = or(WebSockets, WebSocketsSecure, HTTP, HTTPS, WebRTCStar, WebRTCDirect, TCP, UTP, QUIC, DNS);
// Unlike ws-star, stardust can run over any transport thus removing the requirement for websockets (but don't even think about running a stardust server over webrtc-star ;) )
const Stardust = or(and(Reliable, base('p2p-stardust'), base('p2p')), and(Reliable, base('p2p-stardust')));
const _P2P = or(and(Reliable, base('p2p')), WebRTCStar, WebRTCDirect, base('p2p'));
const _Circuit = or(and(_P2P, base('p2p-circuit'), _P2P), and(_P2P, base('p2p-circuit')), and(base('p2p-circuit'), _P2P), and(Reliable, base('p2p-circuit')), and(base('p2p-circuit'), Reliable), base('p2p-circuit'));
const CircuitRecursive = ()=>or(and(_Circuit, CircuitRecursive), _Circuit)
;
const Circuit = CircuitRecursive();
const P2P = or(and(Circuit, _P2P, Circuit), and(_P2P, Circuit), and(Circuit, _P2P), Circuit, _P2P);
module.exports = {
    DNS,
    DNS4,
    DNS6,
    DNSADDR,
    IP,
    TCP,
    UDP,
    QUIC,
    UTP,
    HTTP,
    HTTPS,
    WebSockets,
    WebSocketsSecure,
    WebSocketStar,
    WebRTCStar,
    WebRTCDirect,
    Reliable,
    Stardust,
    Circuit,
    P2P,
    IPFS: P2P
};
/*
 * Validation funcs
 */ /**
 * @param {PartialMatchesFunction} partialMatch
 */ function makeMatchesFunction(partialMatch) {
    /**
   * @type {MatchesFunction}
   */ function matches(a) {
        if (!Multiaddr.isMultiaddr(a)) try {
            a = new Multiaddr(a);
        } catch (err) {
            return false // also if it's invalid it's propably not matching as well so return false
            ;
        }
        const out = partialMatch(a.protoNames());
        if (out === null) return false;
        if (out === true || out === false) return out;
        return out.length === 0;
    }
    return matches;
}
/**
 * @param {Array<Mafmt | (() => Mafmt)>} args
 * @returns {Mafmt}
 */ function and(...args) {
    /**
   * @type {PartialMatchesFunction}
   */ function partialMatch(a) {
        if (a.length < args.length) return null;
        /** @type {boolean | string[] | null} */ let out = a;
        args.some((arg)=>{
            out = typeof arg === 'function' ? arg().partialMatch(a) : arg.partialMatch(a);
            if (Array.isArray(out)) a = out;
            if (out === null) return true;
            return false;
        });
        return out;
    }
    return {
        toString: function() {
            return '{ ' + args.join(' ') + ' }';
        },
        input: args,
        matches: makeMatchesFunction(partialMatch),
        partialMatch: partialMatch
    };
}
/**
 * @param {Array<Mafmt | (() => Mafmt)>} args
 * @returns {Mafmt}
 */ function or(...args) {
    /**
   * @type {PartialMatchesFunction}
   */ function partialMatch(a) {
        let out = null;
        args.some((arg)=>{
            const res = typeof arg === 'function' ? arg().partialMatch(a) : arg.partialMatch(a);
            if (res) {
                out = res;
                return true;
            }
            return false;
        });
        return out;
    }
    const result = {
        toString: function() {
            return '{ ' + args.join(' ') + ' }';
        },
        input: args,
        matches: makeMatchesFunction(partialMatch),
        partialMatch: partialMatch
    };
    return result;
}
/**
 * @param {string} n
 * @returns {Mafmt}
 */ function base(n) {
    const name = n;
    /**
   * @type {MatchesFunction}
   */ function matches(a) {
        let ma;
        if (typeof a === 'string' || a instanceof Uint8Array) try {
            ma = new Multiaddr(a);
        } catch (err) {
            return false // also if it's invalid it's probably not matching as well so return false
            ;
        }
        else ma = a;
        const pnames = ma.protoNames();
        if (pnames.length === 1 && pnames[0] === name) return true;
        return false;
    }
    /**
   * @type {PartialMatchesFunction}
   */ function partialMatch(protos) {
        if (protos.length === 0) return null;
        if (protos[0] === name) return protos.slice(1);
        return null;
    }
    return {
        toString: function() {
            return name;
        },
        matches: matches,
        partialMatch: partialMatch
    };
}

},{"multiaddr":"kOPrF"}],"9XZNu":[function(require,module,exports) {
'use strict';
const { URLWithLegacySupport , format , URLSearchParams , defaultBase  } = require('./src/url');
const relative = require('./src/relative');
module.exports = {
    URL: URLWithLegacySupport,
    URLSearchParams,
    format,
    relative,
    defaultBase
};

},{"./src/url":"NeWTv","./src/relative":"bgTgh"}],"NeWTv":[function(require,module,exports) {
'use strict';
const isReactNative = typeof navigator !== 'undefined' && navigator.product === 'ReactNative';
function getDefaultBase() {
    if (isReactNative) return 'http://localhost';
    // in some environments i.e. cloudflare workers location is not available
    if (!self.location) return '';
    return self.location.protocol + '//' + self.location.host;
}
const URL = self.URL;
const defaultBase = getDefaultBase();
class URLWithLegacySupport {
    constructor(url1 = '', base = defaultBase){
        this.super = new URL(url1, base);
        this.path = this.pathname + this.search;
        this.auth = this.username && this.password ? this.username + ':' + this.password : null;
        this.query = this.search && this.search.startsWith('?') ? this.search.slice(1) : null;
    }
    get hash() {
        return this.super.hash;
    }
    get host() {
        return this.super.host;
    }
    get hostname() {
        return this.super.hostname;
    }
    get href() {
        return this.super.href;
    }
    get origin() {
        return this.super.origin;
    }
    get password() {
        return this.super.password;
    }
    get pathname() {
        return this.super.pathname;
    }
    get port() {
        return this.super.port;
    }
    get protocol() {
        return this.super.protocol;
    }
    get search() {
        return this.super.search;
    }
    get searchParams() {
        return this.super.searchParams;
    }
    get username() {
        return this.super.username;
    }
    set hash(hash1) {
        this.super.hash = hash1;
    }
    set host(host1) {
        this.super.host = host1;
    }
    set hostname(hostname1) {
        this.super.hostname = hostname1;
    }
    set href(href) {
        this.super.href = href;
    }
    set password(password) {
        this.super.password = password;
    }
    set pathname(pathname1) {
        this.super.pathname = pathname1;
    }
    set port(port1) {
        this.super.port = port1;
    }
    set protocol(protocol1) {
        this.super.protocol = protocol1;
    }
    set search(search1) {
        this.super.search = search1;
    }
    set username(username) {
        this.super.username = username;
    }
    /**
   * @param {any} o
   */ static createObjectURL(o) {
        return URL.createObjectURL(o);
    }
    /**
   * @param {string} o
   */ static revokeObjectURL(o1) {
        URL.revokeObjectURL(o1);
    }
    toJSON() {
        return this.super.toJSON();
    }
    toString() {
        return this.super.toString();
    }
    format() {
        return this.toString();
    }
}
/**
 * @param {string | import('url').UrlObject} obj
 */ function format(obj) {
    if (typeof obj === 'string') {
        const url = new URL(obj);
        return url.toString();
    }
    if (!(obj instanceof URL)) {
        const userPass = // @ts-ignore its not supported in node but we normalise
        obj.username && obj.password ? `${obj.username}:${obj.password}@` : '';
        const auth = obj.auth ? obj.auth + '@' : '';
        const port = obj.port ? ':' + obj.port : '';
        const protocol = obj.protocol ? obj.protocol + '//' : '';
        const host = obj.host || '';
        const hostname = obj.hostname || '';
        const search = obj.search || (obj.query ? '?' + obj.query : '');
        const hash = obj.hash || '';
        const pathname = obj.pathname || '';
        // @ts-ignore - path is not supported in node but we normalise
        const path = obj.path || pathname + search;
        return `${protocol}${userPass || auth}${host || hostname + port}${path}${hash}`;
    }
}
module.exports = {
    URLWithLegacySupport,
    URLSearchParams: self.URLSearchParams,
    defaultBase,
    format
};

},{}],"bgTgh":[function(require,module,exports) {
'use strict';
const { URLWithLegacySupport , format  } = require('./url');
/**
 * @param {string | undefined} url
 * @param {any} [location]
 * @param {any} [protocolMap]
 * @param {any} [defaultProtocol]
 */ module.exports = (url, location = {
}, protocolMap = {
}, defaultProtocol)=>{
    let protocol = location.protocol ? location.protocol.replace(':', '') : 'http';
    // Check protocol map
    protocol = (protocolMap[protocol] || defaultProtocol || protocol) + ':';
    let urlParsed;
    try {
        urlParsed = new URLWithLegacySupport(url);
    } catch (err) {
        urlParsed = {
        };
    }
    const base = Object.assign({
    }, location, {
        protocol: protocol || urlParsed.protocol,
        host: location.host || urlParsed.host
    });
    return new URLWithLegacySupport(url, format(base)).toString();
};

},{"./url":"NeWTv"}],"ccQWS":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var nanoid = require('nanoid');
var toString = require('uint8arrays/to-string');
var fromString = require('uint8arrays/from-string');
const pathSepS = '/';
const pathSepB = new TextEncoder().encode(pathSepS);
const pathSep = pathSepB[0];
class Key {
    constructor(s, clean){
        if (typeof s === 'string') this._buf = fromString.fromString(s);
        else if (s instanceof Uint8Array) this._buf = s;
        else throw new Error('Invalid key, should be String of Uint8Array');
        if (clean == null) clean = true;
        if (clean) this.clean();
        if (this._buf.byteLength === 0 || this._buf[0] !== pathSep) throw new Error('Invalid key');
    }
    toString(encoding = 'utf8') {
        return toString.toString(this._buf, encoding);
    }
    uint8Array() {
        return this._buf;
    }
    get [Symbol.toStringTag]() {
        return `Key(${this.toString()})`;
    }
    static withNamespaces(list) {
        return new Key(list.join(pathSepS));
    }
    static random() {
        return new Key(nanoid.nanoid().replace(/-/g, ''));
    }
    static asKey(other) {
        if (other instanceof Uint8Array || typeof other === 'string') return new Key(other);
        if (other.uint8Array) return new Key(other.uint8Array());
        return null;
    }
    clean() {
        if (!this._buf || this._buf.byteLength === 0) this._buf = pathSepB;
        if (this._buf[0] !== pathSep) {
            const bytes = new Uint8Array(this._buf.byteLength + 1);
            bytes.fill(pathSep, 0, 1);
            bytes.set(this._buf, 1);
            this._buf = bytes;
        }
        while(this._buf.byteLength > 1 && this._buf[this._buf.byteLength - 1] === pathSep)this._buf = this._buf.subarray(0, -1);
    }
    less(key2) {
        const list1 = this.list();
        const list2 = key2.list();
        for(let i = 0; i < list1.length; i++){
            if (list2.length < i + 1) return false;
            const c1 = list1[i];
            const c2 = list2[i];
            if (c1 < c2) return true;
            else if (c1 > c2) return false;
        }
        return list1.length < list2.length;
    }
    reverse() {
        return Key.withNamespaces(this.list().slice().reverse());
    }
    namespaces() {
        return this.list();
    }
    baseNamespace() {
        const ns = this.namespaces();
        return ns[ns.length - 1];
    }
    list() {
        return this.toString().split(pathSepS).slice(1);
    }
    type() {
        return namespaceType(this.baseNamespace());
    }
    name() {
        return namespaceValue(this.baseNamespace());
    }
    instance(s1) {
        return new Key(this.toString() + ':' + s1);
    }
    path() {
        let p = this.parent().toString();
        if (!p.endsWith(pathSepS)) p += pathSepS;
        p += this.type();
        return new Key(p);
    }
    parent() {
        const list = this.list();
        if (list.length === 1) return new Key(pathSepS);
        return new Key(list.slice(0, -1).join(pathSepS));
    }
    child(key1) {
        if (this.toString() === pathSepS) return key1;
        else if (key1.toString() === pathSepS) return this;
        return new Key(this.toString() + key1.toString(), false);
    }
    isAncestorOf(other1) {
        if (other1.toString() === this.toString()) return false;
        return other1.toString().startsWith(this.toString());
    }
    isDecendantOf(other2) {
        if (other2.toString() === this.toString()) return false;
        return this.toString().startsWith(other2.toString());
    }
    isTopLevel() {
        return this.list().length === 1;
    }
    concat(...keys) {
        return Key.withNamespaces([
            ...this.namespaces(),
            ...flatten(keys.map((key)=>key.namespaces()
            ))
        ]);
    }
}
function namespaceType(ns) {
    const parts = ns.split(':');
    if (parts.length < 2) return '';
    return parts.slice(0, -1).join(':');
}
function namespaceValue(ns) {
    const parts = ns.split(':');
    return parts[parts.length - 1];
}
function flatten(arr) {
    return [].concat(...arr);
}
exports.Key = Key;

},{"nanoid":"4OOvb","uint8arrays/to-string":"g3mCQ","uint8arrays/from-string":"lo45E"}],"4OOvb":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "nanoid", ()=>nanoid
);
parcelHelpers.export(exports, "customAlphabet", ()=>customAlphabet
);
parcelHelpers.export(exports, "customRandom", ()=>customRandom
);
parcelHelpers.export(exports, "urlAlphabet", ()=>_indexJs.urlAlphabet
);
parcelHelpers.export(exports, "random", ()=>random
);
var _indexJs = require("./url-alphabet/index.js");
if (typeof navigator !== 'undefined' && navigator.product === 'ReactNative' && typeof crypto === 'undefined') throw new Error("React Native does not have a built-in secure random generator. If you don’t need unpredictable IDs use `nanoid/non-secure`. For secure IDs, import `react-native-get-random-values` before Nano ID.");
if (typeof msCrypto !== 'undefined' && typeof crypto === 'undefined') throw new Error("Import file with `if (!window.crypto) window.crypto = window.msCrypto` before importing Nano ID to fix IE 11 support");
if (typeof crypto === 'undefined') throw new Error("Your browser does not have secure random generator. If you don’t need unpredictable IDs, you can use nanoid/non-secure.");
let random = (bytes)=>crypto.getRandomValues(new Uint8Array(bytes))
;
let customRandom = (alphabet, size, getRandom)=>{
    let mask = (2 << Math.log(alphabet.length - 1) / Math.LN2) - 1;
    let step = -~(1.6 * mask * size / alphabet.length);
    return ()=>{
        let id = '';
        while(true){
            let bytes = getRandom(step);
            let j = step;
            while(j--){
                id += alphabet[bytes[j] & mask] || '';
                if (id.length === size) return id;
            }
        }
    };
};
let customAlphabet = (alphabet, size)=>customRandom(alphabet, size, random)
;
let nanoid = (size = 21)=>{
    let id = '';
    let bytes = crypto.getRandomValues(new Uint8Array(size));
    while(size--){
        let byte = bytes[size] & 63;
        if (byte < 36) id += byte.toString(36);
        else if (byte < 62) id += (byte - 26).toString(36).toUpperCase();
        else if (byte < 63) id += '_';
        else id += '-';
    }
    return id;
};

},{"./url-alphabet/index.js":"iiQl7","@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"iiQl7":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "urlAlphabet", ()=>urlAlphabet
);
let urlAlphabet = 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict';

},{"@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"ciiiV":[function(require,module,exports) {
exports.interopDefault = function(a) {
    return a && a.__esModule ? a : {
        default: a
    };
};
exports.defineInteropFlag = function(a) {
    Object.defineProperty(a, '__esModule', {
        value: true
    });
};
exports.exportAll = function(source, dest) {
    Object.keys(source).forEach(function(key) {
        if (key === 'default' || key === '__esModule' || dest.hasOwnProperty(key)) return;
        Object.defineProperty(dest, key, {
            enumerable: true,
            get: function() {
                return source[key];
            }
        });
    });
    return dest;
};
exports.export = function(dest, destName, get) {
    Object.defineProperty(dest, destName, {
        enumerable: true,
        get: get
    });
};

},{}],"5AiVw":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var TimeoutController = require('timeout-abort-controller');
var anySignal = require('any-signal');
var parseDuration = require('parse-duration');
var errors = require('./errors.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var TimeoutController__default = /*#__PURE__*/ _interopDefaultLegacy(TimeoutController);
var parseDuration__default = /*#__PURE__*/ _interopDefaultLegacy(parseDuration);
function withTimeoutOption(fn, optionsArgIndex) {
    return (...args)=>{
        const options = args[optionsArgIndex == null ? args.length - 1 : optionsArgIndex];
        if (!options || !options.timeout) return fn(...args);
        const timeout = typeof options.timeout === 'string' ? parseDuration__default['default'](options.timeout) : options.timeout;
        const controller = new TimeoutController__default['default'](timeout);
        options.signal = anySignal.anySignal([
            options.signal,
            controller.signal
        ]);
        const fnRes = fn(...args);
        const timeoutPromise = new Promise((_resolve, reject)=>{
            controller.signal.addEventListener('abort', ()=>{
                reject(new errors.TimeoutError());
            });
        });
        const start = Date.now();
        const maybeThrowTimeoutError = ()=>{
            if (controller.signal.aborted) throw new errors.TimeoutError();
            const timeTaken = Date.now() - start;
            if (timeTaken > timeout) {
                controller.abort();
                throw new errors.TimeoutError();
            }
        };
        if (fnRes[Symbol.asyncIterator]) return (async function*() {
            const it = fnRes[Symbol.asyncIterator]();
            try {
                while(true){
                    const { value , done  } = await Promise.race([
                        it.next(),
                        timeoutPromise
                    ]);
                    if (done) break;
                    maybeThrowTimeoutError();
                    yield value;
                }
            } catch (err) {
                maybeThrowTimeoutError();
                throw err;
            } finally{
                controller.clear();
                if (it.return) it.return();
            }
        })();
        return (async ()=>{
            try {
                const res = await Promise.race([
                    fnRes,
                    timeoutPromise
                ]);
                maybeThrowTimeoutError();
                return res;
            } catch (err) {
                maybeThrowTimeoutError();
                throw err;
            } finally{
                controller.clear();
            }
        })();
    };
}
exports.withTimeoutOption = withTimeoutOption;

},{"timeout-abort-controller":"gYeUY","any-signal":"1586s","parse-duration":"2Fbu7","./errors.js":"9uikE"}],"gYeUY":[function(require,module,exports) {
/* globals self, window */ 'use strict';
// Get around https://github.com/mysticatea/abort-controller/pull/22
const { AbortController  } = typeof self !== 'undefined' ? self : typeof window !== 'undefined' ? window : require('abort-controller');
const retimer = require('retimer');
class TimeoutController extends AbortController {
    /**
   * @constructor
   * @param {number} ms milliseconds
   */ constructor(ms){
        super();
        this._ms = ms;
        this._timer = retimer(()=>this.abort()
        , ms);
        // Patch for safari not supported extending built in classes
        Object.setPrototypeOf(this, TimeoutController.prototype);
    }
    /**
   * Aborts the controller and clears the timer
   */ abort() {
        this._timer.clear();
        return super.abort();
    }
    /**
   * Clears the timer
   */ clear() {
        this._timer.clear();
    }
    /**
   * Resets the timer
   */ reset() {
        this._timer.clear();
        this._timer = retimer(()=>this.abort()
        , this._ms);
    }
}
module.exports = TimeoutController;
module.exports.TimeoutController = TimeoutController;

},{"abort-controller":"hVuZx","retimer":"lUaGE"}],"hVuZx":[function(require,module,exports) {
/*globals self, window */ "use strict";
/*eslint-disable @mysticatea/prettier */ const { AbortController , AbortSignal  } = typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : /* otherwise */ undefined;
/*eslint-enable @mysticatea/prettier */ module.exports = AbortController;
module.exports.AbortSignal = AbortSignal;
module.exports.default = AbortController;

},{}],"lUaGE":[function(require,module,exports) {
'use strict';
var getTime = require('./time');
function Retimer(callback, timeout, args) {
    var that = this;
    this._started = getTime();
    this._rescheduled = 0;
    this._scheduled = timeout;
    this._args = args;
    this._timer = setTimeout(timerWrapper, timeout);
    function timerWrapper() {
        if (that._rescheduled > 0) {
            that._scheduled = that._rescheduled - (getTime() - that._started);
            that._timer = setTimeout(timerWrapper, that._scheduled);
            that._rescheduled = 0;
        } else callback.apply(null, that._args);
    }
}
Retimer.prototype.reschedule = function(timeout) {
    var now = getTime();
    if (now + timeout - (this._started + this._scheduled) < 0) return false;
    else {
        this._started = now;
        this._rescheduled = timeout;
        return true;
    }
};
Retimer.prototype.clear = function() {
    clearTimeout(this._timer);
};
function retimer() {
    if (typeof arguments[0] !== 'function') throw new Error('callback needed');
    if (typeof arguments[1] !== 'number') throw new Error('timeout needed');
    var args;
    if (arguments.length > 0) {
        args = new Array(arguments.length - 2);
        for(var i = 0; i < args.length; i++)args[i] = arguments[i + 2];
    }
    return new Retimer(arguments[0], arguments[1], args);
}
module.exports = retimer;

},{"./time":"34YoM"}],"34YoM":[function(require,module,exports) {
'use strict';
module.exports = function getTime() {
    return Date.now();
};

},{}],"1586s":[function(require,module,exports) {
const { AbortController  } = require('native-abort-controller');
/**
 * Takes an array of AbortSignals and returns a single signal.
 * If any signals are aborted, the returned signal will be aborted.
 * @param {Array<AbortSignal>} signals
 * @returns {AbortSignal}
 */ function anySignal(signals) {
    const controller = new AbortController();
    function onAbort() {
        controller.abort();
        for (const signal of signals){
            if (!signal || !signal.removeEventListener) continue;
            signal.removeEventListener('abort', onAbort);
        }
    }
    for (const signal1 of signals){
        if (!signal1 || !signal1.addEventListener) continue;
        if (signal1.aborted) {
            onAbort();
            break;
        }
        signal1.addEventListener('abort', onAbort);
    }
    return controller.signal;
}
module.exports = anySignal;
module.exports.anySignal = anySignal;

},{"native-abort-controller":"9z1Uk"}],"9z1Uk":[function(require,module,exports) {
'use strict';
let impl;
if (globalThis.AbortController && globalThis.AbortSignal) impl = globalThis;
else impl = require('abort-controller');
module.exports.AbortSignal = impl.AbortSignal;
module.exports.AbortController = impl.AbortController;

},{"abort-controller":"hVuZx"}],"2Fbu7":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
let durationRE = /(-?(?:\d+\.?\d*|\d*\.?\d+)(?:e[-+]?\d+)?)\s*([\p{L}]*)/uig;
/**
 * conversion ratios
 */ parse.nanosecond = parse.ns = 1 / 1000000;
parse['µs'] = parse['μs'] = parse.us = parse.microsecond = 0.001;
parse.millisecond = parse.ms = parse[''] = 1;
parse.second = parse.sec = parse.s = parse.ms * 1000;
parse.minute = parse.min = parse.m = parse.s * 60;
parse.hour = parse.hr = parse.h = parse.m * 60;
parse.day = parse.d = parse.h * 24;
parse.week = parse.wk = parse.w = parse.d * 7;
parse.month = parse.b = parse.d * 30.4375;
parse.year = parse.yr = parse.y = parse.d * 365.25;
/**
 * convert `str` to ms
 *
 * @param {String} str
 * @param {String} format
 * @return {Number}
 */ function parse(str = '', format = 'ms') {
    var result = null;
    // ignore commas/placeholders
    str = (str + '').replace(/(\d)[,_](\d)/g, '$1$2');
    str.replace(durationRE, function(_, n, units) {
        units = unitRatio(units);
        if (units) result = (result || 0) + parseFloat(n, 10) * units;
    });
    return result && result / (unitRatio(format) || 1);
}
function unitRatio(str) {
    return parse[str] || parse[str.toLowerCase().replace(/s$/, '')];
}
exports.default = parse;

},{"@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"9uikE":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
class TimeoutError extends Error {
    constructor(message = 'request timed out'){
        super(message);
        this.name = 'TimeoutError';
        this.code = TimeoutError.code;
    }
}
TimeoutError.code = 'ERR_TIMEOUT';
exports.TimeoutError = TimeoutError;

},{}],"5zZPz":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
var errCode = require('err-code');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
const IPFS_PREFIX = '/ipfs/';
function toCidAndPath(string) {
    if (string instanceof Uint8Array) try {
        string = cid.CID.decode(string);
    } catch (err) {
        throw errCode__default['default'](err, 'ERR_INVALID_CID');
    }
    let cid$1 = cid.CID.asCID(string);
    if (cid$1) return {
        cid: cid$1,
        path: undefined
    };
    string = string.toString();
    if (string.startsWith(IPFS_PREFIX)) string = string.substring(IPFS_PREFIX.length);
    const parts = string.split('/');
    let path;
    try {
        cid$1 = cid.CID.parse(parts.shift() || '');
    } catch (err1) {
        throw errCode__default['default'](err1, 'ERR_INVALID_CID');
    }
    if (parts.length) path = `/${parts.join('/')}`;
    return {
        cid: cid$1,
        path
    };
}
exports.toCidAndPath = toCidAndPath;

},{"multiformats/cid":"fJJnW","err-code":"eQvyh"}],"l8lhl":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var service = require('../utils/service.js');
function createStop({ network , preload , ipns , repo , mfsPreload  }) {
    const stop = async ()=>{
        await Promise.all([
            preload.stop(),
            ipns.stop(),
            mfsPreload.stop(),
            service.Service.stop(network),
            repo.close()
        ]);
    };
    return stop;
}
exports.createStop = createStop;

},{"../utils/service.js":"e1v7I"}],"lSUS4":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var dns = require('ipfs-core-config/dns');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function fqdnFixups(domain) {
    if (domain.endsWith('.eth')) domain = domain.replace(/.eth$/, '.eth.link');
    return domain;
}
function createDns() {
    const resolveDNS = async (domain, options = {
        recursive: true
    })=>{
        if (typeof domain !== 'string') throw new Error('Invalid arguments, domain must be a string');
        domain = fqdnFixups(domain);
        return dns.resolveDnslink(domain, options);
    };
    return withTimeoutOption.withTimeoutOption(resolveDNS);
}
exports.createDns = createDns;

},{"ipfs-core-config/dns":"g5cNG","ipfs-core-utils/with-timeout-option":"5AiVw"}],"g5cNG":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var tlru = require('./utils/tlru.js');
var PQueue = require('p-queue');
var HTTP = require('ipfs-utils/src/http.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var PQueue__default = /*#__PURE__*/ _interopDefaultLegacy(PQueue);
var HTTP__default = /*#__PURE__*/ _interopDefaultLegacy(HTTP);
const cache = new tlru.TLRU(1000);
const ttl = 60000;
const Queue = PQueue__default["default"].default ? PQueue__default["default"].default : PQueue__default["default"];
const httpQueue = new Queue({
    concurrency: 4
});
const ipfsPath = (response)=>{
    if (response.Path) return response.Path;
    throw new Error(response.Message);
};
async function resolveDnslink(fqdn1, opts1) {
    const resolve = async (fqdn, opts = {
    })=>{
        const searchParams = new URLSearchParams(opts);
        searchParams.set('arg', fqdn);
        const query1 = searchParams.toString();
        if (!opts.nocache && cache.has(query1)) {
            const response = cache.get(query1);
            return ipfsPath(response);
        }
        const response = await httpQueue.add(async ()=>{
            const res = await HTTP__default["default"].get('https://ipfs.io/api/v0/dns', {
                searchParams
            });
            const query = new URL(res.url).search.slice(1);
            const json = await res.json();
            cache.set(query, json, ttl);
            return json;
        });
        return ipfsPath(response);
    };
    return resolve(fqdn1, opts1);
}
exports.resolveDnslink = resolveDnslink;

},{"./utils/tlru.js":"5ny6p","p-queue":"ccCVf","ipfs-utils/src/http.js":"2w2r7"}],"5ny6p":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var hashlru = require('hashlru');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var hashlru__default = /*#__PURE__*/ _interopDefaultLegacy(hashlru);
class TLRU {
    constructor(maxSize){
        this.lru = hashlru__default["default"](maxSize);
    }
    get(key) {
        const value = this.lru.get(key);
        if (value) {
            if (value.expire && value.expire < Date.now()) {
                this.lru.remove(key);
                return undefined;
            }
            return value.value;
        }
        return undefined;
    }
    set(key1, value, ttl) {
        this.lru.set(key1, {
            value,
            expire: Date.now() + ttl
        });
    }
    has(key2) {
        const value = this.get(key2);
        if (value) return true;
        return false;
    }
    remove(key3) {
        this.lru.remove(key3);
    }
    clear() {
        this.lru.clear();
    }
}
exports.TLRU = TLRU;

},{"hashlru":"fzwAb"}],"fzwAb":[function(require,module,exports) {
module.exports = function(max) {
    if (!max) throw Error('hashlru must have a max value, of type number, greater than 0');
    var size = 0, cache = Object.create(null), _cache = Object.create(null);
    function update(key, value) {
        cache[key] = value;
        size++;
        if (size >= max) {
            size = 0;
            _cache = cache;
            cache = Object.create(null);
        }
    }
    return {
        has: function(key) {
            return cache[key] !== undefined || _cache[key] !== undefined;
        },
        remove: function(key) {
            if (cache[key] !== undefined) cache[key] = undefined;
            if (_cache[key] !== undefined) _cache[key] = undefined;
        },
        get: function(key) {
            var v = cache[key];
            if (v !== undefined) return v;
            if ((v = _cache[key]) !== undefined) {
                update(key, v);
                return v;
            }
        },
        set: function(key, value) {
            if (cache[key] !== undefined) cache[key] = value;
            else update(key, value);
        },
        clear: function() {
            cache = Object.create(null);
            _cache = Object.create(null);
        }
    };
};

},{}],"ccCVf":[function(require,module,exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
const EventEmitter = require("eventemitter3");
const p_timeout_1 = require("p-timeout");
const priority_queue_1 = require("./priority-queue");
// eslint-disable-next-line @typescript-eslint/no-empty-function
const empty = ()=>{
};
const timeoutError = new p_timeout_1.TimeoutError();
/**
Promise queue with concurrency control.
*/ class PQueue extends EventEmitter {
    constructor(options){
        var _a, _b, _c, _d;
        super();
        this._intervalCount = 0;
        this._intervalEnd = 0;
        this._pendingCount = 0;
        this._resolveEmpty = empty;
        this._resolveIdle = empty;
        // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
        options = Object.assign({
            carryoverConcurrencyCount: false,
            intervalCap: Infinity,
            interval: 0,
            concurrency: Infinity,
            autoStart: true,
            queueClass: priority_queue_1.default
        }, options);
        if (!(typeof options.intervalCap === 'number' && options.intervalCap >= 1)) throw new TypeError(`Expected \`intervalCap\` to be a number from 1 and up, got \`${(_b = (_a = options.intervalCap) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : ''}\` (${typeof options.intervalCap})`);
        if (options.interval === undefined || !(Number.isFinite(options.interval) && options.interval >= 0)) throw new TypeError(`Expected \`interval\` to be a finite number >= 0, got \`${(_d = (_c = options.interval) === null || _c === void 0 ? void 0 : _c.toString()) !== null && _d !== void 0 ? _d : ''}\` (${typeof options.interval})`);
        this._carryoverConcurrencyCount = options.carryoverConcurrencyCount;
        this._isIntervalIgnored = options.intervalCap === Infinity || options.interval === 0;
        this._intervalCap = options.intervalCap;
        this._interval = options.interval;
        this._queue = new options.queueClass();
        this._queueClass = options.queueClass;
        this.concurrency = options.concurrency;
        this._timeout = options.timeout;
        this._throwOnTimeout = options.throwOnTimeout === true;
        this._isPaused = options.autoStart === false;
    }
    get _doesIntervalAllowAnother() {
        return this._isIntervalIgnored || this._intervalCount < this._intervalCap;
    }
    get _doesConcurrentAllowAnother() {
        return this._pendingCount < this._concurrency;
    }
    _next() {
        this._pendingCount--;
        this._tryToStartAnother();
        this.emit('next');
    }
    _resolvePromises() {
        this._resolveEmpty();
        this._resolveEmpty = empty;
        if (this._pendingCount === 0) {
            this._resolveIdle();
            this._resolveIdle = empty;
            this.emit('idle');
        }
    }
    _onResumeInterval() {
        this._onInterval();
        this._initializeIntervalIfNeeded();
        this._timeoutId = undefined;
    }
    _isIntervalPaused() {
        const now = Date.now();
        if (this._intervalId === undefined) {
            const delay = this._intervalEnd - now;
            if (delay < 0) // Act as the interval was done
            // We don't need to resume it here because it will be resumed on line 160
            this._intervalCount = this._carryoverConcurrencyCount ? this._pendingCount : 0;
            else {
                // Act as the interval is pending
                if (this._timeoutId === undefined) this._timeoutId = setTimeout(()=>{
                    this._onResumeInterval();
                }, delay);
                return true;
            }
        }
        return false;
    }
    _tryToStartAnother() {
        if (this._queue.size === 0) {
            // We can clear the interval ("pause")
            // Because we can redo it later ("resume")
            if (this._intervalId) clearInterval(this._intervalId);
            this._intervalId = undefined;
            this._resolvePromises();
            return false;
        }
        if (!this._isPaused) {
            const canInitializeInterval = !this._isIntervalPaused();
            if (this._doesIntervalAllowAnother && this._doesConcurrentAllowAnother) {
                const job = this._queue.dequeue();
                if (!job) return false;
                this.emit('active');
                job();
                if (canInitializeInterval) this._initializeIntervalIfNeeded();
                return true;
            }
        }
        return false;
    }
    _initializeIntervalIfNeeded() {
        if (this._isIntervalIgnored || this._intervalId !== undefined) return;
        this._intervalId = setInterval(()=>{
            this._onInterval();
        }, this._interval);
        this._intervalEnd = Date.now() + this._interval;
    }
    _onInterval() {
        if (this._intervalCount === 0 && this._pendingCount === 0 && this._intervalId) {
            clearInterval(this._intervalId);
            this._intervalId = undefined;
        }
        this._intervalCount = this._carryoverConcurrencyCount ? this._pendingCount : 0;
        this._processQueue();
    }
    /**
    Executes all queued functions until it reaches the limit.
    */ _processQueue() {
        // eslint-disable-next-line no-empty
        while(this._tryToStartAnother());
    }
    get concurrency() {
        return this._concurrency;
    }
    set concurrency(newConcurrency) {
        if (!(typeof newConcurrency === 'number' && newConcurrency >= 1)) throw new TypeError(`Expected \`concurrency\` to be a number from 1 and up, got \`${newConcurrency}\` (${typeof newConcurrency})`);
        this._concurrency = newConcurrency;
        this._processQueue();
    }
    /**
    Adds a sync or async task to the queue. Always returns a promise.
    */ async add(fn, options1 = {
    }) {
        return new Promise((resolve, reject)=>{
            const run = async ()=>{
                this._pendingCount++;
                this._intervalCount++;
                try {
                    const operation = this._timeout === undefined && options1.timeout === undefined ? fn() : p_timeout_1.default(Promise.resolve(fn()), options1.timeout === undefined ? this._timeout : options1.timeout, ()=>{
                        if (options1.throwOnTimeout === undefined ? this._throwOnTimeout : options1.throwOnTimeout) reject(timeoutError);
                        return undefined;
                    });
                    resolve(await operation);
                } catch (error) {
                    reject(error);
                }
                this._next();
            };
            this._queue.enqueue(run, options1);
            this._tryToStartAnother();
            this.emit('add');
        });
    }
    /**
    Same as `.add()`, but accepts an array of sync or async functions.

    @returns A promise that resolves when all functions are resolved.
    */ async addAll(functions, options2) {
        return Promise.all(functions.map(async (function_)=>this.add(function_, options2)
        ));
    }
    /**
    Start (or resume) executing enqueued tasks within concurrency limit. No need to call this if queue is not paused (via `options.autoStart = false` or by `.pause()` method.)
    */ start() {
        if (!this._isPaused) return this;
        this._isPaused = false;
        this._processQueue();
        return this;
    }
    /**
    Put queue execution on hold.
    */ pause() {
        this._isPaused = true;
    }
    /**
    Clear the queue.
    */ clear() {
        this._queue = new this._queueClass();
    }
    /**
    Can be called multiple times. Useful if you for example add additional items at a later time.

    @returns A promise that settles when the queue becomes empty.
    */ async onEmpty() {
        // Instantly resolve if the queue is empty
        if (this._queue.size === 0) return;
        return new Promise((resolve)=>{
            const existingResolve = this._resolveEmpty;
            this._resolveEmpty = ()=>{
                existingResolve();
                resolve();
            };
        });
    }
    /**
    The difference with `.onEmpty` is that `.onIdle` guarantees that all work from the queue has finished. `.onEmpty` merely signals that the queue is empty, but it could mean that some promises haven't completed yet.

    @returns A promise that settles when the queue becomes empty, and all promises have completed; `queue.size === 0 && queue.pending === 0`.
    */ async onIdle() {
        // Instantly resolve if none pending and if nothing else is queued
        if (this._pendingCount === 0 && this._queue.size === 0) return;
        return new Promise((resolve)=>{
            const existingResolve = this._resolveIdle;
            this._resolveIdle = ()=>{
                existingResolve();
                resolve();
            };
        });
    }
    /**
    Size of the queue.
    */ get size() {
        return this._queue.size;
    }
    /**
    Size of the queue, filtered by the given options.

    For example, this can be used to find the number of items remaining in the queue with a specific priority level.
    */ sizeBy(options3) {
        // eslint-disable-next-line unicorn/no-fn-reference-in-iterator
        return this._queue.filter(options3).length;
    }
    /**
    Number of pending promises.
    */ get pending() {
        return this._pendingCount;
    }
    /**
    Whether the queue is currently paused.
    */ get isPaused() {
        return this._isPaused;
    }
    get timeout() {
        return this._timeout;
    }
    /**
    Set the timeout for future operations.
    */ set timeout(milliseconds) {
        this._timeout = milliseconds;
    }
}
exports.default = PQueue;

},{"eventemitter3":"aE2Jy","p-timeout":"i8fSI","./priority-queue":"d6haw"}],"aE2Jy":[function(require,module,exports) {
'use strict';
var has = Object.prototype.hasOwnProperty, prefix = '~';
/**
 * Constructor to create a storage for our `EE` objects.
 * An `Events` instance is a plain object whose properties are event names.
 *
 * @constructor
 * @private
 */ function Events() {
}
//
// We try to not inherit from `Object.prototype`. In some engines creating an
// instance in this way is faster than calling `Object.create(null)` directly.
// If `Object.create(null)` is not supported we prefix the event names with a
// character to make sure that the built-in object properties are not
// overridden or used as an attack vector.
//
if (Object.create) {
    Events.prototype = Object.create(null);
    //
    // This hack is needed because the `__proto__` property is still inherited in
    // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.
    //
    if (!new Events().__proto__) prefix = false;
}
/**
 * Representation of a single event listener.
 *
 * @param {Function} fn The listener function.
 * @param {*} context The context to invoke the listener with.
 * @param {Boolean} [once=false] Specify if the listener is a one-time listener.
 * @constructor
 * @private
 */ function EE(fn, context, once) {
    this.fn = fn;
    this.context = context;
    this.once = once || false;
}
/**
 * Add a listener for a given event.
 *
 * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
 * @param {(String|Symbol)} event The event name.
 * @param {Function} fn The listener function.
 * @param {*} context The context to invoke the listener with.
 * @param {Boolean} once Specify if the listener is a one-time listener.
 * @returns {EventEmitter}
 * @private
 */ function addListener(emitter, event, fn, context, once) {
    if (typeof fn !== 'function') throw new TypeError('The listener must be a function');
    var listener = new EE(fn, context || emitter, once), evt = prefix ? prefix + event : event;
    if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;
    else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);
    else emitter._events[evt] = [
        emitter._events[evt],
        listener
    ];
    return emitter;
}
/**
 * Clear event by name.
 *
 * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
 * @param {(String|Symbol)} evt The Event name.
 * @private
 */ function clearEvent(emitter, evt) {
    if (--emitter._eventsCount === 0) emitter._events = new Events();
    else delete emitter._events[evt];
}
/**
 * Minimal `EventEmitter` interface that is molded against the Node.js
 * `EventEmitter` interface.
 *
 * @constructor
 * @public
 */ function EventEmitter() {
    this._events = new Events();
    this._eventsCount = 0;
}
/**
 * Return an array listing the events for which the emitter has registered
 * listeners.
 *
 * @returns {Array}
 * @public
 */ EventEmitter.prototype.eventNames = function eventNames() {
    var names = [], events, name;
    if (this._eventsCount === 0) return names;
    for(name in events = this._events)if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
    if (Object.getOwnPropertySymbols) return names.concat(Object.getOwnPropertySymbols(events));
    return names;
};
/**
 * Return the listeners registered for a given event.
 *
 * @param {(String|Symbol)} event The event name.
 * @returns {Array} The registered listeners.
 * @public
 */ EventEmitter.prototype.listeners = function listeners(event) {
    var evt = prefix ? prefix + event : event, handlers = this._events[evt];
    if (!handlers) return [];
    if (handlers.fn) return [
        handlers.fn
    ];
    for(var i = 0, l = handlers.length, ee = new Array(l); i < l; i++)ee[i] = handlers[i].fn;
    return ee;
};
/**
 * Return the number of listeners listening to a given event.
 *
 * @param {(String|Symbol)} event The event name.
 * @returns {Number} The number of listeners.
 * @public
 */ EventEmitter.prototype.listenerCount = function listenerCount(event) {
    var evt = prefix ? prefix + event : event, listeners = this._events[evt];
    if (!listeners) return 0;
    if (listeners.fn) return 1;
    return listeners.length;
};
/**
 * Calls each of the listeners registered for a given event.
 *
 * @param {(String|Symbol)} event The event name.
 * @returns {Boolean} `true` if the event had listeners, else `false`.
 * @public
 */ EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
    var evt = prefix ? prefix + event : event;
    if (!this._events[evt]) return false;
    var listeners = this._events[evt], len = arguments.length, args, i;
    if (listeners.fn) {
        if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);
        switch(len){
            case 1:
                return listeners.fn.call(listeners.context), true;
            case 2:
                return listeners.fn.call(listeners.context, a1), true;
            case 3:
                return listeners.fn.call(listeners.context, a1, a2), true;
            case 4:
                return listeners.fn.call(listeners.context, a1, a2, a3), true;
            case 5:
                return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
            case 6:
                return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
        }
        for(i = 1, args = new Array(len - 1); i < len; i++)args[i - 1] = arguments[i];
        listeners.fn.apply(listeners.context, args);
    } else {
        var length = listeners.length, j;
        for(i = 0; i < length; i++){
            if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);
            switch(len){
                case 1:
                    listeners[i].fn.call(listeners[i].context);
                    break;
                case 2:
                    listeners[i].fn.call(listeners[i].context, a1);
                    break;
                case 3:
                    listeners[i].fn.call(listeners[i].context, a1, a2);
                    break;
                case 4:
                    listeners[i].fn.call(listeners[i].context, a1, a2, a3);
                    break;
                default:
                    if (!args) for(j = 1, args = new Array(len - 1); j < len; j++)args[j - 1] = arguments[j];
                    listeners[i].fn.apply(listeners[i].context, args);
            }
        }
    }
    return true;
};
/**
 * Add a listener for a given event.
 *
 * @param {(String|Symbol)} event The event name.
 * @param {Function} fn The listener function.
 * @param {*} [context=this] The context to invoke the listener with.
 * @returns {EventEmitter} `this`.
 * @public
 */ EventEmitter.prototype.on = function on(event, fn, context) {
    return addListener(this, event, fn, context, false);
};
/**
 * Add a one-time listener for a given event.
 *
 * @param {(String|Symbol)} event The event name.
 * @param {Function} fn The listener function.
 * @param {*} [context=this] The context to invoke the listener with.
 * @returns {EventEmitter} `this`.
 * @public
 */ EventEmitter.prototype.once = function once(event, fn, context) {
    return addListener(this, event, fn, context, true);
};
/**
 * Remove the listeners of a given event.
 *
 * @param {(String|Symbol)} event The event name.
 * @param {Function} fn Only remove the listeners that match this function.
 * @param {*} context Only remove the listeners that have this context.
 * @param {Boolean} once Only remove one-time listeners.
 * @returns {EventEmitter} `this`.
 * @public
 */ EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
    var evt = prefix ? prefix + event : event;
    if (!this._events[evt]) return this;
    if (!fn) {
        clearEvent(this, evt);
        return this;
    }
    var listeners = this._events[evt];
    if (listeners.fn) {
        if (listeners.fn === fn && (!once || listeners.once) && (!context || listeners.context === context)) clearEvent(this, evt);
    } else {
        for(var i = 0, events = [], length = listeners.length; i < length; i++)if (listeners[i].fn !== fn || once && !listeners[i].once || context && listeners[i].context !== context) events.push(listeners[i]);
        //
        // Reset the array, or remove it completely if we have no more listeners.
        //
        if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;
        else clearEvent(this, evt);
    }
    return this;
};
/**
 * Remove all listeners, or those of the specified event.
 *
 * @param {(String|Symbol)} [event] The event name.
 * @returns {EventEmitter} `this`.
 * @public
 */ EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
    var evt;
    if (event) {
        evt = prefix ? prefix + event : event;
        if (this._events[evt]) clearEvent(this, evt);
    } else {
        this._events = new Events();
        this._eventsCount = 0;
    }
    return this;
};
//
// Alias methods names because people roll like that.
//
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
EventEmitter.prototype.addListener = EventEmitter.prototype.on;
//
// Expose the prefix.
//
EventEmitter.prefixed = prefix;
//
// Allow `EventEmitter` to be imported as module namespace.
//
EventEmitter.EventEmitter = EventEmitter;
//
// Expose the module.
//
if ('undefined' !== typeof module) module.exports = EventEmitter;

},{}],"i8fSI":[function(require,module,exports) {
'use strict';
const pFinally = require('p-finally');
class TimeoutError extends Error {
    constructor(message1){
        super(message1);
        this.name = 'TimeoutError';
    }
}
const pTimeout = (promise, milliseconds, fallback)=>new Promise((resolve, reject)=>{
        if (typeof milliseconds !== 'number' || milliseconds < 0) throw new TypeError('Expected `milliseconds` to be a positive number');
        if (milliseconds === Infinity) {
            resolve(promise);
            return;
        }
        const timer = setTimeout(()=>{
            if (typeof fallback === 'function') {
                try {
                    resolve(fallback());
                } catch (error) {
                    reject(error);
                }
                return;
            }
            const message = typeof fallback === 'string' ? fallback : `Promise timed out after ${milliseconds} milliseconds`;
            const timeoutError = fallback instanceof Error ? fallback : new TimeoutError(message);
            if (typeof promise.cancel === 'function') promise.cancel();
            reject(timeoutError);
        }, milliseconds);
        // TODO: Use native `finally` keyword when targeting Node.js 10
        pFinally(// eslint-disable-next-line promise/prefer-await-to-then
        promise.then(resolve, reject), ()=>{
            clearTimeout(timer);
        });
    })
;
module.exports = pTimeout;
// TODO: Remove this for the next major release
module.exports.default = pTimeout;
module.exports.TimeoutError = TimeoutError;

},{"p-finally":"1vYA0"}],"1vYA0":[function(require,module,exports) {
'use strict';
module.exports = (promise, onFinally)=>{
    onFinally = onFinally || (()=>{
    });
    return promise.then((val)=>new Promise((resolve)=>{
            resolve(onFinally());
        }).then(()=>val
        )
    , (err)=>new Promise((resolve)=>{
            resolve(onFinally());
        }).then(()=>{
            throw err;
        })
    );
};

},{}],"d6haw":[function(require,module,exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
const lower_bound_1 = require("./lower-bound");
class PriorityQueue {
    constructor(){
        this._queue = [];
    }
    enqueue(run, options) {
        options = Object.assign({
            priority: 0
        }, options);
        const element = {
            priority: options.priority,
            run
        };
        if (this.size && this._queue[this.size - 1].priority >= options.priority) {
            this._queue.push(element);
            return;
        }
        const index = lower_bound_1.default(this._queue, element, (a, b)=>b.priority - a.priority
        );
        this._queue.splice(index, 0, element);
    }
    dequeue() {
        const item = this._queue.shift();
        return item === null || item === void 0 ? void 0 : item.run;
    }
    filter(options1) {
        return this._queue.filter((element)=>element.priority === options1.priority
        ).map((element)=>element.run
        );
    }
    get size() {
        return this._queue.length;
    }
}
exports.default = PriorityQueue;

},{"./lower-bound":"4n1bP"}],"4n1bP":[function(require,module,exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
// Port of lower_bound from https://en.cppreference.com/w/cpp/algorithm/lower_bound
// Used to compute insertion index to keep queue sorted after insertion
function lowerBound(array, value, comparator) {
    let first = 0;
    let count = array.length;
    while(count > 0){
        const step = count / 2 | 0;
        let it = first + step;
        if (comparator(array[it], value) <= 0) {
            first = ++it;
            count -= step + 1;
        } else count = step;
    }
    return first;
}
exports.default = lowerBound;

},{}],"2w2r7":[function(require,module,exports) {
/* eslint-disable no-undef */ 'use strict';
const { fetch , Request , Headers  } = require('./http/fetch');
const { TimeoutError , HTTPError  } = require('./http/error');
const merge = require('merge-options').bind({
    ignoreUndefined: true
});
const { URL , URLSearchParams  } = require('iso-url');
const { AbortController  } = require('native-abort-controller');
const anySignal = require('any-signal');
/**
 * @typedef {import('stream').Readable} NodeReadableStream
 * @typedef {import('./types').HTTPOptions} HTTPOptions
 * @typedef {import('./types').ExtendedResponse} ExtendedResponse
 */ /**
 * @template TResponse
 * @param {Promise<TResponse>} promise
 * @param {number | undefined} ms
 * @param {AbortController} abortController
 * @returns {Promise<TResponse>}
 */ const timeout = (promise, ms, abortController)=>{
    if (ms === undefined) return promise;
    const start = Date.now();
    const timedOut = ()=>{
        const time = Date.now() - start;
        return time >= ms;
    };
    return new Promise((resolve, reject)=>{
        const timeoutID = setTimeout(()=>{
            if (timedOut()) {
                reject(new TimeoutError());
                abortController.abort();
            }
        }, ms);
        /**
     * @param {(value: any) => void } next
     */ const after = (next)=>{
            /**
       * @param {any} res
       */ const fn = (res)=>{
                clearTimeout(timeoutID);
                if (timedOut()) {
                    reject(new TimeoutError());
                    return;
                }
                next(res);
            };
            return fn;
        };
        promise.then(after(resolve), after(reject));
    });
};
const defaults = {
    throwHttpErrors: true,
    credentials: 'same-origin'
};
class HTTP {
    /**
   *
   * @param {HTTPOptions} options
   */ constructor(options7 = {
    }){
        /** @type {HTTPOptions} */ this.opts = merge(defaults, options7);
    }
    /**
   * Fetch
   *
   * @param {string | Request} resource
   * @param {HTTPOptions} options
   * @returns {Promise<ExtendedResponse>}
   */ async fetch(resource6, options1 = {
    }) {
        /** @type {HTTPOptions} */ const opts = merge(this.opts, options1);
        const headers = new Headers(opts.headers);
        // validate resource type
        if (typeof resource6 !== 'string' && !(resource6 instanceof URL || resource6 instanceof Request)) throw new TypeError('`resource` must be a string, URL, or Request');
        const url = new URL(resource6.toString(), opts.base);
        const { searchParams , transformSearchParams , json  } = opts;
        if (searchParams) {
            if (typeof transformSearchParams === 'function') // @ts-ignore
            url.search = transformSearchParams(new URLSearchParams(opts.searchParams));
            else // @ts-ignore
            url.search = new URLSearchParams(opts.searchParams);
        }
        if (json) {
            opts.body = JSON.stringify(opts.json);
            headers.set('content-type', 'application/json');
        }
        const abortController = new AbortController();
        // @ts-ignore
        const signal = anySignal([
            abortController.signal,
            opts.signal
        ]);
        const response = await timeout(fetch(url.toString(), {
            ...opts,
            signal,
            timeout: undefined,
            headers
        }), opts.timeout, abortController);
        if (!response.ok && opts.throwHttpErrors) {
            if (opts.handleError) await opts.handleError(response);
            throw new HTTPError(response);
        }
        response.iterator = function() {
            return fromStream(response.body);
        };
        response.ndjson = async function*() {
            for await (const chunk of ndjson(response.iterator()))if (options1.transform) yield options1.transform(chunk);
            else yield chunk;
        };
        return response;
    }
    /**
   * @param {string | Request} resource
   * @param {HTTPOptions} options
   */ post(resource1, options2 = {
    }) {
        return this.fetch(resource1, {
            ...options2,
            method: 'POST'
        });
    }
    /**
   * @param {string | Request} resource
   * @param {HTTPOptions} options
   */ get(resource2, options3 = {
    }) {
        return this.fetch(resource2, {
            ...options3,
            method: 'GET'
        });
    }
    /**
   * @param {string | Request} resource
   * @param {HTTPOptions} options
   */ put(resource3, options4 = {
    }) {
        return this.fetch(resource3, {
            ...options4,
            method: 'PUT'
        });
    }
    /**
   * @param {string | Request} resource
   * @param {HTTPOptions} options
   */ delete(resource4, options5 = {
    }) {
        return this.fetch(resource4, {
            ...options5,
            method: 'DELETE'
        });
    }
    /**
   * @param {string | Request} resource
   * @param {HTTPOptions} options
   */ options(resource5, options6 = {
    }) {
        return this.fetch(resource5, {
            ...options6,
            method: 'OPTIONS'
        });
    }
}
/**
 * Parses NDJSON chunks from an iterator
 *
 * @param {AsyncIterable<Uint8Array>} source
 * @returns {AsyncIterable<any>}
 */ const ndjson = async function*(source) {
    const decoder = new TextDecoder();
    let buf = '';
    for await (const chunk of source){
        buf += decoder.decode(chunk, {
            stream: true
        });
        const lines = buf.split(/\r?\n/);
        for(let i = 0; i < lines.length - 1; i++){
            const l = lines[i].trim();
            if (l.length > 0) yield JSON.parse(l);
        }
        buf = lines[lines.length - 1];
    }
    buf += decoder.decode();
    buf = buf.trim();
    if (buf.length !== 0) yield JSON.parse(buf);
};
/**
 * Stream to AsyncIterable
 *
 * @template TChunk
 * @param {ReadableStream<TChunk> | NodeReadableStream | null} source
 * @returns {AsyncIterable<TChunk>}
 */ const fromStream = (source)=>{
    // Workaround for https://github.com/node-fetch/node-fetch/issues/766
    if (isNodeReadableStream(source)) {
        const iter = source[Symbol.asyncIterator]();
        return {
            [Symbol.asyncIterator] () {
                return {
                    next: iter.next.bind(iter),
                    return (value) {
                        source.destroy();
                        if (typeof iter.return === 'function') return iter.return();
                        return Promise.resolve({
                            done: true,
                            value
                        });
                    }
                };
            }
        };
    }
    if (isWebReadableStream(source)) {
        const reader = source.getReader();
        return (async function*() {
            try {
                while(true){
                    // Read from the stream
                    const { done , value  } = await reader.read();
                    // Exit if we're done
                    if (done) return;
                    // Else yield the chunk
                    if (value) yield value;
                }
            } finally{
                reader.releaseLock();
            }
        })();
    }
    if (isAsyncIterable(source)) return source;
    throw new TypeError('Body can\'t be converted to AsyncIterable');
};
/**
 * Check if it's an AsyncIterable
 *
 * @template {unknown} TChunk
 * @template {any} Other
 * @param {Other|AsyncIterable<TChunk>} value
 * @returns {value is AsyncIterable<TChunk>}
 */ const isAsyncIterable = (value)=>{
    return typeof value === 'object' && value !== null && typeof /** @type {any} */ value[Symbol.asyncIterator] === 'function';
};
/**
 * Check for web readable stream
 *
 * @template {unknown} TChunk
 * @template {any} Other
 * @param {Other|ReadableStream<TChunk>} value
 * @returns {value is ReadableStream<TChunk>}
 */ const isWebReadableStream = (value)=>{
    return value && typeof /** @type {any} */ value.getReader === 'function';
};
/**
 * @param {any} value
 * @returns {value is NodeReadableStream}
 */ const isNodeReadableStream = (value)=>Object.prototype.hasOwnProperty.call(value, 'readable') && Object.prototype.hasOwnProperty.call(value, 'writable')
;
HTTP.HTTPError = HTTPError;
HTTP.TimeoutError = TimeoutError;
HTTP.streamToAsyncIterator = fromStream;
/**
 * @param {string | Request} resource
 * @param {HTTPOptions} [options]
 */ HTTP.post = (resource, options)=>new HTTP(options).post(resource, options)
;
/**
 * @param {string | Request} resource
 * @param {HTTPOptions} [options]
 */ HTTP.get = (resource, options)=>new HTTP(options).get(resource, options)
;
/**
 * @param {string | Request} resource
 * @param {HTTPOptions} [options]
 */ HTTP.put = (resource, options)=>new HTTP(options).put(resource, options)
;
/**
 * @param {string | Request} resource
 * @param {HTTPOptions} [options]
 */ HTTP.delete = (resource, options)=>new HTTP(options).delete(resource, options)
;
/**
 * @param {string | Request} resource
 * @param {HTTPOptions} [options]
 */ HTTP.options = (resource, options)=>new HTTP(options).options(resource, options)
;
module.exports = HTTP;

},{"./http/fetch":"alPnH","./http/error":"3iocw","merge-options":"8VjFj","iso-url":"9XZNu","native-abort-controller":"9z1Uk","any-signal":"1586s"}],"alPnH":[function(require,module,exports) {
'use strict';
const { TimeoutError , AbortError  } = require('./error');
const { Response , Request , Headers , default: fetch  } = require('../fetch');
/**
 * @typedef {import('../types').FetchOptions} FetchOptions
 * @typedef {import('../types').ProgressFn} ProgressFn
 */ /**
 * Fetch with progress
 *
 * @param {string | Request} url
 * @param {FetchOptions} [options]
 * @returns {Promise<ResponseWithURL>}
 */ const fetchWithProgress = (url, options = {
})=>{
    const request = new XMLHttpRequest();
    request.open(options.method || 'GET', url.toString(), true);
    const { timeout , headers  } = options;
    if (timeout && timeout > 0 && timeout < Infinity) request.timeout = timeout;
    if (options.overrideMimeType != null) request.overrideMimeType(options.overrideMimeType);
    if (headers) for (const [name, value] of new Headers(headers))request.setRequestHeader(name, value);
    if (options.signal) options.signal.onabort = ()=>request.abort()
    ;
    if (options.onUploadProgress) request.upload.onprogress = options.onUploadProgress;
    // Note: Need to use `arraybuffer` here instead of `blob` because `Blob`
    // instances coming from JSDOM are not compatible with `Response` from
    // node-fetch (which is the setup we get when testing with jest because
    // it uses JSDOM which does not provide a global fetch
    // https://github.com/jsdom/jsdom/issues/1724)
    request.responseType = 'arraybuffer';
    return new Promise((resolve, reject)=>{
        /**
     * @param {Event} event
     */ const handleEvent = (event)=>{
            switch(event.type){
                case 'error':
                    resolve(Response.error());
                    break;
                case 'load':
                    resolve(new ResponseWithURL(request.responseURL, request.response, {
                        status: request.status,
                        statusText: request.statusText,
                        headers: parseHeaders(request.getAllResponseHeaders())
                    }));
                    break;
                case 'timeout':
                    reject(new TimeoutError());
                    break;
                case 'abort':
                    reject(new AbortError());
                    break;
                default:
                    break;
            }
        };
        request.onerror = handleEvent;
        request.onload = handleEvent;
        request.ontimeout = handleEvent;
        request.onabort = handleEvent;
        // @ts-expect-error options.body can be a node readable stream, which isn't compatible with XHR, but this
        // file is a browser override so you won't get a node readable stream so ignore the error
        request.send(options.body);
    });
};
const fetchWithStreaming = fetch;
/**
 * @param {string | Request} url
 * @param {FetchOptions} options
 */ const fetchWith = (url, options = {
})=>options.onUploadProgress != null ? fetchWithProgress(url, options) : fetchWithStreaming(url, options)
;
/**
 * Parse Headers from a XMLHttpRequest
 *
 * @param {string} input
 * @returns {Headers}
 */ const parseHeaders = (input)=>{
    const headers = new Headers();
    for (const line of input.trim().split(/[\r\n]+/)){
        const index = line.indexOf(': ');
        if (index > 0) headers.set(line.slice(0, index), line.slice(index + 1));
    }
    return headers;
};
class ResponseWithURL extends Response {
    /**
   * @param {string} url
   * @param {BodyInit} body
   * @param {ResponseInit} options
   */ constructor(url, body, options){
        super(body, options);
        Object.defineProperty(this, 'url', {
            value: url
        });
    }
}
module.exports = {
    fetch: fetchWith,
    Request,
    Headers
};

},{"./error":"3iocw","../fetch":"6mVAe"}],"3iocw":[function(require,module,exports) {
'use strict';
class TimeoutError extends Error {
    constructor(message = 'Request timed out'){
        super(message);
        this.name = 'TimeoutError';
    }
}
exports.TimeoutError = TimeoutError;
class AbortError extends Error {
    constructor(message1 = 'The operation was aborted.'){
        super(message1);
        this.name = 'AbortError';
    }
}
exports.AbortError = AbortError;
class HTTPError extends Error {
    /**
   * @param {Response} response
   */ constructor(response){
        super(response.statusText);
        this.name = 'HTTPError';
        this.response = response;
    }
}
exports.HTTPError = HTTPError;

},{}],"6mVAe":[function(require,module,exports) {
'use strict';
const { isElectronMain  } = require('./env');
if (isElectronMain) module.exports = require('electron-fetch');
else // use window.fetch if it is available, fall back to node-fetch if not
module.exports = require('native-fetch');

},{"./env":"42nOp","electron-fetch":"joWnX","native-fetch":"h5XVM"}],"joWnX":[function(require,module,exports) {
"use strict";

},{}],"h5XVM":[function(require,module,exports) {
'use strict';
if (globalThis.fetch && globalThis.Headers && globalThis.Request && globalThis.Response) module.exports = {
    default: globalThis.fetch,
    Headers: globalThis.Headers,
    Request: globalThis.Request,
    Response: globalThis.Response
};
else module.exports = {
    default: require('node-fetch').default,
    Headers: require('node-fetch').Headers,
    Request: require('node-fetch').Request,
    Response: require('node-fetch').Response
};

},{"node-fetch":"c195Y"}],"c195Y":[function(require,module,exports) {
"use strict";
// ref: https://github.com/tc39/proposal-global
var getGlobal = function() {
    // the only reliable means to get the global object is
    // `Function('return this')()`
    // However, this causes CSP violations in Chrome apps.
    if (typeof self !== 'undefined') return self;
    if (typeof window !== 'undefined') return window;
    if (typeof global !== 'undefined') return global;
    throw new Error('unable to locate global object');
};
var global = getGlobal();
module.exports = exports = global.fetch;
// Needed for TypeScript and Webpack.
if (global.fetch) exports.default = global.fetch.bind(global);
exports.Headers = global.Headers;
exports.Request = global.Request;
exports.Response = global.Response;

},{}],"h8Bpc":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
function createIsOnline({ network  }) {
    return ()=>{
        const net = network.try();
        return net != null && Boolean(net.libp2p.isStarted());
    };
}
exports.createIsOnline = createIsOnline;

},{}],"iTKY7":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var isIpfs = require('is-ipfs');
var cid = require('multiformats/cid');
var PeerId = require('peer-id');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
var utils = require('../utils.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var isIpfs__default = /*#__PURE__*/ _interopDefaultLegacy(isIpfs);
var PeerId__default = /*#__PURE__*/ _interopDefaultLegacy(PeerId);
function createResolve({ repo , codecs , bases , name  }) {
    async function resolve(path, opts = {
    }) {
        if (!isIpfs__default['default'].path(path)) throw new Error('invalid argument ' + path);
        if (isIpfs__default['default'].ipnsPath(path)) for await (const resolvedPath of name.resolve(path, opts))path = resolvedPath;
        const [, schema, hash, ...rest] = path.split('/');
        const base = opts.cidBase ? await bases.getBase(opts.cidBase) : undefined;
        const bytes = parseBytes(hash);
        if (rest.length === 0) {
            const str = base ? base.encoder.encode(bytes) : hash;
            return `/${schema}/${str}`;
        }
        const cid$1 = cid.CID.decode(bytes);
        path = rest.join('/');
        const results = utils.resolve(cid$1, path, codecs, repo, opts);
        let value = cid$1;
        let remainderPath = path;
        for await (const result of results)if (cid.CID.asCID(result.value)) {
            value = result.value;
            remainderPath = result.remainderPath;
        }
        return `/ipfs/${value.toString(base && base.encoder)}${remainderPath ? '/' + remainderPath : ''}`;
    }
    return withTimeoutOption.withTimeoutOption(resolve);
}
function parseBytes(str) {
    try {
        return PeerId__default['default'].parse(str).toBytes();
    } catch  {
        return cid.CID.parse(str).bytes;
    }
}
exports.createResolve = createResolve;

},{"is-ipfs":"2Nskw","multiformats/cid":"fJJnW","peer-id":"4VGWt","ipfs-core-utils/with-timeout-option":"5AiVw","../utils.js":"4LLx8"}],"4VGWt":[function(require,module,exports) {
/*
 * Id is an object representation of a peer Id. a peer Id is a multihash
 */ 'use strict';
const { CID  } = require('multiformats/cid');
const b32 = require('multiformats/bases/base32');
const b36 = require('multiformats/bases/base36');
const b58 = require('multiformats/bases/base58');
const b64 = require('multiformats/bases/base64');
const { base58btc  } = require('multiformats/bases/base58');
const { base32  } = require('multiformats/bases/base32');
const { base16  } = require('multiformats/bases/base16');
const Digest = require('multiformats/hashes/digest');
const cryptoKeys = require('libp2p-crypto/src/keys');
const withIs = require('class-is');
const { PeerIdProto  } = require('./proto');
const { equals: uint8ArrayEquals  } = require('uint8arrays/equals');
const { fromString: uint8ArrayFromString  } = require('uint8arrays/from-string');
const { toString: uint8ArrayToString  } = require('uint8arrays/to-string');
const { identity  } = require('multiformats/hashes/identity');
const bases = {
    ...b32,
    ...b36,
    ...b58,
    ...b64
};
const baseDecoder = Object.keys(bases).reduce((acc, curr)=>acc.or(bases[curr])
, base32.decoder);
// these values are from https://github.com/multiformats/multicodec/blob/master/table.csv
const DAG_PB_CODE = 112;
const LIBP2P_KEY_CODE = 114;
class PeerId {
    constructor(id3, privKey2, pubKey2){
        if (!(id3 instanceof Uint8Array)) throw new Error('invalid id provided');
        if (privKey2 && pubKey2 && !uint8ArrayEquals(privKey2.public.bytes, pubKey2.bytes)) throw new Error('inconsistent arguments');
        this._id = id3;
        this._idB58String = base58btc.encode(this.id).substring(1);
        this._privKey = privKey2;
        this._pubKey = pubKey2;
    }
    get id() {
        return this._id;
    }
    set id(val1) {
        throw new Error('Id is immutable');
    }
    get privKey() {
        return this._privKey;
    }
    set privKey(privKey1) {
        this._privKey = privKey1;
    }
    get pubKey() {
        if (this._pubKey) return this._pubKey;
        if (this._privKey) return this._privKey.public;
        try {
            const decoded = Digest.decode(this.id);
            if (decoded.code === identity.code) this._pubKey = cryptoKeys.unmarshalPublicKey(decoded.digest);
        } catch (_) {
        // Ignore, there is no valid public key
        }
        return this._pubKey;
    }
    set pubKey(pubKey1) {
        this._pubKey = pubKey1;
    }
    // Return the protobuf version of the public key, matching go ipfs formatting
    marshalPubKey() {
        if (this.pubKey) return cryptoKeys.marshalPublicKey(this.pubKey);
    }
    // Return the protobuf version of the private key, matching go ipfs formatting
    marshalPrivKey() {
        if (this.privKey) return cryptoKeys.marshalPrivateKey(this.privKey);
    }
    // Return the protobuf version of the peer-id
    marshal(excludePriv) {
        return PeerIdProto.encode({
            id: this.toBytes(),
            pubKey: this.marshalPubKey(),
            privKey: excludePriv ? null : this.marshalPrivKey()
        }).finish();
    }
    toPrint() {
        let pid = this.toB58String();
        // All sha256 nodes start with Qm
        // We can skip the Qm to make the peer.ID more useful
        if (pid.startsWith('Qm')) pid = pid.slice(2);
        let maxRunes = 6;
        if (pid.length < maxRunes) maxRunes = pid.length;
        return '<peer.ID ' + pid.substr(0, maxRunes) + '>';
    }
    // return the jsonified version of the key, matching the formatting
    // of go-ipfs for its config file
    toJSON() {
        return {
            id: this.toB58String(),
            privKey: toB64Opt(this.marshalPrivKey()),
            pubKey: toB64Opt(this.marshalPubKey())
        };
    }
    // encode/decode functions
    toHexString() {
        return base16.encode(this.id).substring(1);
    }
    toBytes() {
        return this.id;
    }
    toB58String() {
        return this._idB58String;
    }
    // return self-describing String representation
    // in default format from RFC 0001: https://github.com/libp2p/specs/pull/209
    toString() {
        if (!this._idCIDString) {
            const cid = CID.createV1(LIBP2P_KEY_CODE, Digest.decode(this.id));
            Object.defineProperty(this, '_idCIDString', {
                value: cid.toString(),
                enumerable: false
            });
        }
        return this._idCIDString;
    }
    /**
   * Checks the equality of `this` peer against a given PeerId.
   *
   * @param {Uint8Array|PeerId} id
   * @returns {boolean}
   */ equals(id1) {
        if (id1 instanceof Uint8Array) return uint8ArrayEquals(this.id, id1);
        else if (id1.id) return uint8ArrayEquals(this.id, id1.id);
        else throw new Error('not valid Id');
    }
    /**
   * Checks the equality of `this` peer against a given PeerId.
   *
   * @deprecated Use `.equals`
   * @param {Uint8Array|PeerId} id
   * @returns {boolean}
   */ isEqual(id2) {
        return this.equals(id2);
    }
    /*
   * Check if this PeerId instance is valid (privKey -> pubKey -> Id)
   */ isValid() {
        // TODO: needs better checking
        return Boolean(this.privKey && this.privKey.public && this.privKey.public.bytes && this.pubKey.bytes instanceof Uint8Array && uint8ArrayEquals(this.privKey.public.bytes, this.pubKey.bytes));
    }
    /**
   * Check if the PeerId has an inline public key.
   *
   * @returns {boolean}
   */ hasInlinePublicKey() {
        try {
            const decoded = Digest.decode(this.id);
            if (decoded.code === identity.code) return true;
        } catch (_) {
        // Ignore, there is no valid public key
        }
        return false;
    }
}
const PeerIdWithIs = withIs(PeerId, {
    className: 'PeerId',
    symbolName: '@libp2p/js-peer-id/PeerId'
});
exports = module.exports = PeerIdWithIs;
const computeDigest = (pubKey)=>{
    if (pubKey.bytes.length <= 42) return Digest.create(identity.code, pubKey.bytes).bytes;
    else return pubKey.hash();
};
const computePeerId = async (privKey, pubKey)=>{
    const digest = await computeDigest(pubKey);
    return new PeerIdWithIs(digest, privKey, pubKey);
};
// generation
exports.create = async (opts)=>{
    opts = opts || {
    };
    opts.bits = opts.bits || 2048;
    opts.keyType = opts.keyType || 'RSA';
    const key = await cryptoKeys.generateKeyPair(opts.keyType, opts.bits);
    return computePeerId(key, key.public);
};
exports.createFromHexString = (str)=>{
    return new PeerIdWithIs(base16.decode('f' + str));
};
exports.createFromBytes = (buf)=>{
    try {
        const cid = CID.decode(buf);
        if (!validMulticodec(cid)) throw new Error('Supplied PeerID CID is invalid');
        return exports.createFromCID(cid);
    } catch  {
        const digest = Digest.decode(buf);
        if (digest.code !== identity.code) throw new Error('Supplied PeerID CID is invalid');
        return new PeerIdWithIs(buf);
    }
};
exports.createFromB58String = (str)=>{
    return exports.createFromBytes(base58btc.decode('z' + str));
};
const validMulticodec = (cid)=>{
    // supported: 'libp2p-key' (CIDv1) and 'dag-pb' (CIDv0 converted to CIDv1)
    return cid.code === LIBP2P_KEY_CODE || cid.code === DAG_PB_CODE;
};
exports.createFromCID = (cid)=>{
    cid = CID.asCID(cid);
    if (!cid || !validMulticodec(cid)) throw new Error('Supplied PeerID CID is invalid');
    return new PeerIdWithIs(cid.multihash.bytes);
};
// Public Key input will be a Uint8Array
exports.createFromPubKey = async (key)=>{
    let buf = key;
    if (typeof buf === 'string') buf = uint8ArrayFromString(key, 'base64pad');
    if (!(buf instanceof Uint8Array)) throw new Error('Supplied key is neither a base64 string nor a Uint8Array');
    const pubKey = await cryptoKeys.unmarshalPublicKey(buf);
    return computePeerId(undefined, pubKey);
};
// Private key input will be a string
exports.createFromPrivKey = async (key)=>{
    if (typeof key === 'string') key = uint8ArrayFromString(key, 'base64pad');
    if (!(key instanceof Uint8Array)) throw new Error('Supplied key is neither a base64 string nor a Uint8Array');
    const privKey = await cryptoKeys.unmarshalPrivateKey(key);
    return computePeerId(privKey, privKey.public);
};
exports.createFromJSON = async (obj)=>{
    const id = base58btc.decode('z' + obj.id);
    const rawPrivKey = obj.privKey && uint8ArrayFromString(obj.privKey, 'base64pad');
    const rawPubKey = obj.pubKey && uint8ArrayFromString(obj.pubKey, 'base64pad');
    const pub = rawPubKey && await cryptoKeys.unmarshalPublicKey(rawPubKey);
    if (!rawPrivKey) return new PeerIdWithIs(id, undefined, pub);
    const privKey = await cryptoKeys.unmarshalPrivateKey(rawPrivKey);
    const privDigest = await computeDigest(privKey.public);
    let pubDigest;
    if (pub) pubDigest = await computeDigest(pub);
    if (pub && !uint8ArrayEquals(privDigest, pubDigest)) throw new Error('Public and private key do not match');
    if (id && !uint8ArrayEquals(privDigest, id)) throw new Error('Id and private key do not match');
    return new PeerIdWithIs(id, privKey, pub);
};
exports.createFromProtobuf = async (buf)=>{
    if (typeof buf === 'string') buf = uint8ArrayFromString(buf, 'base16');
    let { id , privKey , pubKey  } = PeerIdProto.decode(buf);
    privKey = privKey ? await cryptoKeys.unmarshalPrivateKey(privKey) : false;
    pubKey = pubKey ? await cryptoKeys.unmarshalPublicKey(pubKey) : false;
    let pubDigest;
    let privDigest;
    if (privKey) privDigest = await computeDigest(privKey.public);
    if (pubKey) pubDigest = await computeDigest(pubKey);
    if (privKey) {
        if (pubKey) {
            if (!uint8ArrayEquals(privDigest, pubDigest)) throw new Error('Public and private key do not match');
        }
        return new PeerIdWithIs(privDigest, privKey, privKey.public);
    }
    // TODO: val id and pubDigest
    if (pubKey) return new PeerIdWithIs(pubDigest, undefined, pubKey);
    if (id) return new PeerIdWithIs(id);
    throw new Error('Protobuf did not contain any usable key material');
};
exports.parse = (str)=>{
    if (str.charAt(0) === '1' || str.charAt(0) === 'Q') // identity hash ed25519 key or sha2-256 hash of rsa public key
    // base58btc encoded either way
    str = `z${str}`;
    return exports.createFromBytes(baseDecoder.decode(str));
};
exports.isPeerId = (peerId)=>{
    return Boolean(typeof peerId === 'object' && peerId._id && peerId._idB58String);
};
function toB64Opt(val) {
    if (val) return uint8ArrayToString(val, 'base64pad');
}

},{"multiformats/cid":"fJJnW","multiformats/bases/base32":"63xDB","multiformats/bases/base36":"iaopc","multiformats/bases/base58":"6Rnqi","multiformats/bases/base64":"7Lo1j","multiformats/bases/base16":"kDDoG","multiformats/hashes/digest":"fkA58","libp2p-crypto/src/keys":"Ore66","class-is":"eROOZ","./proto":"b9Uyl","uint8arrays/equals":"fjLeN","uint8arrays/from-string":"lo45E","uint8arrays/to-string":"g3mCQ","multiformats/hashes/identity":"7Cndu"}],"Ore66":[function(require,module,exports) {
'use strict';
const keysPBM = require('./keys');
require('node-forge/lib/asn1');
require('node-forge/lib/pbe');
const forge = require('node-forge/lib/forge');
const errcode = require('err-code');
const { fromString: uint8ArrayFromString  } = require('uint8arrays/from-string');
const importer = require('./importer');
const supportedKeys = {
    rsa: require('./rsa-class'),
    ed25519: require('./ed25519-class'),
    secp256k1: require('./secp256k1-class')(keysPBM, require('../random-bytes'))
};
const ErrMissingSecp256K1 = {
    message: 'secp256k1 support requires libp2p-crypto-secp256k1 package',
    code: 'ERR_MISSING_PACKAGE'
};
function typeToKey(type) {
    const key = supportedKeys[type.toLowerCase()];
    if (!key) {
        const supported = Object.keys(supportedKeys).join(' / ');
        throw errcode(new Error(`invalid or unsupported key type ${type}. Must be ${supported}`), 'ERR_UNSUPPORTED_KEY_TYPE');
    }
    return key;
}
// Generates a keypair of the given type and bitsize
const generateKeyPair = async (type, bits)=>{
    return typeToKey(type).generateKeyPair(bits);
};
// Generates a keypair of the given type and bitsize
// seed is a 32 byte uint8array
const generateKeyPairFromSeed = async (type, seed, bits)=>{
    const key = typeToKey(type);
    if (type.toLowerCase() !== 'ed25519') throw errcode(new Error('Seed key derivation is unimplemented for RSA or secp256k1'), 'ERR_UNSUPPORTED_KEY_DERIVATION_TYPE');
    return key.generateKeyPairFromSeed(seed, bits);
};
// Converts a protobuf serialized public key into its
// representative object
const unmarshalPublicKey = (buf)=>{
    const decoded = keysPBM.PublicKey.decode(buf);
    const data = decoded.Data;
    switch(decoded.Type){
        case keysPBM.KeyType.RSA:
            return supportedKeys.rsa.unmarshalRsaPublicKey(data);
        case keysPBM.KeyType.Ed25519:
            return supportedKeys.ed25519.unmarshalEd25519PublicKey(data);
        case keysPBM.KeyType.Secp256k1:
            if (supportedKeys.secp256k1) return supportedKeys.secp256k1.unmarshalSecp256k1PublicKey(data);
            else throw errcode(new Error(ErrMissingSecp256K1.message), ErrMissingSecp256K1.code);
        default:
            typeToKey(decoded.Type) // throws because type is not supported
            ;
    }
};
// Converts a public key object into a protobuf serialized public key
const marshalPublicKey = (key, type)=>{
    type = (type || 'rsa').toLowerCase();
    typeToKey(type) // check type
    ;
    return key.bytes;
};
// Converts a protobuf serialized private key into its
// representative object
const unmarshalPrivateKey = async (buf)=>{
    const decoded = keysPBM.PrivateKey.decode(buf);
    const data = decoded.Data;
    switch(decoded.Type){
        case keysPBM.KeyType.RSA:
            return supportedKeys.rsa.unmarshalRsaPrivateKey(data);
        case keysPBM.KeyType.Ed25519:
            return supportedKeys.ed25519.unmarshalEd25519PrivateKey(data);
        case keysPBM.KeyType.Secp256k1:
            if (supportedKeys.secp256k1) return supportedKeys.secp256k1.unmarshalSecp256k1PrivateKey(data);
            else throw errcode(new Error(ErrMissingSecp256K1.message), ErrMissingSecp256K1.code);
        default:
            typeToKey(decoded.Type) // throws because type is not supported
            ;
    }
};
// Converts a private key object into a protobuf serialized private key
const marshalPrivateKey = (key, type)=>{
    type = (type || 'rsa').toLowerCase();
    typeToKey(type) // check type
    ;
    return key.bytes;
};
/**
 *
 * @param {string} encryptedKey
 * @param {string} password
 */ const importKey = async (encryptedKey, password)=>{
    try {
        const key = await importer.import(encryptedKey, password);
        return unmarshalPrivateKey(key);
    } catch (_) {
    // Ignore and try the old pem decrypt
    }
    // Only rsa supports pem right now
    const key = forge.pki.decryptRsaPrivateKey(encryptedKey, password);
    if (key === null) throw errcode(new Error('Cannot read the key, most likely the password is wrong or not a RSA key'), 'ERR_CANNOT_DECRYPT_PEM');
    let der = forge.asn1.toDer(forge.pki.privateKeyToAsn1(key));
    der = uint8ArrayFromString(der.getBytes(), 'ascii');
    return supportedKeys.rsa.unmarshalRsaPrivateKey(der);
};
module.exports = {
    supportedKeys,
    keysPBM,
    keyStretcher: require('./key-stretcher'),
    generateEphemeralKeyPair: require('./ephemeral-keys'),
    generateKeyPair,
    generateKeyPairFromSeed,
    unmarshalPublicKey,
    marshalPublicKey,
    unmarshalPrivateKey,
    marshalPrivateKey,
    import: importKey
};

},{"./keys":"jQuh5","node-forge/lib/asn1":"fLyrX","node-forge/lib/pbe":"klwlu","node-forge/lib/forge":"7AnVp","err-code":"eQvyh","uint8arrays/from-string":"lo45E","./importer":"8gaLA","./rsa-class":"F5NLK","./ed25519-class":"Gg3Pl","./secp256k1-class":"6ex4h","../random-bytes":"1G1Dz","./key-stretcher":"3mB6S","./ephemeral-keys":"g85te"}],"jQuh5":[function(require,module,exports) {
/*eslint-disable*/ "use strict";
var $protobuf = require("protobufjs/minimal");
// Common aliases
var $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util;
// Exported root namespace
var $root = $protobuf.roots["libp2p-crypto-keys"] || ($protobuf.roots["libp2p-crypto-keys"] = {
});
/**
 * KeyType enum.
 * @exports KeyType
 * @enum {number}
 * @property {number} RSA=0 RSA value
 * @property {number} Ed25519=1 Ed25519 value
 * @property {number} Secp256k1=2 Secp256k1 value
 */ $root.KeyType = (function() {
    var valuesById = {
    }, values = Object.create(valuesById);
    values[valuesById[0] = "RSA"] = 0;
    values[valuesById[1] = "Ed25519"] = 1;
    values[valuesById[2] = "Secp256k1"] = 2;
    return values;
})();
$root.PublicKey = (function() {
    /**
     * Properties of a PublicKey.
     * @exports IPublicKey
     * @interface IPublicKey
     * @property {KeyType} Type PublicKey Type
     * @property {Uint8Array} Data PublicKey Data
     */ /**
     * Constructs a new PublicKey.
     * @exports PublicKey
     * @classdesc Represents a PublicKey.
     * @implements IPublicKey
     * @constructor
     * @param {IPublicKey=} [p] Properties to set
     */ function PublicKey(p) {
        if (p) {
            for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
        }
    }
    /**
     * PublicKey Type.
     * @member {KeyType} Type
     * @memberof PublicKey
     * @instance
     */ PublicKey.prototype.Type = 0;
    /**
     * PublicKey Data.
     * @member {Uint8Array} Data
     * @memberof PublicKey
     * @instance
     */ PublicKey.prototype.Data = $util.newBuffer([]);
    /**
     * Encodes the specified PublicKey message. Does not implicitly {@link PublicKey.verify|verify} messages.
     * @function encode
     * @memberof PublicKey
     * @static
     * @param {IPublicKey} m PublicKey message or plain object to encode
     * @param {$protobuf.Writer} [w] Writer to encode to
     * @returns {$protobuf.Writer} Writer
     */ PublicKey.encode = function encode(m, w) {
        if (!w) w = $Writer.create();
        w.uint32(8).int32(m.Type);
        w.uint32(18).bytes(m.Data);
        return w;
    };
    /**
     * Decodes a PublicKey message from the specified reader or buffer.
     * @function decode
     * @memberof PublicKey
     * @static
     * @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
     * @param {number} [l] Message length if known beforehand
     * @returns {PublicKey} PublicKey
     * @throws {Error} If the payload is not a reader or valid buffer
     * @throws {$protobuf.util.ProtocolError} If required fields are missing
     */ PublicKey.decode = function decode(r, l) {
        if (!(r instanceof $Reader)) r = $Reader.create(r);
        var c = l === undefined ? r.len : r.pos + l, m = new $root.PublicKey();
        while(r.pos < c){
            var t = r.uint32();
            switch(t >>> 3){
                case 1:
                    m.Type = r.int32();
                    break;
                case 2:
                    m.Data = r.bytes();
                    break;
                default:
                    r.skipType(t & 7);
                    break;
            }
        }
        if (!m.hasOwnProperty("Type")) throw $util.ProtocolError("missing required 'Type'", {
            instance: m
        });
        if (!m.hasOwnProperty("Data")) throw $util.ProtocolError("missing required 'Data'", {
            instance: m
        });
        return m;
    };
    /**
     * Creates a PublicKey message from a plain object. Also converts values to their respective internal types.
     * @function fromObject
     * @memberof PublicKey
     * @static
     * @param {Object.<string,*>} d Plain object
     * @returns {PublicKey} PublicKey
     */ PublicKey.fromObject = function fromObject(d) {
        if (d instanceof $root.PublicKey) return d;
        var m = new $root.PublicKey();
        switch(d.Type){
            case "RSA":
            case 0:
                m.Type = 0;
                break;
            case "Ed25519":
            case 1:
                m.Type = 1;
                break;
            case "Secp256k1":
            case 2:
                m.Type = 2;
                break;
        }
        if (d.Data != null) {
            if (typeof d.Data === "string") $util.base64.decode(d.Data, m.Data = $util.newBuffer($util.base64.length(d.Data)), 0);
            else if (d.Data.length) m.Data = d.Data;
        }
        return m;
    };
    /**
     * Creates a plain object from a PublicKey message. Also converts values to other types if specified.
     * @function toObject
     * @memberof PublicKey
     * @static
     * @param {PublicKey} m PublicKey
     * @param {$protobuf.IConversionOptions} [o] Conversion options
     * @returns {Object.<string,*>} Plain object
     */ PublicKey.toObject = function toObject(m, o) {
        if (!o) o = {
        };
        var d = {
        };
        if (o.defaults) {
            d.Type = o.enums === String ? "RSA" : 0;
            if (o.bytes === String) d.Data = "";
            else {
                d.Data = [];
                if (o.bytes !== Array) d.Data = $util.newBuffer(d.Data);
            }
        }
        if (m.Type != null && m.hasOwnProperty("Type")) d.Type = o.enums === String ? $root.KeyType[m.Type] : m.Type;
        if (m.Data != null && m.hasOwnProperty("Data")) d.Data = o.bytes === String ? $util.base64.encode(m.Data, 0, m.Data.length) : o.bytes === Array ? Array.prototype.slice.call(m.Data) : m.Data;
        return d;
    };
    /**
     * Converts this PublicKey to JSON.
     * @function toJSON
     * @memberof PublicKey
     * @instance
     * @returns {Object.<string,*>} JSON object
     */ PublicKey.prototype.toJSON = function toJSON() {
        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
    };
    return PublicKey;
})();
$root.PrivateKey = (function() {
    /**
     * Properties of a PrivateKey.
     * @exports IPrivateKey
     * @interface IPrivateKey
     * @property {KeyType} Type PrivateKey Type
     * @property {Uint8Array} Data PrivateKey Data
     */ /**
     * Constructs a new PrivateKey.
     * @exports PrivateKey
     * @classdesc Represents a PrivateKey.
     * @implements IPrivateKey
     * @constructor
     * @param {IPrivateKey=} [p] Properties to set
     */ function PrivateKey(p) {
        if (p) {
            for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
        }
    }
    /**
     * PrivateKey Type.
     * @member {KeyType} Type
     * @memberof PrivateKey
     * @instance
     */ PrivateKey.prototype.Type = 0;
    /**
     * PrivateKey Data.
     * @member {Uint8Array} Data
     * @memberof PrivateKey
     * @instance
     */ PrivateKey.prototype.Data = $util.newBuffer([]);
    /**
     * Encodes the specified PrivateKey message. Does not implicitly {@link PrivateKey.verify|verify} messages.
     * @function encode
     * @memberof PrivateKey
     * @static
     * @param {IPrivateKey} m PrivateKey message or plain object to encode
     * @param {$protobuf.Writer} [w] Writer to encode to
     * @returns {$protobuf.Writer} Writer
     */ PrivateKey.encode = function encode(m, w) {
        if (!w) w = $Writer.create();
        w.uint32(8).int32(m.Type);
        w.uint32(18).bytes(m.Data);
        return w;
    };
    /**
     * Decodes a PrivateKey message from the specified reader or buffer.
     * @function decode
     * @memberof PrivateKey
     * @static
     * @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
     * @param {number} [l] Message length if known beforehand
     * @returns {PrivateKey} PrivateKey
     * @throws {Error} If the payload is not a reader or valid buffer
     * @throws {$protobuf.util.ProtocolError} If required fields are missing
     */ PrivateKey.decode = function decode(r, l) {
        if (!(r instanceof $Reader)) r = $Reader.create(r);
        var c = l === undefined ? r.len : r.pos + l, m = new $root.PrivateKey();
        while(r.pos < c){
            var t = r.uint32();
            switch(t >>> 3){
                case 1:
                    m.Type = r.int32();
                    break;
                case 2:
                    m.Data = r.bytes();
                    break;
                default:
                    r.skipType(t & 7);
                    break;
            }
        }
        if (!m.hasOwnProperty("Type")) throw $util.ProtocolError("missing required 'Type'", {
            instance: m
        });
        if (!m.hasOwnProperty("Data")) throw $util.ProtocolError("missing required 'Data'", {
            instance: m
        });
        return m;
    };
    /**
     * Creates a PrivateKey message from a plain object. Also converts values to their respective internal types.
     * @function fromObject
     * @memberof PrivateKey
     * @static
     * @param {Object.<string,*>} d Plain object
     * @returns {PrivateKey} PrivateKey
     */ PrivateKey.fromObject = function fromObject(d) {
        if (d instanceof $root.PrivateKey) return d;
        var m = new $root.PrivateKey();
        switch(d.Type){
            case "RSA":
            case 0:
                m.Type = 0;
                break;
            case "Ed25519":
            case 1:
                m.Type = 1;
                break;
            case "Secp256k1":
            case 2:
                m.Type = 2;
                break;
        }
        if (d.Data != null) {
            if (typeof d.Data === "string") $util.base64.decode(d.Data, m.Data = $util.newBuffer($util.base64.length(d.Data)), 0);
            else if (d.Data.length) m.Data = d.Data;
        }
        return m;
    };
    /**
     * Creates a plain object from a PrivateKey message. Also converts values to other types if specified.
     * @function toObject
     * @memberof PrivateKey
     * @static
     * @param {PrivateKey} m PrivateKey
     * @param {$protobuf.IConversionOptions} [o] Conversion options
     * @returns {Object.<string,*>} Plain object
     */ PrivateKey.toObject = function toObject(m, o) {
        if (!o) o = {
        };
        var d = {
        };
        if (o.defaults) {
            d.Type = o.enums === String ? "RSA" : 0;
            if (o.bytes === String) d.Data = "";
            else {
                d.Data = [];
                if (o.bytes !== Array) d.Data = $util.newBuffer(d.Data);
            }
        }
        if (m.Type != null && m.hasOwnProperty("Type")) d.Type = o.enums === String ? $root.KeyType[m.Type] : m.Type;
        if (m.Data != null && m.hasOwnProperty("Data")) d.Data = o.bytes === String ? $util.base64.encode(m.Data, 0, m.Data.length) : o.bytes === Array ? Array.prototype.slice.call(m.Data) : m.Data;
        return d;
    };
    /**
     * Converts this PrivateKey to JSON.
     * @function toJSON
     * @memberof PrivateKey
     * @instance
     * @returns {Object.<string,*>} JSON object
     */ PrivateKey.prototype.toJSON = function toJSON() {
        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
    };
    return PrivateKey;
})();
module.exports = $root;

},{"protobufjs/minimal":"9Jmso"}],"fLyrX":[function(require,module,exports) {
/**
 * Javascript implementation of Abstract Syntax Notation Number One.
 *
 * @author Dave Longley
 *
 * Copyright (c) 2010-2015 Digital Bazaar, Inc.
 *
 * An API for storing data using the Abstract Syntax Notation Number One
 * format using DER (Distinguished Encoding Rules) encoding. This encoding is
 * commonly used to store data for PKI, i.e. X.509 Certificates, and this
 * implementation exists for that purpose.
 *
 * Abstract Syntax Notation Number One (ASN.1) is used to define the abstract
 * syntax of information without restricting the way the information is encoded
 * for transmission. It provides a standard that allows for open systems
 * communication. ASN.1 defines the syntax of information data and a number of
 * simple data types as well as a notation for describing them and specifying
 * values for them.
 *
 * The RSA algorithm creates public and private keys that are often stored in
 * X.509 or PKCS#X formats -- which use ASN.1 (encoded in DER format). This
 * class provides the most basic functionality required to store and load DSA
 * keys that are encoded according to ASN.1.
 *
 * The most common binary encodings for ASN.1 are BER (Basic Encoding Rules)
 * and DER (Distinguished Encoding Rules). DER is just a subset of BER that
 * has stricter requirements for how data must be encoded.
 *
 * Each ASN.1 structure has a tag (a byte identifying the ASN.1 structure type)
 * and a byte array for the value of this ASN1 structure which may be data or a
 * list of ASN.1 structures.
 *
 * Each ASN.1 structure using BER is (Tag-Length-Value):
 *
 * | byte 0 | bytes X | bytes Y |
 * |--------|---------|----------
 * |  tag   | length  |  value  |
 *
 * ASN.1 allows for tags to be of "High-tag-number form" which allows a tag to
 * be two or more octets, but that is not supported by this class. A tag is
 * only 1 byte. Bits 1-5 give the tag number (ie the data type within a
 * particular 'class'), 6 indicates whether or not the ASN.1 value is
 * constructed from other ASN.1 values, and bits 7 and 8 give the 'class'. If
 * bits 7 and 8 are both zero, the class is UNIVERSAL. If only bit 7 is set,
 * then the class is APPLICATION. If only bit 8 is set, then the class is
 * CONTEXT_SPECIFIC. If both bits 7 and 8 are set, then the class is PRIVATE.
 * The tag numbers for the data types for the class UNIVERSAL are listed below:
 *
 * UNIVERSAL 0 Reserved for use by the encoding rules
 * UNIVERSAL 1 Boolean type
 * UNIVERSAL 2 Integer type
 * UNIVERSAL 3 Bitstring type
 * UNIVERSAL 4 Octetstring type
 * UNIVERSAL 5 Null type
 * UNIVERSAL 6 Object identifier type
 * UNIVERSAL 7 Object descriptor type
 * UNIVERSAL 8 External type and Instance-of type
 * UNIVERSAL 9 Real type
 * UNIVERSAL 10 Enumerated type
 * UNIVERSAL 11 Embedded-pdv type
 * UNIVERSAL 12 UTF8String type
 * UNIVERSAL 13 Relative object identifier type
 * UNIVERSAL 14-15 Reserved for future editions
 * UNIVERSAL 16 Sequence and Sequence-of types
 * UNIVERSAL 17 Set and Set-of types
 * UNIVERSAL 18-22, 25-30 Character string types
 * UNIVERSAL 23-24 Time types
 *
 * The length of an ASN.1 structure is specified after the tag identifier.
 * There is a definite form and an indefinite form. The indefinite form may
 * be used if the encoding is constructed and not all immediately available.
 * The indefinite form is encoded using a length byte with only the 8th bit
 * set. The end of the constructed object is marked using end-of-contents
 * octets (two zero bytes).
 *
 * The definite form looks like this:
 *
 * The length may take up 1 or more bytes, it depends on the length of the
 * value of the ASN.1 structure. DER encoding requires that if the ASN.1
 * structure has a value that has a length greater than 127, more than 1 byte
 * will be used to store its length, otherwise just one byte will be used.
 * This is strict.
 *
 * In the case that the length of the ASN.1 value is less than 127, 1 octet
 * (byte) is used to store the "short form" length. The 8th bit has a value of
 * 0 indicating the length is "short form" and not "long form" and bits 7-1
 * give the length of the data. (The 8th bit is the left-most, most significant
 * bit: also known as big endian or network format).
 *
 * In the case that the length of the ASN.1 value is greater than 127, 2 to
 * 127 octets (bytes) are used to store the "long form" length. The first
 * byte's 8th bit is set to 1 to indicate the length is "long form." Bits 7-1
 * give the number of additional octets. All following octets are in base 256
 * with the most significant digit first (typical big-endian binary unsigned
 * integer storage). So, for instance, if the length of a value was 257, the
 * first byte would be set to:
 *
 * 10000010 = 130 = 0x82.
 *
 * This indicates there are 2 octets (base 256) for the length. The second and
 * third bytes (the octets just mentioned) would store the length in base 256:
 *
 * octet 2: 00000001 = 1 * 256^1 = 256
 * octet 3: 00000001 = 1 * 256^0 = 1
 * total = 257
 *
 * The algorithm for converting a js integer value of 257 to base-256 is:
 *
 * var value = 257;
 * var bytes = [];
 * bytes[0] = (value >>> 8) & 0xFF; // most significant byte first
 * bytes[1] = value & 0xFF;        // least significant byte last
 *
 * On the ASN.1 UNIVERSAL Object Identifier (OID) type:
 *
 * An OID can be written like: "value1.value2.value3...valueN"
 *
 * The DER encoding rules:
 *
 * The first byte has the value 40 * value1 + value2.
 * The following bytes, if any, encode the remaining values. Each value is
 * encoded in base 128, most significant digit first (big endian), with as
 * few digits as possible, and the most significant bit of each byte set
 * to 1 except the last in each value's encoding. For example: Given the
 * OID "1.2.840.113549", its DER encoding is (remember each byte except the
 * last one in each encoding is OR'd with 0x80):
 *
 * byte 1: 40 * 1 + 2 = 42 = 0x2A.
 * bytes 2-3: 128 * 6 + 72 = 840 = 6 72 = 6 72 = 0x0648 = 0x8648
 * bytes 4-6: 16384 * 6 + 128 * 119 + 13 = 6 119 13 = 0x06770D = 0x86F70D
 *
 * The final value is: 0x2A864886F70D.
 * The full OID (including ASN.1 tag and length of 6 bytes) is:
 * 0x06062A864886F70D
 */ var forge = require('./forge');
require('./util');
require('./oids');
/* ASN.1 API */ var asn1 = module.exports = forge.asn1 = forge.asn1 || {
};
/**
 * ASN.1 classes.
 */ asn1.Class = {
    UNIVERSAL: 0,
    APPLICATION: 64,
    CONTEXT_SPECIFIC: 128,
    PRIVATE: 192
};
/**
 * ASN.1 types. Not all types are supported by this implementation, only
 * those necessary to implement a simple PKI are implemented.
 */ asn1.Type = {
    NONE: 0,
    BOOLEAN: 1,
    INTEGER: 2,
    BITSTRING: 3,
    OCTETSTRING: 4,
    NULL: 5,
    OID: 6,
    ODESC: 7,
    EXTERNAL: 8,
    REAL: 9,
    ENUMERATED: 10,
    EMBEDDED: 11,
    UTF8: 12,
    ROID: 13,
    SEQUENCE: 16,
    SET: 17,
    PRINTABLESTRING: 19,
    IA5STRING: 22,
    UTCTIME: 23,
    GENERALIZEDTIME: 24,
    BMPSTRING: 30
};
/**
 * Creates a new asn1 object.
 *
 * @param tagClass the tag class for the object.
 * @param type the data type (tag number) for the object.
 * @param constructed true if the asn1 object is in constructed form.
 * @param value the value for the object, if it is not constructed.
 * @param [options] the options to use:
 *          [bitStringContents] the plain BIT STRING content including padding
 *            byte.
 *
 * @return the asn1 object.
 */ asn1.create = function(tagClass, type, constructed, value, options) {
    /* An asn1 object has a tagClass, a type, a constructed flag, and a
    value. The value's type depends on the constructed flag. If
    constructed, it will contain a list of other asn1 objects. If not,
    it will contain the ASN.1 value as an array of bytes formatted
    according to the ASN.1 data type. */ // remove undefined values
    if (forge.util.isArray(value)) {
        var tmp = [];
        for(var i = 0; i < value.length; ++i)if (value[i] !== undefined) tmp.push(value[i]);
        value = tmp;
    }
    var obj = {
        tagClass: tagClass,
        type: type,
        constructed: constructed,
        composed: constructed || forge.util.isArray(value),
        value: value
    };
    if (options && 'bitStringContents' in options) {
        // TODO: copy byte buffer if it's a buffer not a string
        obj.bitStringContents = options.bitStringContents;
        // TODO: add readonly flag to avoid this overhead
        // save copy to detect changes
        obj.original = asn1.copy(obj);
    }
    return obj;
};
/**
 * Copies an asn1 object.
 *
 * @param obj the asn1 object.
 * @param [options] copy options:
 *          [excludeBitStringContents] true to not copy bitStringContents
 *
 * @return the a copy of the asn1 object.
 */ asn1.copy = function(obj, options) {
    var copy;
    if (forge.util.isArray(obj)) {
        copy = [];
        for(var i = 0; i < obj.length; ++i)copy.push(asn1.copy(obj[i], options));
        return copy;
    }
    if (typeof obj === 'string') // TODO: copy byte buffer if it's a buffer not a string
    return obj;
    copy = {
        tagClass: obj.tagClass,
        type: obj.type,
        constructed: obj.constructed,
        composed: obj.composed,
        value: asn1.copy(obj.value, options)
    };
    if (options && !options.excludeBitStringContents) // TODO: copy byte buffer if it's a buffer not a string
    copy.bitStringContents = obj.bitStringContents;
    return copy;
};
/**
 * Compares asn1 objects for equality.
 *
 * Note this function does not run in constant time.
 *
 * @param obj1 the first asn1 object.
 * @param obj2 the second asn1 object.
 * @param [options] compare options:
 *          [includeBitStringContents] true to compare bitStringContents
 *
 * @return true if the asn1 objects are equal.
 */ asn1.equals = function(obj1, obj2, options) {
    if (forge.util.isArray(obj1)) {
        if (!forge.util.isArray(obj2)) return false;
        if (obj1.length !== obj2.length) return false;
        for(var i = 0; i < obj1.length; ++i){
            if (!asn1.equals(obj1[i], obj2[i])) return false;
        }
        return true;
    }
    if (typeof obj1 !== typeof obj2) return false;
    if (typeof obj1 === 'string') return obj1 === obj2;
    var equal = obj1.tagClass === obj2.tagClass && obj1.type === obj2.type && obj1.constructed === obj2.constructed && obj1.composed === obj2.composed && asn1.equals(obj1.value, obj2.value);
    if (options && options.includeBitStringContents) equal = equal && obj1.bitStringContents === obj2.bitStringContents;
    return equal;
};
/**
 * Gets the length of a BER-encoded ASN.1 value.
 *
 * In case the length is not specified, undefined is returned.
 *
 * @param b the BER-encoded ASN.1 byte buffer, starting with the first
 *          length byte.
 *
 * @return the length of the BER-encoded ASN.1 value or undefined.
 */ asn1.getBerValueLength = function(b) {
    // TODO: move this function and related DER/BER functions to a der.js
    // file; better abstract ASN.1 away from der/ber.
    var b2 = b.getByte();
    if (b2 === 128) return undefined;
    // see if the length is "short form" or "long form" (bit 8 set)
    var length;
    var longForm = b2 & 128;
    if (!longForm) // length is just the first byte
    length = b2;
    else // the number of bytes the length is specified in bits 7 through 1
    // and each length byte is in big-endian base-256
    length = b.getInt((b2 & 127) << 3);
    return length;
};
/**
 * Check if the byte buffer has enough bytes. Throws an Error if not.
 *
 * @param bytes the byte buffer to parse from.
 * @param remaining the bytes remaining in the current parsing state.
 * @param n the number of bytes the buffer must have.
 */ function _checkBufferLength(bytes, remaining, n) {
    if (n > remaining) {
        var error = new Error('Too few bytes to parse DER.');
        error.available = bytes.length();
        error.remaining = remaining;
        error.requested = n;
        throw error;
    }
}
/**
 * Gets the length of a BER-encoded ASN.1 value.
 *
 * In case the length is not specified, undefined is returned.
 *
 * @param bytes the byte buffer to parse from.
 * @param remaining the bytes remaining in the current parsing state.
 *
 * @return the length of the BER-encoded ASN.1 value or undefined.
 */ var _getValueLength = function(bytes, remaining) {
    // TODO: move this function and related DER/BER functions to a der.js
    // file; better abstract ASN.1 away from der/ber.
    // fromDer already checked that this byte exists
    var b2 = bytes.getByte();
    remaining--;
    if (b2 === 128) return undefined;
    // see if the length is "short form" or "long form" (bit 8 set)
    var length;
    var longForm = b2 & 128;
    if (!longForm) // length is just the first byte
    length = b2;
    else {
        // the number of bytes the length is specified in bits 7 through 1
        // and each length byte is in big-endian base-256
        var longFormBytes = b2 & 127;
        _checkBufferLength(bytes, remaining, longFormBytes);
        length = bytes.getInt(longFormBytes << 3);
    }
    // FIXME: this will only happen for 32 bit getInt with high bit set
    if (length < 0) throw new Error('Negative length: ' + length);
    return length;
};
/**
 * Parses an asn1 object from a byte buffer in DER format.
 *
 * @param bytes the byte buffer to parse from.
 * @param [strict] true to be strict when checking value lengths, false to
 *          allow truncated values (default: true).
 * @param [options] object with options or boolean strict flag
 *          [strict] true to be strict when checking value lengths, false to
 *            allow truncated values (default: true).
 *          [decodeBitStrings] true to attempt to decode the content of
 *            BIT STRINGs (not OCTET STRINGs) using strict mode. Note that
 *            without schema support to understand the data context this can
 *            erroneously decode values that happen to be valid ASN.1. This
 *            flag will be deprecated or removed as soon as schema support is
 *            available. (default: true)
 *
 * @return the parsed asn1 object.
 */ asn1.fromDer = function(bytes, options) {
    if (options === undefined) options = {
        strict: true,
        decodeBitStrings: true
    };
    if (typeof options === 'boolean') options = {
        strict: options,
        decodeBitStrings: true
    };
    if (!('strict' in options)) options.strict = true;
    if (!('decodeBitStrings' in options)) options.decodeBitStrings = true;
    // wrap in buffer if needed
    if (typeof bytes === 'string') bytes = forge.util.createBuffer(bytes);
    return _fromDer(bytes, bytes.length(), 0, options);
};
/**
 * Internal function to parse an asn1 object from a byte buffer in DER format.
 *
 * @param bytes the byte buffer to parse from.
 * @param remaining the number of bytes remaining for this chunk.
 * @param depth the current parsing depth.
 * @param options object with same options as fromDer().
 *
 * @return the parsed asn1 object.
 */ function _fromDer(bytes, remaining, depth, options) {
    // temporary storage for consumption calculations
    var start;
    // minimum length for ASN.1 DER structure is 2
    _checkBufferLength(bytes, remaining, 2);
    // get the first byte
    var b1 = bytes.getByte();
    // consumed one byte
    remaining--;
    // get the tag class
    var tagClass = b1 & 192;
    // get the type (bits 1-5)
    var type = b1 & 31;
    // get the variable value length and adjust remaining bytes
    start = bytes.length();
    var length = _getValueLength(bytes, remaining);
    remaining -= start - bytes.length();
    // ensure there are enough bytes to get the value
    if (length !== undefined && length > remaining) {
        if (options.strict) {
            var error = new Error('Too few bytes to read ASN.1 value.');
            error.available = bytes.length();
            error.remaining = remaining;
            error.requested = length;
            throw error;
        }
        // Note: be lenient with truncated values and use remaining state bytes
        length = remaining;
    }
    // value storage
    var value;
    // possible BIT STRING contents storage
    var bitStringContents;
    // constructed flag is bit 6 (32 = 0x20) of the first byte
    var constructed = (b1 & 32) === 32;
    if (constructed) {
        // parse child asn1 objects from the value
        value = [];
        if (length === undefined) // asn1 object of indefinite length, read until end tag
        for(;;){
            _checkBufferLength(bytes, remaining, 2);
            if (bytes.bytes(2) === String.fromCharCode(0, 0)) {
                bytes.getBytes(2);
                remaining -= 2;
                break;
            }
            start = bytes.length();
            value.push(_fromDer(bytes, remaining, depth + 1, options));
            remaining -= start - bytes.length();
        }
        else // parsing asn1 object of definite length
        while(length > 0){
            start = bytes.length();
            value.push(_fromDer(bytes, length, depth + 1, options));
            remaining -= start - bytes.length();
            length -= start - bytes.length();
        }
    }
    // if a BIT STRING, save the contents including padding
    if (value === undefined && tagClass === asn1.Class.UNIVERSAL && type === asn1.Type.BITSTRING) bitStringContents = bytes.bytes(length);
    // determine if a non-constructed value should be decoded as a composed
    // value that contains other ASN.1 objects. BIT STRINGs (and OCTET STRINGs)
    // can be used this way.
    if (value === undefined && options.decodeBitStrings && tagClass === asn1.Class.UNIVERSAL && type === asn1.Type.BITSTRING /*|| type === asn1.Type.OCTETSTRING*/  && length > 1) {
        // save read position
        var savedRead = bytes.read;
        var savedRemaining = remaining;
        var unused = 0;
        if (type === asn1.Type.BITSTRING) {
            /* The first octet gives the number of bits by which the length of the
        bit string is less than the next multiple of eight (this is called
        the "number of unused bits").

        The second and following octets give the value of the bit string
        converted to an octet string. */ _checkBufferLength(bytes, remaining, 1);
            unused = bytes.getByte();
            remaining--;
        }
        // if all bits are used, maybe the BIT/OCTET STRING holds ASN.1 objs
        if (unused === 0) try {
            // attempt to parse child asn1 object from the value
            // (stored in array to signal composed value)
            start = bytes.length();
            var subOptions = {
                // enforce strict mode to avoid parsing ASN.1 from plain data
                verbose: options.verbose,
                strict: true,
                decodeBitStrings: true
            };
            var composed = _fromDer(bytes, remaining, depth + 1, subOptions);
            var used = start - bytes.length();
            remaining -= used;
            if (type == asn1.Type.BITSTRING) used++;
            // if the data all decoded and the class indicates UNIVERSAL or
            // CONTEXT_SPECIFIC then assume we've got an encapsulated ASN.1 object
            var tc = composed.tagClass;
            if (used === length && (tc === asn1.Class.UNIVERSAL || tc === asn1.Class.CONTEXT_SPECIFIC)) value = [
                composed
            ];
        } catch (ex) {
        }
        if (value === undefined) {
            // restore read position
            bytes.read = savedRead;
            remaining = savedRemaining;
        }
    }
    if (value === undefined) {
        // asn1 not constructed or composed, get raw value
        // TODO: do DER to OID conversion and vice-versa in .toDer?
        if (length === undefined) {
            if (options.strict) throw new Error('Non-constructed ASN.1 object of indefinite length.');
            // be lenient and use remaining state bytes
            length = remaining;
        }
        if (type === asn1.Type.BMPSTRING) {
            value = '';
            for(; length > 0; length -= 2){
                _checkBufferLength(bytes, remaining, 2);
                value += String.fromCharCode(bytes.getInt16());
                remaining -= 2;
            }
        } else value = bytes.getBytes(length);
    }
    // add BIT STRING contents if available
    var asn1Options = bitStringContents === undefined ? null : {
        bitStringContents: bitStringContents
    };
    // create and return asn1 object
    return asn1.create(tagClass, type, constructed, value, asn1Options);
}
/**
 * Converts the given asn1 object to a buffer of bytes in DER format.
 *
 * @param asn1 the asn1 object to convert to bytes.
 *
 * @return the buffer of bytes.
 */ asn1.toDer = function(obj) {
    var bytes = forge.util.createBuffer();
    // build the first byte
    var b1 = obj.tagClass | obj.type;
    // for storing the ASN.1 value
    var value = forge.util.createBuffer();
    // use BIT STRING contents if available and data not changed
    var useBitStringContents = false;
    if ('bitStringContents' in obj) {
        useBitStringContents = true;
        if (obj.original) useBitStringContents = asn1.equals(obj, obj.original);
    }
    if (useBitStringContents) value.putBytes(obj.bitStringContents);
    else if (obj.composed) {
        // if composed, use each child asn1 object's DER bytes as value
        // turn on 6th bit (0x20 = 32) to indicate asn1 is constructed
        // from other asn1 objects
        if (obj.constructed) b1 |= 32;
        else // type is a bit string, add unused bits of 0x00
        value.putByte(0);
        // add all of the child DER bytes together
        for(var i = 0; i < obj.value.length; ++i)if (obj.value[i] !== undefined) value.putBuffer(asn1.toDer(obj.value[i]));
    } else {
        // use asn1.value directly
        if (obj.type === asn1.Type.BMPSTRING) for(var i = 0; i < obj.value.length; ++i)value.putInt16(obj.value.charCodeAt(i));
        else // ensure integer is minimally-encoded
        // TODO: should all leading bytes be stripped vs just one?
        // .. ex '00 00 01' => '01'?
        if (obj.type === asn1.Type.INTEGER && obj.value.length > 1 && (obj.value.charCodeAt(0) === 0 && (obj.value.charCodeAt(1) & 128) === 0 || obj.value.charCodeAt(0) === 255 && (obj.value.charCodeAt(1) & 128) === 128)) value.putBytes(obj.value.substr(1));
        else value.putBytes(obj.value);
    }
    // add tag byte
    bytes.putByte(b1);
    // use "short form" encoding
    if (value.length() <= 127) // one byte describes the length
    // bit 8 = 0 and bits 7-1 = length
    bytes.putByte(value.length() & 127);
    else {
        // use "long form" encoding
        // 2 to 127 bytes describe the length
        // first byte: bit 8 = 1 and bits 7-1 = # of additional bytes
        // other bytes: length in base 256, big-endian
        var len = value.length();
        var lenBytes = '';
        do {
            lenBytes += String.fromCharCode(len & 255);
            len = len >>> 8;
        }while (len > 0)
        // set first byte to # bytes used to store the length and turn on
        // bit 8 to indicate long-form length is used
        bytes.putByte(lenBytes.length | 128);
        // concatenate length bytes in reverse since they were generated
        // little endian and we need big endian
        for(var i = lenBytes.length - 1; i >= 0; --i)bytes.putByte(lenBytes.charCodeAt(i));
    }
    // concatenate value bytes
    bytes.putBuffer(value);
    return bytes;
};
/**
 * Converts an OID dot-separated string to a byte buffer. The byte buffer
 * contains only the DER-encoded value, not any tag or length bytes.
 *
 * @param oid the OID dot-separated string.
 *
 * @return the byte buffer.
 */ asn1.oidToDer = function(oid) {
    // split OID into individual values
    var values = oid.split('.');
    var bytes = forge.util.createBuffer();
    // first byte is 40 * value1 + value2
    bytes.putByte(40 * parseInt(values[0], 10) + parseInt(values[1], 10));
    // other bytes are each value in base 128 with 8th bit set except for
    // the last byte for each value
    var last, valueBytes, value, b;
    for(var i = 2; i < values.length; ++i){
        // produce value bytes in reverse because we don't know how many
        // bytes it will take to store the value
        last = true;
        valueBytes = [];
        value = parseInt(values[i], 10);
        do {
            b = value & 127;
            value = value >>> 7;
            // if value is not last, then turn on 8th bit
            if (!last) b |= 128;
            valueBytes.push(b);
            last = false;
        }while (value > 0)
        // add value bytes in reverse (needs to be in big endian)
        for(var n = valueBytes.length - 1; n >= 0; --n)bytes.putByte(valueBytes[n]);
    }
    return bytes;
};
/**
 * Converts a DER-encoded byte buffer to an OID dot-separated string. The
 * byte buffer should contain only the DER-encoded value, not any tag or
 * length bytes.
 *
 * @param bytes the byte buffer.
 *
 * @return the OID dot-separated string.
 */ asn1.derToOid = function(bytes) {
    var oid;
    // wrap in buffer if needed
    if (typeof bytes === 'string') bytes = forge.util.createBuffer(bytes);
    // first byte is 40 * value1 + value2
    var b = bytes.getByte();
    oid = Math.floor(b / 40) + '.' + b % 40;
    // other bytes are each value in base 128 with 8th bit set except for
    // the last byte for each value
    var value = 0;
    while(bytes.length() > 0){
        b = bytes.getByte();
        value = value << 7;
        // not the last byte for the value
        if (b & 128) value += b & 127;
        else {
            // last byte
            oid += '.' + (value + b);
            value = 0;
        }
    }
    return oid;
};
/**
 * Converts a UTCTime value to a date.
 *
 * Note: GeneralizedTime has 4 digits for the year and is used for X.509
 * dates past 2049. Parsing that structure hasn't been implemented yet.
 *
 * @param utc the UTCTime value to convert.
 *
 * @return the date.
 */ asn1.utcTimeToDate = function(utc) {
    /* The following formats can be used:

    YYMMDDhhmmZ
    YYMMDDhhmm+hh'mm'
    YYMMDDhhmm-hh'mm'
    YYMMDDhhmmssZ
    YYMMDDhhmmss+hh'mm'
    YYMMDDhhmmss-hh'mm'

    Where:

    YY is the least significant two digits of the year
    MM is the month (01 to 12)
    DD is the day (01 to 31)
    hh is the hour (00 to 23)
    mm are the minutes (00 to 59)
    ss are the seconds (00 to 59)
    Z indicates that local time is GMT, + indicates that local time is
    later than GMT, and - indicates that local time is earlier than GMT
    hh' is the absolute value of the offset from GMT in hours
    mm' is the absolute value of the offset from GMT in minutes */ var date = new Date();
    // if YY >= 50 use 19xx, if YY < 50 use 20xx
    var year = parseInt(utc.substr(0, 2), 10);
    year = year >= 50 ? 1900 + year : 2000 + year;
    var MM = parseInt(utc.substr(2, 2), 10) - 1; // use 0-11 for month
    var DD = parseInt(utc.substr(4, 2), 10);
    var hh = parseInt(utc.substr(6, 2), 10);
    var mm = parseInt(utc.substr(8, 2), 10);
    var ss = 0;
    // not just YYMMDDhhmmZ
    if (utc.length > 11) {
        // get character after minutes
        var c = utc.charAt(10);
        var end = 10;
        // see if seconds are present
        if (c !== '+' && c !== '-') {
            // get seconds
            ss = parseInt(utc.substr(10, 2), 10);
            end += 2;
        }
    }
    // update date
    date.setUTCFullYear(year, MM, DD);
    date.setUTCHours(hh, mm, ss, 0);
    if (end) {
        // get +/- after end of time
        c = utc.charAt(end);
        if (c === '+' || c === '-') {
            // get hours+minutes offset
            var hhoffset = parseInt(utc.substr(end + 1, 2), 10);
            var mmoffset = parseInt(utc.substr(end + 4, 2), 10);
            // calculate offset in milliseconds
            var offset = hhoffset * 60 + mmoffset;
            offset *= 60000;
            // apply offset
            if (c === '+') date.setTime(+date - offset);
            else date.setTime(+date + offset);
        }
    }
    return date;
};
/**
 * Converts a GeneralizedTime value to a date.
 *
 * @param gentime the GeneralizedTime value to convert.
 *
 * @return the date.
 */ asn1.generalizedTimeToDate = function(gentime) {
    /* The following formats can be used:

    YYYYMMDDHHMMSS
    YYYYMMDDHHMMSS.fff
    YYYYMMDDHHMMSSZ
    YYYYMMDDHHMMSS.fffZ
    YYYYMMDDHHMMSS+hh'mm'
    YYYYMMDDHHMMSS.fff+hh'mm'
    YYYYMMDDHHMMSS-hh'mm'
    YYYYMMDDHHMMSS.fff-hh'mm'

    Where:

    YYYY is the year
    MM is the month (01 to 12)
    DD is the day (01 to 31)
    hh is the hour (00 to 23)
    mm are the minutes (00 to 59)
    ss are the seconds (00 to 59)
    .fff is the second fraction, accurate to three decimal places
    Z indicates that local time is GMT, + indicates that local time is
    later than GMT, and - indicates that local time is earlier than GMT
    hh' is the absolute value of the offset from GMT in hours
    mm' is the absolute value of the offset from GMT in minutes */ var date = new Date();
    var YYYY = parseInt(gentime.substr(0, 4), 10);
    var MM = parseInt(gentime.substr(4, 2), 10) - 1; // use 0-11 for month
    var DD = parseInt(gentime.substr(6, 2), 10);
    var hh = parseInt(gentime.substr(8, 2), 10);
    var mm = parseInt(gentime.substr(10, 2), 10);
    var ss = parseInt(gentime.substr(12, 2), 10);
    var fff = 0;
    var offset = 0;
    var isUTC = false;
    if (gentime.charAt(gentime.length - 1) === 'Z') isUTC = true;
    var end = gentime.length - 5, c = gentime.charAt(end);
    if (c === '+' || c === '-') {
        // get hours+minutes offset
        var hhoffset = parseInt(gentime.substr(end + 1, 2), 10);
        var mmoffset = parseInt(gentime.substr(end + 4, 2), 10);
        // calculate offset in milliseconds
        offset = hhoffset * 60 + mmoffset;
        offset *= 60000;
        // apply offset
        if (c === '+') offset *= -1;
        isUTC = true;
    }
    // check for second fraction
    if (gentime.charAt(14) === '.') fff = parseFloat(gentime.substr(14), 10) * 1000;
    if (isUTC) {
        date.setUTCFullYear(YYYY, MM, DD);
        date.setUTCHours(hh, mm, ss, fff);
        // apply offset
        date.setTime(+date + offset);
    } else {
        date.setFullYear(YYYY, MM, DD);
        date.setHours(hh, mm, ss, fff);
    }
    return date;
};
/**
 * Converts a date to a UTCTime value.
 *
 * Note: GeneralizedTime has 4 digits for the year and is used for X.509
 * dates past 2049. Converting to a GeneralizedTime hasn't been
 * implemented yet.
 *
 * @param date the date to convert.
 *
 * @return the UTCTime value.
 */ asn1.dateToUtcTime = function(date) {
    // TODO: validate; currently assumes proper format
    if (typeof date === 'string') return date;
    var rval = '';
    // create format YYMMDDhhmmssZ
    var format = [];
    format.push(('' + date.getUTCFullYear()).substr(2));
    format.push('' + (date.getUTCMonth() + 1));
    format.push('' + date.getUTCDate());
    format.push('' + date.getUTCHours());
    format.push('' + date.getUTCMinutes());
    format.push('' + date.getUTCSeconds());
    // ensure 2 digits are used for each format entry
    for(var i = 0; i < format.length; ++i){
        if (format[i].length < 2) rval += '0';
        rval += format[i];
    }
    rval += 'Z';
    return rval;
};
/**
 * Converts a date to a GeneralizedTime value.
 *
 * @param date the date to convert.
 *
 * @return the GeneralizedTime value as a string.
 */ asn1.dateToGeneralizedTime = function(date) {
    // TODO: validate; currently assumes proper format
    if (typeof date === 'string') return date;
    var rval = '';
    // create format YYYYMMDDHHMMSSZ
    var format = [];
    format.push('' + date.getUTCFullYear());
    format.push('' + (date.getUTCMonth() + 1));
    format.push('' + date.getUTCDate());
    format.push('' + date.getUTCHours());
    format.push('' + date.getUTCMinutes());
    format.push('' + date.getUTCSeconds());
    // ensure 2 digits are used for each format entry
    for(var i = 0; i < format.length; ++i){
        if (format[i].length < 2) rval += '0';
        rval += format[i];
    }
    rval += 'Z';
    return rval;
};
/**
 * Converts a javascript integer to a DER-encoded byte buffer to be used
 * as the value for an INTEGER type.
 *
 * @param x the integer.
 *
 * @return the byte buffer.
 */ asn1.integerToDer = function(x) {
    var rval = forge.util.createBuffer();
    if (x >= -128 && x < 128) return rval.putSignedInt(x, 8);
    if (x >= -32768 && x < 32768) return rval.putSignedInt(x, 16);
    if (x >= -8388608 && x < 8388608) return rval.putSignedInt(x, 24);
    if (x >= -2147483648 && x < 2147483648) return rval.putSignedInt(x, 32);
    var error = new Error('Integer too large; max is 32-bits.');
    error.integer = x;
    throw error;
};
/**
 * Converts a DER-encoded byte buffer to a javascript integer. This is
 * typically used to decode the value of an INTEGER type.
 *
 * @param bytes the byte buffer.
 *
 * @return the integer.
 */ asn1.derToInteger = function(bytes) {
    // wrap in buffer if needed
    if (typeof bytes === 'string') bytes = forge.util.createBuffer(bytes);
    var n = bytes.length() * 8;
    if (n > 32) throw new Error('Integer too large; max is 32-bits.');
    return bytes.getSignedInt(n);
};
/**
 * Validates that the given ASN.1 object is at least a super set of the
 * given ASN.1 structure. Only tag classes and types are checked. An
 * optional map may also be provided to capture ASN.1 values while the
 * structure is checked.
 *
 * To capture an ASN.1 value, set an object in the validator's 'capture'
 * parameter to the key to use in the capture map. To capture the full
 * ASN.1 object, specify 'captureAsn1'. To capture BIT STRING bytes, including
 * the leading unused bits counter byte, specify 'captureBitStringContents'.
 * To capture BIT STRING bytes, without the leading unused bits counter byte,
 * specify 'captureBitStringValue'.
 *
 * Objects in the validator may set a field 'optional' to true to indicate
 * that it isn't necessary to pass validation.
 *
 * @param obj the ASN.1 object to validate.
 * @param v the ASN.1 structure validator.
 * @param capture an optional map to capture values in.
 * @param errors an optional array for storing validation errors.
 *
 * @return true on success, false on failure.
 */ asn1.validate = function(obj, v, capture, errors) {
    var rval = false;
    // ensure tag class and type are the same if specified
    if ((obj.tagClass === v.tagClass || typeof v.tagClass === 'undefined') && (obj.type === v.type || typeof v.type === 'undefined')) {
        // ensure constructed flag is the same if specified
        if (obj.constructed === v.constructed || typeof v.constructed === 'undefined') {
            rval = true;
            // handle sub values
            if (v.value && forge.util.isArray(v.value)) {
                var j = 0;
                for(var i = 0; rval && i < v.value.length; ++i){
                    rval = v.value[i].optional || false;
                    if (obj.value[j]) {
                        rval = asn1.validate(obj.value[j], v.value[i], capture, errors);
                        if (rval) ++j;
                        else if (v.value[i].optional) rval = true;
                    }
                    if (!rval && errors) errors.push('[' + v.name + '] ' + 'Tag class "' + v.tagClass + '", type "' + v.type + '" expected value length "' + v.value.length + '", got "' + obj.value.length + '"');
                }
            }
            if (rval && capture) {
                if (v.capture) capture[v.capture] = obj.value;
                if (v.captureAsn1) capture[v.captureAsn1] = obj;
                if (v.captureBitStringContents && 'bitStringContents' in obj) capture[v.captureBitStringContents] = obj.bitStringContents;
                if (v.captureBitStringValue && 'bitStringContents' in obj) {
                    var value;
                    if (obj.bitStringContents.length < 2) capture[v.captureBitStringValue] = '';
                    else {
                        // FIXME: support unused bits with data shifting
                        var unused = obj.bitStringContents.charCodeAt(0);
                        if (unused !== 0) throw new Error('captureBitStringValue only supported for zero unused bits');
                        capture[v.captureBitStringValue] = obj.bitStringContents.slice(1);
                    }
                }
            }
        } else if (errors) errors.push('[' + v.name + '] ' + 'Expected constructed "' + v.constructed + '", got "' + obj.constructed + '"');
    } else if (errors) {
        if (obj.tagClass !== v.tagClass) errors.push('[' + v.name + '] ' + 'Expected tag class "' + v.tagClass + '", got "' + obj.tagClass + '"');
        if (obj.type !== v.type) errors.push('[' + v.name + '] ' + 'Expected type "' + v.type + '", got "' + obj.type + '"');
    }
    return rval;
};
// regex for testing for non-latin characters
var _nonLatinRegex = /[^\\u0000-\\u00ff]/;
/**
 * Pretty prints an ASN.1 object to a string.
 *
 * @param obj the object to write out.
 * @param level the level in the tree.
 * @param indentation the indentation to use.
 *
 * @return the string.
 */ asn1.prettyPrint = function(obj, level, indentation) {
    var rval = '';
    // set default level and indentation
    level = level || 0;
    indentation = indentation || 2;
    // start new line for deep levels
    if (level > 0) rval += '\n';
    // create indent
    var indent = '';
    for(var i = 0; i < level * indentation; ++i)indent += ' ';
    // print class:type
    rval += indent + 'Tag: ';
    switch(obj.tagClass){
        case asn1.Class.UNIVERSAL:
            rval += 'Universal:';
            break;
        case asn1.Class.APPLICATION:
            rval += 'Application:';
            break;
        case asn1.Class.CONTEXT_SPECIFIC:
            rval += 'Context-Specific:';
            break;
        case asn1.Class.PRIVATE:
            rval += 'Private:';
            break;
    }
    if (obj.tagClass === asn1.Class.UNIVERSAL) {
        rval += obj.type;
        // known types
        switch(obj.type){
            case asn1.Type.NONE:
                rval += ' (None)';
                break;
            case asn1.Type.BOOLEAN:
                rval += ' (Boolean)';
                break;
            case asn1.Type.INTEGER:
                rval += ' (Integer)';
                break;
            case asn1.Type.BITSTRING:
                rval += ' (Bit string)';
                break;
            case asn1.Type.OCTETSTRING:
                rval += ' (Octet string)';
                break;
            case asn1.Type.NULL:
                rval += ' (Null)';
                break;
            case asn1.Type.OID:
                rval += ' (Object Identifier)';
                break;
            case asn1.Type.ODESC:
                rval += ' (Object Descriptor)';
                break;
            case asn1.Type.EXTERNAL:
                rval += ' (External or Instance of)';
                break;
            case asn1.Type.REAL:
                rval += ' (Real)';
                break;
            case asn1.Type.ENUMERATED:
                rval += ' (Enumerated)';
                break;
            case asn1.Type.EMBEDDED:
                rval += ' (Embedded PDV)';
                break;
            case asn1.Type.UTF8:
                rval += ' (UTF8)';
                break;
            case asn1.Type.ROID:
                rval += ' (Relative Object Identifier)';
                break;
            case asn1.Type.SEQUENCE:
                rval += ' (Sequence)';
                break;
            case asn1.Type.SET:
                rval += ' (Set)';
                break;
            case asn1.Type.PRINTABLESTRING:
                rval += ' (Printable String)';
                break;
            case asn1.Type.IA5String:
                rval += ' (IA5String (ASCII))';
                break;
            case asn1.Type.UTCTIME:
                rval += ' (UTC time)';
                break;
            case asn1.Type.GENERALIZEDTIME:
                rval += ' (Generalized time)';
                break;
            case asn1.Type.BMPSTRING:
                rval += ' (BMP String)';
                break;
        }
    } else rval += obj.type;
    rval += '\n';
    rval += indent + 'Constructed: ' + obj.constructed + '\n';
    if (obj.composed) {
        var subvalues = 0;
        var sub = '';
        for(var i = 0; i < obj.value.length; ++i)if (obj.value[i] !== undefined) {
            subvalues += 1;
            sub += asn1.prettyPrint(obj.value[i], level + 1, indentation);
            if (i + 1 < obj.value.length) sub += ',';
        }
        rval += indent + 'Sub values: ' + subvalues + sub;
    } else {
        rval += indent + 'Value: ';
        if (obj.type === asn1.Type.OID) {
            var oid = asn1.derToOid(obj.value);
            rval += oid;
            if (forge.pki && forge.pki.oids) {
                if (oid in forge.pki.oids) rval += ' (' + forge.pki.oids[oid] + ') ';
            }
        }
        if (obj.type === asn1.Type.INTEGER) try {
            rval += asn1.derToInteger(obj.value);
        } catch (ex) {
            rval += '0x' + forge.util.bytesToHex(obj.value);
        }
        else if (obj.type === asn1.Type.BITSTRING) {
            // TODO: shift bits as needed to display without padding
            if (obj.value.length > 1) // remove unused bits field
            rval += '0x' + forge.util.bytesToHex(obj.value.slice(1));
            else rval += '(none)';
            // show unused bit count
            if (obj.value.length > 0) {
                var unused = obj.value.charCodeAt(0);
                if (unused == 1) rval += ' (1 unused bit shown)';
                else if (unused > 1) rval += ' (' + unused + ' unused bits shown)';
            }
        } else if (obj.type === asn1.Type.OCTETSTRING) {
            if (!_nonLatinRegex.test(obj.value)) rval += '(' + obj.value + ') ';
            rval += '0x' + forge.util.bytesToHex(obj.value);
        } else if (obj.type === asn1.Type.UTF8) rval += forge.util.decodeUtf8(obj.value);
        else if (obj.type === asn1.Type.PRINTABLESTRING || obj.type === asn1.Type.IA5String) rval += obj.value;
        else if (_nonLatinRegex.test(obj.value)) rval += '0x' + forge.util.bytesToHex(obj.value);
        else if (obj.value.length === 0) rval += '[null]';
        else rval += obj.value;
    }
    return rval;
};

},{"./forge":"7AnVp","./util":"cHj6b","./oids":"iymJu"}],"7AnVp":[function(require,module,exports) {
/**
 * Node.js module for Forge.
 *
 * @author Dave Longley
 *
 * Copyright 2011-2016 Digital Bazaar, Inc.
 */ module.exports = {
    // default options
    options: {
        usePureJavaScript: false
    }
};

},{}],"cHj6b":[function(require,module,exports) {
var Buffer = require("buffer").Buffer;
var process = require("process");
var global = arguments[3];
/**
 * Utility functions for web applications.
 *
 * @author Dave Longley
 *
 * Copyright (c) 2010-2018 Digital Bazaar, Inc.
 */ var forge = require('./forge');
var baseN = require('./baseN');
/* Utilities API */ var util = module.exports = forge.util = forge.util || {
};
// define setImmediate and nextTick
(function() {
    typeof process !== 'undefined' && process.nextTick;
    // polyfill nextTick with native setImmediate
    if (typeof setImmediate === 'function') {
        util.setImmediate = function() {
            return setImmediate.apply(undefined, arguments);
        };
        util.nextTick = function(callback) {
            return setImmediate(callback);
        };
        return;
    }
    /* Note: A polyfill upgrade pattern is used here to allow combining
  polyfills. For example, MutationObserver is fast, but blocks UI updates,
  so it needs to allow UI updates periodically, so it falls back on
  postMessage or setTimeout. */ // polyfill with setTimeout
    util.setImmediate = function(callback) {
        setTimeout(callback, 0);
    };
    // upgrade polyfill to use postMessage
    if (typeof window !== 'undefined' && typeof window.postMessage === 'function') {
        var msg = 'forge.setImmediate';
        var callbacks = [];
        util.setImmediate = function(callback) {
            callbacks.push(callback);
            // only send message when one hasn't been sent in
            // the current turn of the event loop
            if (callbacks.length === 1) window.postMessage(msg, '*');
        };
        function handler(event) {
            if (event.source === window && event.data === msg) {
                event.stopPropagation();
                var copy = callbacks.slice();
                callbacks.length = 0;
                copy.forEach(function(callback) {
                    callback();
                });
            }
        }
        window.addEventListener('message', handler, true);
    }
    // upgrade polyfill to use MutationObserver
    if (typeof MutationObserver !== 'undefined') {
        // polyfill with MutationObserver
        var now = Date.now();
        var attr = true;
        var div = document.createElement('div');
        var callbacks = [];
        new MutationObserver(function() {
            var copy = callbacks.slice();
            callbacks.length = 0;
            copy.forEach(function(callback) {
                callback();
            });
        }).observe(div, {
            attributes: true
        });
        var oldSetImmediate = util.setImmediate;
        util.setImmediate = function(callback) {
            if (Date.now() - now > 15) {
                now = Date.now();
                oldSetImmediate(callback);
            } else {
                callbacks.push(callback);
                // only trigger observer when it hasn't been triggered in
                // the current turn of the event loop
                if (callbacks.length === 1) div.setAttribute('a', attr = !attr);
            }
        };
    }
    util.nextTick = util.setImmediate;
})();
// check if running under Node.js
util.isNodejs = typeof process !== 'undefined' && process.versions && process.versions.node;
// 'self' will also work in Web Workers (instance of WorkerGlobalScope) while
// it will point to `window` in the main thread.
// To remain compatible with older browsers, we fall back to 'window' if 'self'
// is not available.
util.globalScope = (function() {
    if (util.isNodejs) return global;
    return typeof self === 'undefined' ? window : self;
})();
// define isArray
util.isArray = Array.isArray || function(x) {
    return Object.prototype.toString.call(x) === '[object Array]';
};
// define isArrayBuffer
util.isArrayBuffer = function(x) {
    return typeof ArrayBuffer !== 'undefined' && x instanceof ArrayBuffer;
};
// define isArrayBufferView
util.isArrayBufferView = function(x) {
    return x && util.isArrayBuffer(x.buffer) && x.byteLength !== undefined;
};
/**
 * Ensure a bits param is 8, 16, 24, or 32. Used to validate input for
 * algorithms where bit manipulation, JavaScript limitations, and/or algorithm
 * design only allow for byte operations of a limited size.
 *
 * @param n number of bits.
 *
 * Throw Error if n invalid.
 */ function _checkBitsParam(n) {
    if (!(n === 8 || n === 16 || n === 24 || n === 32)) throw new Error('Only 8, 16, 24, or 32 bits supported: ' + n);
}
// TODO: set ByteBuffer to best available backing
util.ByteBuffer = ByteStringBuffer;
/** Buffer w/BinaryString backing */ /**
 * Constructor for a binary string backed byte buffer.
 *
 * @param [b] the bytes to wrap (either encoded as string, one byte per
 *          character, or as an ArrayBuffer or Typed Array).
 */ function ByteStringBuffer(b) {
    // TODO: update to match DataBuffer API
    // the data in this buffer
    this.data = '';
    // the pointer for reading from this buffer
    this.read = 0;
    if (typeof b === 'string') this.data = b;
    else if (util.isArrayBuffer(b) || util.isArrayBufferView(b)) {
        if (typeof Buffer !== 'undefined' && b instanceof Buffer) this.data = b.toString('binary');
        else {
            // convert native buffer to forge buffer
            // FIXME: support native buffers internally instead
            var arr = new Uint8Array(b);
            try {
                this.data = String.fromCharCode.apply(null, arr);
            } catch (e) {
                for(var i = 0; i < arr.length; ++i)this.putByte(arr[i]);
            }
        }
    } else if (b instanceof ByteStringBuffer || typeof b === 'object' && typeof b.data === 'string' && typeof b.read === 'number') {
        // copy existing buffer
        this.data = b.data;
        this.read = b.read;
    }
    // used for v8 optimization
    this._constructedStringLength = 0;
}
util.ByteStringBuffer = ByteStringBuffer;
/* Note: This is an optimization for V8-based browsers. When V8 concatenates
  a string, the strings are only joined logically using a "cons string" or
  "constructed/concatenated string". These containers keep references to one
  another and can result in very large memory usage. For example, if a 2MB
  string is constructed by concatenating 4 bytes together at a time, the
  memory usage will be ~44MB; so ~22x increase. The strings are only joined
  together when an operation requiring their joining takes place, such as
  substr(). This function is called when adding data to this buffer to ensure
  these types of strings are periodically joined to reduce the memory
  footprint. */ var _MAX_CONSTRUCTED_STRING_LENGTH = 4096;
util.ByteStringBuffer.prototype._optimizeConstructedString = function(x) {
    this._constructedStringLength += x;
    if (this._constructedStringLength > _MAX_CONSTRUCTED_STRING_LENGTH) {
        // this substr() should cause the constructed string to join
        this.data.substr(0, 1);
        this._constructedStringLength = 0;
    }
};
/**
 * Gets the number of bytes in this buffer.
 *
 * @return the number of bytes in this buffer.
 */ util.ByteStringBuffer.prototype.length = function() {
    return this.data.length - this.read;
};
/**
 * Gets whether or not this buffer is empty.
 *
 * @return true if this buffer is empty, false if not.
 */ util.ByteStringBuffer.prototype.isEmpty = function() {
    return this.length() <= 0;
};
/**
 * Puts a byte in this buffer.
 *
 * @param b the byte to put.
 *
 * @return this buffer.
 */ util.ByteStringBuffer.prototype.putByte = function(b) {
    return this.putBytes(String.fromCharCode(b));
};
/**
 * Puts a byte in this buffer N times.
 *
 * @param b the byte to put.
 * @param n the number of bytes of value b to put.
 *
 * @return this buffer.
 */ util.ByteStringBuffer.prototype.fillWithByte = function(b, n) {
    b = String.fromCharCode(b);
    var d = this.data;
    while(n > 0){
        if (n & 1) d += b;
        n >>>= 1;
        if (n > 0) b += b;
    }
    this.data = d;
    this._optimizeConstructedString(n);
    return this;
};
/**
 * Puts bytes in this buffer.
 *
 * @param bytes the bytes (as a binary encoded string) to put.
 *
 * @return this buffer.
 */ util.ByteStringBuffer.prototype.putBytes = function(bytes) {
    this.data += bytes;
    this._optimizeConstructedString(bytes.length);
    return this;
};
/**
 * Puts a UTF-16 encoded string into this buffer.
 *
 * @param str the string to put.
 *
 * @return this buffer.
 */ util.ByteStringBuffer.prototype.putString = function(str) {
    return this.putBytes(util.encodeUtf8(str));
};
/**
 * Puts a 16-bit integer in this buffer in big-endian order.
 *
 * @param i the 16-bit integer.
 *
 * @return this buffer.
 */ util.ByteStringBuffer.prototype.putInt16 = function(i) {
    return this.putBytes(String.fromCharCode(i >> 8 & 255) + String.fromCharCode(i & 255));
};
/**
 * Puts a 24-bit integer in this buffer in big-endian order.
 *
 * @param i the 24-bit integer.
 *
 * @return this buffer.
 */ util.ByteStringBuffer.prototype.putInt24 = function(i) {
    return this.putBytes(String.fromCharCode(i >> 16 & 255) + String.fromCharCode(i >> 8 & 255) + String.fromCharCode(i & 255));
};
/**
 * Puts a 32-bit integer in this buffer in big-endian order.
 *
 * @param i the 32-bit integer.
 *
 * @return this buffer.
 */ util.ByteStringBuffer.prototype.putInt32 = function(i) {
    return this.putBytes(String.fromCharCode(i >> 24 & 255) + String.fromCharCode(i >> 16 & 255) + String.fromCharCode(i >> 8 & 255) + String.fromCharCode(i & 255));
};
/**
 * Puts a 16-bit integer in this buffer in little-endian order.
 *
 * @param i the 16-bit integer.
 *
 * @return this buffer.
 */ util.ByteStringBuffer.prototype.putInt16Le = function(i) {
    return this.putBytes(String.fromCharCode(i & 255) + String.fromCharCode(i >> 8 & 255));
};
/**
 * Puts a 24-bit integer in this buffer in little-endian order.
 *
 * @param i the 24-bit integer.
 *
 * @return this buffer.
 */ util.ByteStringBuffer.prototype.putInt24Le = function(i) {
    return this.putBytes(String.fromCharCode(i & 255) + String.fromCharCode(i >> 8 & 255) + String.fromCharCode(i >> 16 & 255));
};
/**
 * Puts a 32-bit integer in this buffer in little-endian order.
 *
 * @param i the 32-bit integer.
 *
 * @return this buffer.
 */ util.ByteStringBuffer.prototype.putInt32Le = function(i) {
    return this.putBytes(String.fromCharCode(i & 255) + String.fromCharCode(i >> 8 & 255) + String.fromCharCode(i >> 16 & 255) + String.fromCharCode(i >> 24 & 255));
};
/**
 * Puts an n-bit integer in this buffer in big-endian order.
 *
 * @param i the n-bit integer.
 * @param n the number of bits in the integer (8, 16, 24, or 32).
 *
 * @return this buffer.
 */ util.ByteStringBuffer.prototype.putInt = function(i, n) {
    _checkBitsParam(n);
    var bytes = '';
    do {
        n -= 8;
        bytes += String.fromCharCode(i >> n & 255);
    }while (n > 0)
    return this.putBytes(bytes);
};
/**
 * Puts a signed n-bit integer in this buffer in big-endian order. Two's
 * complement representation is used.
 *
 * @param i the n-bit integer.
 * @param n the number of bits in the integer (8, 16, 24, or 32).
 *
 * @return this buffer.
 */ util.ByteStringBuffer.prototype.putSignedInt = function(i, n) {
    // putInt checks n
    if (i < 0) i += 2 << n - 1;
    return this.putInt(i, n);
};
/**
 * Puts the given buffer into this buffer.
 *
 * @param buffer the buffer to put into this one.
 *
 * @return this buffer.
 */ util.ByteStringBuffer.prototype.putBuffer = function(buffer) {
    return this.putBytes(buffer.getBytes());
};
/**
 * Gets a byte from this buffer and advances the read pointer by 1.
 *
 * @return the byte.
 */ util.ByteStringBuffer.prototype.getByte = function() {
    return this.data.charCodeAt(this.read++);
};
/**
 * Gets a uint16 from this buffer in big-endian order and advances the read
 * pointer by 2.
 *
 * @return the uint16.
 */ util.ByteStringBuffer.prototype.getInt16 = function() {
    var rval = this.data.charCodeAt(this.read) << 8 ^ this.data.charCodeAt(this.read + 1);
    this.read += 2;
    return rval;
};
/**
 * Gets a uint24 from this buffer in big-endian order and advances the read
 * pointer by 3.
 *
 * @return the uint24.
 */ util.ByteStringBuffer.prototype.getInt24 = function() {
    var rval = this.data.charCodeAt(this.read) << 16 ^ this.data.charCodeAt(this.read + 1) << 8 ^ this.data.charCodeAt(this.read + 2);
    this.read += 3;
    return rval;
};
/**
 * Gets a uint32 from this buffer in big-endian order and advances the read
 * pointer by 4.
 *
 * @return the word.
 */ util.ByteStringBuffer.prototype.getInt32 = function() {
    var rval = this.data.charCodeAt(this.read) << 24 ^ this.data.charCodeAt(this.read + 1) << 16 ^ this.data.charCodeAt(this.read + 2) << 8 ^ this.data.charCodeAt(this.read + 3);
    this.read += 4;
    return rval;
};
/**
 * Gets a uint16 from this buffer in little-endian order and advances the read
 * pointer by 2.
 *
 * @return the uint16.
 */ util.ByteStringBuffer.prototype.getInt16Le = function() {
    var rval = this.data.charCodeAt(this.read) ^ this.data.charCodeAt(this.read + 1) << 8;
    this.read += 2;
    return rval;
};
/**
 * Gets a uint24 from this buffer in little-endian order and advances the read
 * pointer by 3.
 *
 * @return the uint24.
 */ util.ByteStringBuffer.prototype.getInt24Le = function() {
    var rval = this.data.charCodeAt(this.read) ^ this.data.charCodeAt(this.read + 1) << 8 ^ this.data.charCodeAt(this.read + 2) << 16;
    this.read += 3;
    return rval;
};
/**
 * Gets a uint32 from this buffer in little-endian order and advances the read
 * pointer by 4.
 *
 * @return the word.
 */ util.ByteStringBuffer.prototype.getInt32Le = function() {
    var rval = this.data.charCodeAt(this.read) ^ this.data.charCodeAt(this.read + 1) << 8 ^ this.data.charCodeAt(this.read + 2) << 16 ^ this.data.charCodeAt(this.read + 3) << 24;
    this.read += 4;
    return rval;
};
/**
 * Gets an n-bit integer from this buffer in big-endian order and advances the
 * read pointer by ceil(n/8).
 *
 * @param n the number of bits in the integer (8, 16, 24, or 32).
 *
 * @return the integer.
 */ util.ByteStringBuffer.prototype.getInt = function(n) {
    _checkBitsParam(n);
    var rval = 0;
    do {
        // TODO: Use (rval * 0x100) if adding support for 33 to 53 bits.
        rval = (rval << 8) + this.data.charCodeAt(this.read++);
        n -= 8;
    }while (n > 0)
    return rval;
};
/**
 * Gets a signed n-bit integer from this buffer in big-endian order, using
 * two's complement, and advances the read pointer by n/8.
 *
 * @param n the number of bits in the integer (8, 16, 24, or 32).
 *
 * @return the integer.
 */ util.ByteStringBuffer.prototype.getSignedInt = function(n) {
    // getInt checks n
    var x = this.getInt(n);
    var max = 2 << n - 2;
    if (x >= max) x -= max << 1;
    return x;
};
/**
 * Reads bytes out as a binary encoded string and clears them from the
 * buffer. Note that the resulting string is binary encoded (in node.js this
 * encoding is referred to as `binary`, it is *not* `utf8`).
 *
 * @param count the number of bytes to read, undefined or null for all.
 *
 * @return a binary encoded string of bytes.
 */ util.ByteStringBuffer.prototype.getBytes = function(count) {
    var rval;
    if (count) {
        // read count bytes
        count = Math.min(this.length(), count);
        rval = this.data.slice(this.read, this.read + count);
        this.read += count;
    } else if (count === 0) rval = '';
    else {
        // read all bytes, optimize to only copy when needed
        rval = this.read === 0 ? this.data : this.data.slice(this.read);
        this.clear();
    }
    return rval;
};
/**
 * Gets a binary encoded string of the bytes from this buffer without
 * modifying the read pointer.
 *
 * @param count the number of bytes to get, omit to get all.
 *
 * @return a string full of binary encoded characters.
 */ util.ByteStringBuffer.prototype.bytes = function(count) {
    return typeof count === 'undefined' ? this.data.slice(this.read) : this.data.slice(this.read, this.read + count);
};
/**
 * Gets a byte at the given index without modifying the read pointer.
 *
 * @param i the byte index.
 *
 * @return the byte.
 */ util.ByteStringBuffer.prototype.at = function(i) {
    return this.data.charCodeAt(this.read + i);
};
/**
 * Puts a byte at the given index without modifying the read pointer.
 *
 * @param i the byte index.
 * @param b the byte to put.
 *
 * @return this buffer.
 */ util.ByteStringBuffer.prototype.setAt = function(i, b) {
    this.data = this.data.substr(0, this.read + i) + String.fromCharCode(b) + this.data.substr(this.read + i + 1);
    return this;
};
/**
 * Gets the last byte without modifying the read pointer.
 *
 * @return the last byte.
 */ util.ByteStringBuffer.prototype.last = function() {
    return this.data.charCodeAt(this.data.length - 1);
};
/**
 * Creates a copy of this buffer.
 *
 * @return the copy.
 */ util.ByteStringBuffer.prototype.copy = function() {
    var c = util.createBuffer(this.data);
    c.read = this.read;
    return c;
};
/**
 * Compacts this buffer.
 *
 * @return this buffer.
 */ util.ByteStringBuffer.prototype.compact = function() {
    if (this.read > 0) {
        this.data = this.data.slice(this.read);
        this.read = 0;
    }
    return this;
};
/**
 * Clears this buffer.
 *
 * @return this buffer.
 */ util.ByteStringBuffer.prototype.clear = function() {
    this.data = '';
    this.read = 0;
    return this;
};
/**
 * Shortens this buffer by triming bytes off of the end of this buffer.
 *
 * @param count the number of bytes to trim off.
 *
 * @return this buffer.
 */ util.ByteStringBuffer.prototype.truncate = function(count) {
    var len = Math.max(0, this.length() - count);
    this.data = this.data.substr(this.read, len);
    this.read = 0;
    return this;
};
/**
 * Converts this buffer to a hexadecimal string.
 *
 * @return a hexadecimal string.
 */ util.ByteStringBuffer.prototype.toHex = function() {
    var rval = '';
    for(var i = this.read; i < this.data.length; ++i){
        var b = this.data.charCodeAt(i);
        if (b < 16) rval += '0';
        rval += b.toString(16);
    }
    return rval;
};
/**
 * Converts this buffer to a UTF-16 string (standard JavaScript string).
 *
 * @return a UTF-16 string.
 */ util.ByteStringBuffer.prototype.toString = function() {
    return util.decodeUtf8(this.bytes());
};
/** End Buffer w/BinaryString backing */ /** Buffer w/UInt8Array backing */ /**
 * FIXME: Experimental. Do not use yet.
 *
 * Constructor for an ArrayBuffer-backed byte buffer.
 *
 * The buffer may be constructed from a string, an ArrayBuffer, DataView, or a
 * TypedArray.
 *
 * If a string is given, its encoding should be provided as an option,
 * otherwise it will default to 'binary'. A 'binary' string is encoded such
 * that each character is one byte in length and size.
 *
 * If an ArrayBuffer, DataView, or TypedArray is given, it will be used
 * *directly* without any copying. Note that, if a write to the buffer requires
 * more space, the buffer will allocate a new backing ArrayBuffer to
 * accommodate. The starting read and write offsets for the buffer may be
 * given as options.
 *
 * @param [b] the initial bytes for this buffer.
 * @param options the options to use:
 *          [readOffset] the starting read offset to use (default: 0).
 *          [writeOffset] the starting write offset to use (default: the
 *            length of the first parameter).
 *          [growSize] the minimum amount, in bytes, to grow the buffer by to
 *            accommodate writes (default: 1024).
 *          [encoding] the encoding ('binary', 'utf8', 'utf16', 'hex') for the
 *            first parameter, if it is a string (default: 'binary').
 */ function DataBuffer(b, options) {
    // default options
    options = options || {
    };
    // pointers for read from/write to buffer
    this.read = options.readOffset || 0;
    this.growSize = options.growSize || 1024;
    var isArrayBuffer = util.isArrayBuffer(b);
    var isArrayBufferView = util.isArrayBufferView(b);
    if (isArrayBuffer || isArrayBufferView) {
        // use ArrayBuffer directly
        if (isArrayBuffer) this.data = new DataView(b);
        else // TODO: adjust read/write offset based on the type of view
        // or specify that this must be done in the options ... that the
        // offsets are byte-based
        this.data = new DataView(b.buffer, b.byteOffset, b.byteLength);
        this.write = 'writeOffset' in options ? options.writeOffset : this.data.byteLength;
        return;
    }
    // initialize to empty array buffer and add any given bytes using putBytes
    this.data = new DataView(new ArrayBuffer(0));
    this.write = 0;
    if (b !== null && b !== undefined) this.putBytes(b);
    if ('writeOffset' in options) this.write = options.writeOffset;
}
util.DataBuffer = DataBuffer;
/**
 * Gets the number of bytes in this buffer.
 *
 * @return the number of bytes in this buffer.
 */ util.DataBuffer.prototype.length = function() {
    return this.write - this.read;
};
/**
 * Gets whether or not this buffer is empty.
 *
 * @return true if this buffer is empty, false if not.
 */ util.DataBuffer.prototype.isEmpty = function() {
    return this.length() <= 0;
};
/**
 * Ensures this buffer has enough empty space to accommodate the given number
 * of bytes. An optional parameter may be given that indicates a minimum
 * amount to grow the buffer if necessary. If the parameter is not given,
 * the buffer will be grown by some previously-specified default amount
 * or heuristic.
 *
 * @param amount the number of bytes to accommodate.
 * @param [growSize] the minimum amount, in bytes, to grow the buffer by if
 *          necessary.
 */ util.DataBuffer.prototype.accommodate = function(amount, growSize) {
    if (this.length() >= amount) return this;
    growSize = Math.max(growSize || this.growSize, amount);
    // grow buffer
    var src = new Uint8Array(this.data.buffer, this.data.byteOffset, this.data.byteLength);
    var dst = new Uint8Array(this.length() + growSize);
    dst.set(src);
    this.data = new DataView(dst.buffer);
    return this;
};
/**
 * Puts a byte in this buffer.
 *
 * @param b the byte to put.
 *
 * @return this buffer.
 */ util.DataBuffer.prototype.putByte = function(b) {
    this.accommodate(1);
    this.data.setUint8(this.write++, b);
    return this;
};
/**
 * Puts a byte in this buffer N times.
 *
 * @param b the byte to put.
 * @param n the number of bytes of value b to put.
 *
 * @return this buffer.
 */ util.DataBuffer.prototype.fillWithByte = function(b, n) {
    this.accommodate(n);
    for(var i = 0; i < n; ++i)this.data.setUint8(b);
    return this;
};
/**
 * Puts bytes in this buffer. The bytes may be given as a string, an
 * ArrayBuffer, a DataView, or a TypedArray.
 *
 * @param bytes the bytes to put.
 * @param [encoding] the encoding for the first parameter ('binary', 'utf8',
 *          'utf16', 'hex'), if it is a string (default: 'binary').
 *
 * @return this buffer.
 */ util.DataBuffer.prototype.putBytes = function(bytes, encoding) {
    if (util.isArrayBufferView(bytes)) {
        var src = new Uint8Array(bytes.buffer, bytes.byteOffset, bytes.byteLength);
        var len = src.byteLength - src.byteOffset;
        this.accommodate(len);
        var dst = new Uint8Array(this.data.buffer, this.write);
        dst.set(src);
        this.write += len;
        return this;
    }
    if (util.isArrayBuffer(bytes)) {
        var src = new Uint8Array(bytes);
        this.accommodate(src.byteLength);
        var dst = new Uint8Array(this.data.buffer);
        dst.set(src, this.write);
        this.write += src.byteLength;
        return this;
    }
    // bytes is a util.DataBuffer or equivalent
    if (bytes instanceof util.DataBuffer || typeof bytes === 'object' && typeof bytes.read === 'number' && typeof bytes.write === 'number' && util.isArrayBufferView(bytes.data)) {
        var src = new Uint8Array(bytes.data.byteLength, bytes.read, bytes.length());
        this.accommodate(src.byteLength);
        var dst = new Uint8Array(bytes.data.byteLength, this.write);
        dst.set(src);
        this.write += src.byteLength;
        return this;
    }
    if (bytes instanceof util.ByteStringBuffer) {
        // copy binary string and process as the same as a string parameter below
        bytes = bytes.data;
        encoding = 'binary';
    }
    // string conversion
    encoding = encoding || 'binary';
    if (typeof bytes === 'string') {
        var view;
        // decode from string
        if (encoding === 'hex') {
            this.accommodate(Math.ceil(bytes.length / 2));
            view = new Uint8Array(this.data.buffer, this.write);
            this.write += util.binary.hex.decode(bytes, view, this.write);
            return this;
        }
        if (encoding === 'base64') {
            this.accommodate(Math.ceil(bytes.length / 4) * 3);
            view = new Uint8Array(this.data.buffer, this.write);
            this.write += util.binary.base64.decode(bytes, view, this.write);
            return this;
        }
        // encode text as UTF-8 bytes
        if (encoding === 'utf8') {
            // encode as UTF-8 then decode string as raw binary
            bytes = util.encodeUtf8(bytes);
            encoding = 'binary';
        }
        // decode string as raw binary
        if (encoding === 'binary' || encoding === 'raw') {
            // one byte per character
            this.accommodate(bytes.length);
            view = new Uint8Array(this.data.buffer, this.write);
            this.write += util.binary.raw.decode(view);
            return this;
        }
        // encode text as UTF-16 bytes
        if (encoding === 'utf16') {
            // two bytes per character
            this.accommodate(bytes.length * 2);
            view = new Uint16Array(this.data.buffer, this.write);
            this.write += util.text.utf16.encode(view);
            return this;
        }
        throw new Error('Invalid encoding: ' + encoding);
    }
    throw Error('Invalid parameter: ' + bytes);
};
/**
 * Puts the given buffer into this buffer.
 *
 * @param buffer the buffer to put into this one.
 *
 * @return this buffer.
 */ util.DataBuffer.prototype.putBuffer = function(buffer) {
    this.putBytes(buffer);
    buffer.clear();
    return this;
};
/**
 * Puts a string into this buffer.
 *
 * @param str the string to put.
 * @param [encoding] the encoding for the string (default: 'utf16').
 *
 * @return this buffer.
 */ util.DataBuffer.prototype.putString = function(str) {
    return this.putBytes(str, 'utf16');
};
/**
 * Puts a 16-bit integer in this buffer in big-endian order.
 *
 * @param i the 16-bit integer.
 *
 * @return this buffer.
 */ util.DataBuffer.prototype.putInt16 = function(i) {
    this.accommodate(2);
    this.data.setInt16(this.write, i);
    this.write += 2;
    return this;
};
/**
 * Puts a 24-bit integer in this buffer in big-endian order.
 *
 * @param i the 24-bit integer.
 *
 * @return this buffer.
 */ util.DataBuffer.prototype.putInt24 = function(i) {
    this.accommodate(3);
    this.data.setInt16(this.write, i >> 8 & 65535);
    this.data.setInt8(this.write, i >> 16 & 255);
    this.write += 3;
    return this;
};
/**
 * Puts a 32-bit integer in this buffer in big-endian order.
 *
 * @param i the 32-bit integer.
 *
 * @return this buffer.
 */ util.DataBuffer.prototype.putInt32 = function(i) {
    this.accommodate(4);
    this.data.setInt32(this.write, i);
    this.write += 4;
    return this;
};
/**
 * Puts a 16-bit integer in this buffer in little-endian order.
 *
 * @param i the 16-bit integer.
 *
 * @return this buffer.
 */ util.DataBuffer.prototype.putInt16Le = function(i) {
    this.accommodate(2);
    this.data.setInt16(this.write, i, true);
    this.write += 2;
    return this;
};
/**
 * Puts a 24-bit integer in this buffer in little-endian order.
 *
 * @param i the 24-bit integer.
 *
 * @return this buffer.
 */ util.DataBuffer.prototype.putInt24Le = function(i) {
    this.accommodate(3);
    this.data.setInt8(this.write, i >> 16 & 255);
    this.data.setInt16(this.write, i >> 8 & 65535, true);
    this.write += 3;
    return this;
};
/**
 * Puts a 32-bit integer in this buffer in little-endian order.
 *
 * @param i the 32-bit integer.
 *
 * @return this buffer.
 */ util.DataBuffer.prototype.putInt32Le = function(i) {
    this.accommodate(4);
    this.data.setInt32(this.write, i, true);
    this.write += 4;
    return this;
};
/**
 * Puts an n-bit integer in this buffer in big-endian order.
 *
 * @param i the n-bit integer.
 * @param n the number of bits in the integer (8, 16, 24, or 32).
 *
 * @return this buffer.
 */ util.DataBuffer.prototype.putInt = function(i, n) {
    _checkBitsParam(n);
    this.accommodate(n / 8);
    do {
        n -= 8;
        this.data.setInt8(this.write++, i >> n & 255);
    }while (n > 0)
    return this;
};
/**
 * Puts a signed n-bit integer in this buffer in big-endian order. Two's
 * complement representation is used.
 *
 * @param i the n-bit integer.
 * @param n the number of bits in the integer.
 *
 * @return this buffer.
 */ util.DataBuffer.prototype.putSignedInt = function(i, n) {
    _checkBitsParam(n);
    this.accommodate(n / 8);
    if (i < 0) i += 2 << n - 1;
    return this.putInt(i, n);
};
/**
 * Gets a byte from this buffer and advances the read pointer by 1.
 *
 * @return the byte.
 */ util.DataBuffer.prototype.getByte = function() {
    return this.data.getInt8(this.read++);
};
/**
 * Gets a uint16 from this buffer in big-endian order and advances the read
 * pointer by 2.
 *
 * @return the uint16.
 */ util.DataBuffer.prototype.getInt16 = function() {
    var rval = this.data.getInt16(this.read);
    this.read += 2;
    return rval;
};
/**
 * Gets a uint24 from this buffer in big-endian order and advances the read
 * pointer by 3.
 *
 * @return the uint24.
 */ util.DataBuffer.prototype.getInt24 = function() {
    var rval = this.data.getInt16(this.read) << 8 ^ this.data.getInt8(this.read + 2);
    this.read += 3;
    return rval;
};
/**
 * Gets a uint32 from this buffer in big-endian order and advances the read
 * pointer by 4.
 *
 * @return the word.
 */ util.DataBuffer.prototype.getInt32 = function() {
    var rval = this.data.getInt32(this.read);
    this.read += 4;
    return rval;
};
/**
 * Gets a uint16 from this buffer in little-endian order and advances the read
 * pointer by 2.
 *
 * @return the uint16.
 */ util.DataBuffer.prototype.getInt16Le = function() {
    var rval = this.data.getInt16(this.read, true);
    this.read += 2;
    return rval;
};
/**
 * Gets a uint24 from this buffer in little-endian order and advances the read
 * pointer by 3.
 *
 * @return the uint24.
 */ util.DataBuffer.prototype.getInt24Le = function() {
    var rval = this.data.getInt8(this.read) ^ this.data.getInt16(this.read + 1, true) << 8;
    this.read += 3;
    return rval;
};
/**
 * Gets a uint32 from this buffer in little-endian order and advances the read
 * pointer by 4.
 *
 * @return the word.
 */ util.DataBuffer.prototype.getInt32Le = function() {
    var rval = this.data.getInt32(this.read, true);
    this.read += 4;
    return rval;
};
/**
 * Gets an n-bit integer from this buffer in big-endian order and advances the
 * read pointer by n/8.
 *
 * @param n the number of bits in the integer (8, 16, 24, or 32).
 *
 * @return the integer.
 */ util.DataBuffer.prototype.getInt = function(n) {
    _checkBitsParam(n);
    var rval = 0;
    do {
        // TODO: Use (rval * 0x100) if adding support for 33 to 53 bits.
        rval = (rval << 8) + this.data.getInt8(this.read++);
        n -= 8;
    }while (n > 0)
    return rval;
};
/**
 * Gets a signed n-bit integer from this buffer in big-endian order, using
 * two's complement, and advances the read pointer by n/8.
 *
 * @param n the number of bits in the integer (8, 16, 24, or 32).
 *
 * @return the integer.
 */ util.DataBuffer.prototype.getSignedInt = function(n) {
    // getInt checks n
    var x = this.getInt(n);
    var max = 2 << n - 2;
    if (x >= max) x -= max << 1;
    return x;
};
/**
 * Reads bytes out as a binary encoded string and clears them from the
 * buffer.
 *
 * @param count the number of bytes to read, undefined or null for all.
 *
 * @return a binary encoded string of bytes.
 */ util.DataBuffer.prototype.getBytes = function(count) {
    // TODO: deprecate this method, it is poorly named and
    // this.toString('binary') replaces it
    // add a toTypedArray()/toArrayBuffer() function
    var rval;
    if (count) {
        // read count bytes
        count = Math.min(this.length(), count);
        rval = this.data.slice(this.read, this.read + count);
        this.read += count;
    } else if (count === 0) rval = '';
    else {
        // read all bytes, optimize to only copy when needed
        rval = this.read === 0 ? this.data : this.data.slice(this.read);
        this.clear();
    }
    return rval;
};
/**
 * Gets a binary encoded string of the bytes from this buffer without
 * modifying the read pointer.
 *
 * @param count the number of bytes to get, omit to get all.
 *
 * @return a string full of binary encoded characters.
 */ util.DataBuffer.prototype.bytes = function(count) {
    // TODO: deprecate this method, it is poorly named, add "getString()"
    return typeof count === 'undefined' ? this.data.slice(this.read) : this.data.slice(this.read, this.read + count);
};
/**
 * Gets a byte at the given index without modifying the read pointer.
 *
 * @param i the byte index.
 *
 * @return the byte.
 */ util.DataBuffer.prototype.at = function(i) {
    return this.data.getUint8(this.read + i);
};
/**
 * Puts a byte at the given index without modifying the read pointer.
 *
 * @param i the byte index.
 * @param b the byte to put.
 *
 * @return this buffer.
 */ util.DataBuffer.prototype.setAt = function(i, b) {
    this.data.setUint8(i, b);
    return this;
};
/**
 * Gets the last byte without modifying the read pointer.
 *
 * @return the last byte.
 */ util.DataBuffer.prototype.last = function() {
    return this.data.getUint8(this.write - 1);
};
/**
 * Creates a copy of this buffer.
 *
 * @return the copy.
 */ util.DataBuffer.prototype.copy = function() {
    return new util.DataBuffer(this);
};
/**
 * Compacts this buffer.
 *
 * @return this buffer.
 */ util.DataBuffer.prototype.compact = function() {
    if (this.read > 0) {
        var src = new Uint8Array(this.data.buffer, this.read);
        var dst = new Uint8Array(src.byteLength);
        dst.set(src);
        this.data = new DataView(dst);
        this.write -= this.read;
        this.read = 0;
    }
    return this;
};
/**
 * Clears this buffer.
 *
 * @return this buffer.
 */ util.DataBuffer.prototype.clear = function() {
    this.data = new DataView(new ArrayBuffer(0));
    this.read = this.write = 0;
    return this;
};
/**
 * Shortens this buffer by triming bytes off of the end of this buffer.
 *
 * @param count the number of bytes to trim off.
 *
 * @return this buffer.
 */ util.DataBuffer.prototype.truncate = function(count) {
    this.write = Math.max(0, this.length() - count);
    this.read = Math.min(this.read, this.write);
    return this;
};
/**
 * Converts this buffer to a hexadecimal string.
 *
 * @return a hexadecimal string.
 */ util.DataBuffer.prototype.toHex = function() {
    var rval = '';
    for(var i = this.read; i < this.data.byteLength; ++i){
        var b = this.data.getUint8(i);
        if (b < 16) rval += '0';
        rval += b.toString(16);
    }
    return rval;
};
/**
 * Converts this buffer to a string, using the given encoding. If no
 * encoding is given, 'utf8' (UTF-8) is used.
 *
 * @param [encoding] the encoding to use: 'binary', 'utf8', 'utf16', 'hex',
 *          'base64' (default: 'utf8').
 *
 * @return a string representation of the bytes in this buffer.
 */ util.DataBuffer.prototype.toString = function(encoding) {
    var view = new Uint8Array(this.data, this.read, this.length());
    encoding = encoding || 'utf8';
    // encode to string
    if (encoding === 'binary' || encoding === 'raw') return util.binary.raw.encode(view);
    if (encoding === 'hex') return util.binary.hex.encode(view);
    if (encoding === 'base64') return util.binary.base64.encode(view);
    // decode to text
    if (encoding === 'utf8') return util.text.utf8.decode(view);
    if (encoding === 'utf16') return util.text.utf16.decode(view);
    throw new Error('Invalid encoding: ' + encoding);
};
/** End Buffer w/UInt8Array backing */ /**
 * Creates a buffer that stores bytes. A value may be given to populate the
 * buffer with data. This value can either be string of encoded bytes or a
 * regular string of characters. When passing a string of binary encoded
 * bytes, the encoding `raw` should be given. This is also the default. When
 * passing a string of characters, the encoding `utf8` should be given.
 *
 * @param [input] a string with encoded bytes to store in the buffer.
 * @param [encoding] (default: 'raw', other: 'utf8').
 */ util.createBuffer = function(input, encoding) {
    // TODO: deprecate, use new ByteBuffer() instead
    encoding = encoding || 'raw';
    if (input !== undefined && encoding === 'utf8') input = util.encodeUtf8(input);
    return new util.ByteBuffer(input);
};
/**
 * Fills a string with a particular value. If you want the string to be a byte
 * string, pass in String.fromCharCode(theByte).
 *
 * @param c the character to fill the string with, use String.fromCharCode
 *          to fill the string with a byte value.
 * @param n the number of characters of value c to fill with.
 *
 * @return the filled string.
 */ util.fillString = function(c, n) {
    var s = '';
    while(n > 0){
        if (n & 1) s += c;
        n >>>= 1;
        if (n > 0) c += c;
    }
    return s;
};
/**
 * Performs a per byte XOR between two byte strings and returns the result as a
 * string of bytes.
 *
 * @param s1 first string of bytes.
 * @param s2 second string of bytes.
 * @param n the number of bytes to XOR.
 *
 * @return the XOR'd result.
 */ util.xorBytes = function(s1, s2, n) {
    var s3 = '';
    var b = '';
    var t = '';
    var i = 0;
    var c = 0;
    for(; n > 0; --n, ++i){
        b = s1.charCodeAt(i) ^ s2.charCodeAt(i);
        if (c >= 10) {
            s3 += t;
            t = '';
            c = 0;
        }
        t += String.fromCharCode(b);
        ++c;
    }
    s3 += t;
    return s3;
};
/**
 * Converts a hex string into a 'binary' encoded string of bytes.
 *
 * @param hex the hexadecimal string to convert.
 *
 * @return the binary-encoded string of bytes.
 */ util.hexToBytes = function(hex) {
    // TODO: deprecate: "Deprecated. Use util.binary.hex.decode instead."
    var rval = '';
    var i = 0;
    if (hex.length & true) {
        // odd number of characters, convert first character alone
        i = 1;
        rval += String.fromCharCode(parseInt(hex[0], 16));
    }
    // convert 2 characters (1 byte) at a time
    for(; i < hex.length; i += 2)rval += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
    return rval;
};
/**
 * Converts a 'binary' encoded string of bytes to hex.
 *
 * @param bytes the byte string to convert.
 *
 * @return the string of hexadecimal characters.
 */ util.bytesToHex = function(bytes) {
    // TODO: deprecate: "Deprecated. Use util.binary.hex.encode instead."
    return util.createBuffer(bytes).toHex();
};
/**
 * Converts an 32-bit integer to 4-big-endian byte string.
 *
 * @param i the integer.
 *
 * @return the byte string.
 */ util.int32ToBytes = function(i) {
    return String.fromCharCode(i >> 24 & 255) + String.fromCharCode(i >> 16 & 255) + String.fromCharCode(i >> 8 & 255) + String.fromCharCode(i & 255);
};
// base64 characters, reverse mapping
var _base64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
var _base64Idx = [
    /*43 -43 = 0*/ /*'+',  1,  2,  3,'/' */ 62,
    -1,
    -1,
    -1,
    63,
    /*'0','1','2','3','4','5','6','7','8','9' */ 52,
    53,
    54,
    55,
    56,
    57,
    58,
    59,
    60,
    61,
    /*15, 16, 17,'=', 19, 20, 21 */ -1,
    -1,
    -1,
    64,
    -1,
    -1,
    -1,
    /*65 - 43 = 22*/ /*'A','B','C','D','E','F','G','H','I','J','K','L','M', */ 0,
    1,
    2,
    3,
    4,
    5,
    6,
    7,
    8,
    9,
    10,
    11,
    12,
    /*'N','O','P','Q','R','S','T','U','V','W','X','Y','Z' */ 13,
    14,
    15,
    16,
    17,
    18,
    19,
    20,
    21,
    22,
    23,
    24,
    25,
    /*91 - 43 = 48 */ /*48, 49, 50, 51, 52, 53 */ -1,
    -1,
    -1,
    -1,
    -1,
    -1,
    /*97 - 43 = 54*/ /*'a','b','c','d','e','f','g','h','i','j','k','l','m' */ 26,
    27,
    28,
    29,
    30,
    31,
    32,
    33,
    34,
    35,
    36,
    37,
    38,
    /*'n','o','p','q','r','s','t','u','v','w','x','y','z' */ 39,
    40,
    41,
    42,
    43,
    44,
    45,
    46,
    47,
    48,
    49,
    50,
    51
];
// base58 characters (Bitcoin alphabet)
var _base58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
/**
 * Base64 encodes a 'binary' encoded string of bytes.
 *
 * @param input the binary encoded string of bytes to base64-encode.
 * @param maxline the maximum number of encoded characters per line to use,
 *          defaults to none.
 *
 * @return the base64-encoded output.
 */ util.encode64 = function(input, maxline) {
    // TODO: deprecate: "Deprecated. Use util.binary.base64.encode instead."
    var line = '';
    var output = '';
    var chr1, chr2, chr3;
    var i = 0;
    while(i < input.length){
        chr1 = input.charCodeAt(i++);
        chr2 = input.charCodeAt(i++);
        chr3 = input.charCodeAt(i++);
        // encode 4 character group
        line += _base64.charAt(chr1 >> 2);
        line += _base64.charAt((chr1 & 3) << 4 | chr2 >> 4);
        if (isNaN(chr2)) line += '==';
        else {
            line += _base64.charAt((chr2 & 15) << 2 | chr3 >> 6);
            line += isNaN(chr3) ? '=' : _base64.charAt(chr3 & 63);
        }
        if (maxline && line.length > maxline) {
            output += line.substr(0, maxline) + '\r\n';
            line = line.substr(maxline);
        }
    }
    output += line;
    return output;
};
/**
 * Base64 decodes a string into a 'binary' encoded string of bytes.
 *
 * @param input the base64-encoded input.
 *
 * @return the binary encoded string.
 */ util.decode64 = function(input) {
    // TODO: deprecate: "Deprecated. Use util.binary.base64.decode instead."
    // remove all non-base64 characters
    input = input.replace(/[^A-Za-z0-9\+\/\=]/g, '');
    var output = '';
    var enc1, enc2, enc3, enc4;
    var i = 0;
    while(i < input.length){
        enc1 = _base64Idx[input.charCodeAt(i++) - 43];
        enc2 = _base64Idx[input.charCodeAt(i++) - 43];
        enc3 = _base64Idx[input.charCodeAt(i++) - 43];
        enc4 = _base64Idx[input.charCodeAt(i++) - 43];
        output += String.fromCharCode(enc1 << 2 | enc2 >> 4);
        if (enc3 !== 64) {
            // decoded at least 2 bytes
            output += String.fromCharCode((enc2 & 15) << 4 | enc3 >> 2);
            if (enc4 !== 64) // decoded 3 bytes
            output += String.fromCharCode((enc3 & 3) << 6 | enc4);
        }
    }
    return output;
};
/**
 * Encodes the given string of characters (a standard JavaScript
 * string) as a binary encoded string where the bytes represent
 * a UTF-8 encoded string of characters. Non-ASCII characters will be
 * encoded as multiple bytes according to UTF-8.
 *
 * @param str a standard string of characters to encode.
 *
 * @return the binary encoded string.
 */ util.encodeUtf8 = function(str) {
    return unescape(encodeURIComponent(str));
};
/**
 * Decodes a binary encoded string that contains bytes that
 * represent a UTF-8 encoded string of characters -- into a
 * string of characters (a standard JavaScript string).
 *
 * @param str the binary encoded string to decode.
 *
 * @return the resulting standard string of characters.
 */ util.decodeUtf8 = function(str) {
    return decodeURIComponent(escape(str));
};
// binary encoding/decoding tools
// FIXME: Experimental. Do not use yet.
util.binary = {
    raw: {
    },
    hex: {
    },
    base64: {
    },
    base58: {
    },
    baseN: {
        encode: baseN.encode,
        decode: baseN.decode
    }
};
/**
 * Encodes a Uint8Array as a binary-encoded string. This encoding uses
 * a value between 0 and 255 for each character.
 *
 * @param bytes the Uint8Array to encode.
 *
 * @return the binary-encoded string.
 */ util.binary.raw.encode = function(bytes) {
    return String.fromCharCode.apply(null, bytes);
};
/**
 * Decodes a binary-encoded string to a Uint8Array. This encoding uses
 * a value between 0 and 255 for each character.
 *
 * @param str the binary-encoded string to decode.
 * @param [output] an optional Uint8Array to write the output to; if it
 *          is too small, an exception will be thrown.
 * @param [offset] the start offset for writing to the output (default: 0).
 *
 * @return the Uint8Array or the number of bytes written if output was given.
 */ util.binary.raw.decode = function(str, output, offset) {
    var out = output;
    if (!out) out = new Uint8Array(str.length);
    offset = offset || 0;
    var j = offset;
    for(var i = 0; i < str.length; ++i)out[j++] = str.charCodeAt(i);
    return output ? j - offset : out;
};
/**
 * Encodes a 'binary' string, ArrayBuffer, DataView, TypedArray, or
 * ByteBuffer as a string of hexadecimal characters.
 *
 * @param bytes the bytes to convert.
 *
 * @return the string of hexadecimal characters.
 */ util.binary.hex.encode = util.bytesToHex;
/**
 * Decodes a hex-encoded string to a Uint8Array.
 *
 * @param hex the hexadecimal string to convert.
 * @param [output] an optional Uint8Array to write the output to; if it
 *          is too small, an exception will be thrown.
 * @param [offset] the start offset for writing to the output (default: 0).
 *
 * @return the Uint8Array or the number of bytes written if output was given.
 */ util.binary.hex.decode = function(hex, output, offset) {
    var out = output;
    if (!out) out = new Uint8Array(Math.ceil(hex.length / 2));
    offset = offset || 0;
    var i = 0, j = offset;
    if (hex.length & 1) {
        // odd number of characters, convert first character alone
        i = 1;
        out[j++] = parseInt(hex[0], 16);
    }
    // convert 2 characters (1 byte) at a time
    for(; i < hex.length; i += 2)out[j++] = parseInt(hex.substr(i, 2), 16);
    return output ? j - offset : out;
};
/**
 * Base64-encodes a Uint8Array.
 *
 * @param input the Uint8Array to encode.
 * @param maxline the maximum number of encoded characters per line to use,
 *          defaults to none.
 *
 * @return the base64-encoded output string.
 */ util.binary.base64.encode = function(input, maxline) {
    var line = '';
    var output = '';
    var chr1, chr2, chr3;
    var i = 0;
    while(i < input.byteLength){
        chr1 = input[i++];
        chr2 = input[i++];
        chr3 = input[i++];
        // encode 4 character group
        line += _base64.charAt(chr1 >> 2);
        line += _base64.charAt((chr1 & 3) << 4 | chr2 >> 4);
        if (isNaN(chr2)) line += '==';
        else {
            line += _base64.charAt((chr2 & 15) << 2 | chr3 >> 6);
            line += isNaN(chr3) ? '=' : _base64.charAt(chr3 & 63);
        }
        if (maxline && line.length > maxline) {
            output += line.substr(0, maxline) + '\r\n';
            line = line.substr(maxline);
        }
    }
    output += line;
    return output;
};
/**
 * Decodes a base64-encoded string to a Uint8Array.
 *
 * @param input the base64-encoded input string.
 * @param [output] an optional Uint8Array to write the output to; if it
 *          is too small, an exception will be thrown.
 * @param [offset] the start offset for writing to the output (default: 0).
 *
 * @return the Uint8Array or the number of bytes written if output was given.
 */ util.binary.base64.decode = function(input, output, offset) {
    var out = output;
    if (!out) out = new Uint8Array(Math.ceil(input.length / 4) * 3);
    // remove all non-base64 characters
    input = input.replace(/[^A-Za-z0-9\+\/\=]/g, '');
    offset = offset || 0;
    var enc1, enc2, enc3, enc4;
    var i = 0, j = offset;
    while(i < input.length){
        enc1 = _base64Idx[input.charCodeAt(i++) - 43];
        enc2 = _base64Idx[input.charCodeAt(i++) - 43];
        enc3 = _base64Idx[input.charCodeAt(i++) - 43];
        enc4 = _base64Idx[input.charCodeAt(i++) - 43];
        out[j++] = enc1 << 2 | enc2 >> 4;
        if (enc3 !== 64) {
            // decoded at least 2 bytes
            out[j++] = (enc2 & 15) << 4 | enc3 >> 2;
            if (enc4 !== 64) // decoded 3 bytes
            out[j++] = (enc3 & 3) << 6 | enc4;
        }
    }
    // make sure result is the exact decoded length
    return output ? j - offset : out.subarray(0, j);
};
// add support for base58 encoding/decoding with Bitcoin alphabet
util.binary.base58.encode = function(input, maxline) {
    return util.binary.baseN.encode(input, _base58, maxline);
};
util.binary.base58.decode = function(input, maxline) {
    return util.binary.baseN.decode(input, _base58, maxline);
};
// text encoding/decoding tools
// FIXME: Experimental. Do not use yet.
util.text = {
    utf8: {
    },
    utf16: {
    }
};
/**
 * Encodes the given string as UTF-8 in a Uint8Array.
 *
 * @param str the string to encode.
 * @param [output] an optional Uint8Array to write the output to; if it
 *          is too small, an exception will be thrown.
 * @param [offset] the start offset for writing to the output (default: 0).
 *
 * @return the Uint8Array or the number of bytes written if output was given.
 */ util.text.utf8.encode = function(str, output, offset) {
    str = util.encodeUtf8(str);
    var out = output;
    if (!out) out = new Uint8Array(str.length);
    offset = offset || 0;
    var j = offset;
    for(var i = 0; i < str.length; ++i)out[j++] = str.charCodeAt(i);
    return output ? j - offset : out;
};
/**
 * Decodes the UTF-8 contents from a Uint8Array.
 *
 * @param bytes the Uint8Array to decode.
 *
 * @return the resulting string.
 */ util.text.utf8.decode = function(bytes) {
    return util.decodeUtf8(String.fromCharCode.apply(null, bytes));
};
/**
 * Encodes the given string as UTF-16 in a Uint8Array.
 *
 * @param str the string to encode.
 * @param [output] an optional Uint8Array to write the output to; if it
 *          is too small, an exception will be thrown.
 * @param [offset] the start offset for writing to the output (default: 0).
 *
 * @return the Uint8Array or the number of bytes written if output was given.
 */ util.text.utf16.encode = function(str, output, offset) {
    var out = output;
    if (!out) out = new Uint8Array(str.length * 2);
    var view = new Uint16Array(out.buffer);
    offset = offset || 0;
    var j = offset;
    var k = offset;
    for(var i = 0; i < str.length; ++i){
        view[k++] = str.charCodeAt(i);
        j += 2;
    }
    return output ? j - offset : out;
};
/**
 * Decodes the UTF-16 contents from a Uint8Array.
 *
 * @param bytes the Uint8Array to decode.
 *
 * @return the resulting string.
 */ util.text.utf16.decode = function(bytes) {
    return String.fromCharCode.apply(null, new Uint16Array(bytes.buffer));
};
/**
 * Deflates the given data using a flash interface.
 *
 * @param api the flash interface.
 * @param bytes the data.
 * @param raw true to return only raw deflate data, false to include zlib
 *          header and trailer.
 *
 * @return the deflated data as a string.
 */ util.deflate = function(api, bytes, raw) {
    bytes = util.decode64(api.deflate(util.encode64(bytes)).rval);
    // strip zlib header and trailer if necessary
    if (raw) {
        // zlib header is 2 bytes (CMF,FLG) where FLG indicates that
        // there is a 4-byte DICT (alder-32) block before the data if
        // its 5th bit is set
        var start = 2;
        var flg = bytes.charCodeAt(1);
        if (flg & 32) start = 6;
        // zlib trailer is 4 bytes of adler-32
        bytes = bytes.substring(start, bytes.length - 4);
    }
    return bytes;
};
/**
 * Inflates the given data using a flash interface.
 *
 * @param api the flash interface.
 * @param bytes the data.
 * @param raw true if the incoming data has no zlib header or trailer and is
 *          raw DEFLATE data.
 *
 * @return the inflated data as a string, null on error.
 */ util.inflate = function(api, bytes, raw) {
    // TODO: add zlib header and trailer if necessary/possible
    var rval = api.inflate(util.encode64(bytes)).rval;
    return rval === null ? null : util.decode64(rval);
};
/**
 * Sets a storage object.
 *
 * @param api the storage interface.
 * @param id the storage ID to use.
 * @param obj the storage object, null to remove.
 */ var _setStorageObject = function(api, id, obj) {
    if (!api) throw new Error('WebStorage not available.');
    var rval;
    if (obj === null) rval = api.removeItem(id);
    else {
        // json-encode and base64-encode object
        obj = util.encode64(JSON.stringify(obj));
        rval = api.setItem(id, obj);
    }
    // handle potential flash error
    if (typeof rval !== 'undefined' && rval.rval !== true) {
        var error = new Error(rval.error.message);
        error.id = rval.error.id;
        error.name = rval.error.name;
        throw error;
    }
};
/**
 * Gets a storage object.
 *
 * @param api the storage interface.
 * @param id the storage ID to use.
 *
 * @return the storage object entry or null if none exists.
 */ var _getStorageObject = function(api, id) {
    if (!api) throw new Error('WebStorage not available.');
    // get the existing entry
    var rval = api.getItem(id);
    /* Note: We check api.init because we can't do (api == localStorage)
    on IE because of "Class doesn't support Automation" exception. Only
    the flash api has an init method so this works too, but we need a
    better solution in the future. */ // flash returns item wrapped in an object, handle special case
    if (api.init) {
        if (rval.rval === null) {
            if (rval.error) {
                var error = new Error(rval.error.message);
                error.id = rval.error.id;
                error.name = rval.error.name;
                throw error;
            }
            // no error, but also no item
            rval = null;
        } else rval = rval.rval;
    }
    // handle decoding
    if (rval !== null) // base64-decode and json-decode data
    rval = JSON.parse(util.decode64(rval));
    return rval;
};
/**
 * Stores an item in local storage.
 *
 * @param api the storage interface.
 * @param id the storage ID to use.
 * @param key the key for the item.
 * @param data the data for the item (any javascript object/primitive).
 */ var _setItem = function(api, id, key, data) {
    // get storage object
    var obj = _getStorageObject(api, id);
    if (obj === null) // create a new storage object
    obj = {
    };
    // update key
    obj[key] = data;
    // set storage object
    _setStorageObject(api, id, obj);
};
/**
 * Gets an item from local storage.
 *
 * @param api the storage interface.
 * @param id the storage ID to use.
 * @param key the key for the item.
 *
 * @return the item.
 */ var _getItem = function(api, id, key) {
    // get storage object
    var rval = _getStorageObject(api, id);
    if (rval !== null) // return data at key
    rval = key in rval ? rval[key] : null;
    return rval;
};
/**
 * Removes an item from local storage.
 *
 * @param api the storage interface.
 * @param id the storage ID to use.
 * @param key the key for the item.
 */ var _removeItem = function(api, id, key) {
    // get storage object
    var obj = _getStorageObject(api, id);
    if (obj !== null && key in obj) {
        // remove key
        delete obj[key];
        // see if entry has no keys remaining
        var empty = true;
        for(var prop in obj){
            empty = false;
            break;
        }
        if (empty) // remove entry entirely if no keys are left
        obj = null;
        // set storage object
        _setStorageObject(api, id, obj);
    }
};
/**
 * Clears the local disk storage identified by the given ID.
 *
 * @param api the storage interface.
 * @param id the storage ID to use.
 */ var _clearItems = function(api, id) {
    _setStorageObject(api, id, null);
};
/**
 * Calls a storage function.
 *
 * @param func the function to call.
 * @param args the arguments for the function.
 * @param location the location argument.
 *
 * @return the return value from the function.
 */ var _callStorageFunction = function(func, args, location) {
    var rval = null;
    // default storage types
    if (typeof location === 'undefined') location = [
        'web',
        'flash'
    ];
    // apply storage types in order of preference
    var type;
    var done = false;
    var exception = null;
    for(var idx in location){
        type = location[idx];
        try {
            if (type === 'flash' || type === 'both') {
                if (args[0] === null) throw new Error('Flash local storage not available.');
                rval = func.apply(this, args);
                done = type === 'flash';
            }
            if (type === 'web' || type === 'both') {
                args[0] = localStorage;
                rval = func.apply(this, args);
                done = true;
            }
        } catch (ex) {
            exception = ex;
        }
        if (done) break;
    }
    if (!done) throw exception;
    return rval;
};
/**
 * Stores an item on local disk.
 *
 * The available types of local storage include 'flash', 'web', and 'both'.
 *
 * The type 'flash' refers to flash local storage (SharedObject). In order
 * to use flash local storage, the 'api' parameter must be valid. The type
 * 'web' refers to WebStorage, if supported by the browser. The type 'both'
 * refers to storing using both 'flash' and 'web', not just one or the
 * other.
 *
 * The location array should list the storage types to use in order of
 * preference:
 *
 * ['flash']: flash only storage
 * ['web']: web only storage
 * ['both']: try to store in both
 * ['flash','web']: store in flash first, but if not available, 'web'
 * ['web','flash']: store in web first, but if not available, 'flash'
 *
 * The location array defaults to: ['web', 'flash']
 *
 * @param api the flash interface, null to use only WebStorage.
 * @param id the storage ID to use.
 * @param key the key for the item.
 * @param data the data for the item (any javascript object/primitive).
 * @param location an array with the preferred types of storage to use.
 */ util.setItem = function(api, id, key, data, location) {
    _callStorageFunction(_setItem, arguments, location);
};
/**
 * Gets an item on local disk.
 *
 * Set setItem() for details on storage types.
 *
 * @param api the flash interface, null to use only WebStorage.
 * @param id the storage ID to use.
 * @param key the key for the item.
 * @param location an array with the preferred types of storage to use.
 *
 * @return the item.
 */ util.getItem = function(api, id, key, location) {
    return _callStorageFunction(_getItem, arguments, location);
};
/**
 * Removes an item on local disk.
 *
 * Set setItem() for details on storage types.
 *
 * @param api the flash interface.
 * @param id the storage ID to use.
 * @param key the key for the item.
 * @param location an array with the preferred types of storage to use.
 */ util.removeItem = function(api, id, key, location) {
    _callStorageFunction(_removeItem, arguments, location);
};
/**
 * Clears the local disk storage identified by the given ID.
 *
 * Set setItem() for details on storage types.
 *
 * @param api the flash interface if flash is available.
 * @param id the storage ID to use.
 * @param location an array with the preferred types of storage to use.
 */ util.clearItems = function(api, id, location) {
    _callStorageFunction(_clearItems, arguments, location);
};
/**
 * Parses the scheme, host, and port from an http(s) url.
 *
 * @param str the url string.
 *
 * @return the parsed url object or null if the url is invalid.
 */ util.parseUrl = function(str) {
    // FIXME: this regex looks a bit broken
    var regex = /^(https?):\/\/([^:&^\/]*):?(\d*)(.*)$/g;
    regex.lastIndex = 0;
    var m = regex.exec(str);
    var url = m === null ? null : {
        full: str,
        scheme: m[1],
        host: m[2],
        port: m[3],
        path: m[4]
    };
    if (url) {
        url.fullHost = url.host;
        if (url.port) {
            if (url.port !== 80 && url.scheme === 'http') url.fullHost += ':' + url.port;
            else if (url.port !== 443 && url.scheme === 'https') url.fullHost += ':' + url.port;
        } else if (url.scheme === 'http') url.port = 80;
        else if (url.scheme === 'https') url.port = 443;
        url.full = url.scheme + '://' + url.fullHost;
    }
    return url;
};
/* Storage for query variables */ var _queryVariables = null;
/**
 * Returns the window location query variables. Query is parsed on the first
 * call and the same object is returned on subsequent calls. The mapping
 * is from keys to an array of values. Parameters without values will have
 * an object key set but no value added to the value array. Values are
 * unescaped.
 *
 * ...?k1=v1&k2=v2:
 * {
 *   "k1": ["v1"],
 *   "k2": ["v2"]
 * }
 *
 * ...?k1=v1&k1=v2:
 * {
 *   "k1": ["v1", "v2"]
 * }
 *
 * ...?k1=v1&k2:
 * {
 *   "k1": ["v1"],
 *   "k2": []
 * }
 *
 * ...?k1=v1&k1:
 * {
 *   "k1": ["v1"]
 * }
 *
 * ...?k1&k1:
 * {
 *   "k1": []
 * }
 *
 * @param query the query string to parse (optional, default to cached
 *          results from parsing window location search query).
 *
 * @return object mapping keys to variables.
 */ util.getQueryVariables = function(query) {
    var parse = function(q) {
        var rval = {
        };
        var kvpairs = q.split('&');
        for(var i = 0; i < kvpairs.length; i++){
            var pos = kvpairs[i].indexOf('=');
            var key;
            var val;
            if (pos > 0) {
                key = kvpairs[i].substring(0, pos);
                val = kvpairs[i].substring(pos + 1);
            } else {
                key = kvpairs[i];
                val = null;
            }
            if (!(key in rval)) rval[key] = [];
            // disallow overriding object prototype keys
            if (!(key in Object.prototype) && val !== null) rval[key].push(unescape(val));
        }
        return rval;
    };
    var rval1;
    if (typeof query === 'undefined') {
        // set cached variables if needed
        if (_queryVariables === null) {
            if (typeof window !== 'undefined' && window.location && window.location.search) // parse window search query
            _queryVariables = parse(window.location.search.substring(1));
            else // no query variables available
            _queryVariables = {
            };
        }
        rval1 = _queryVariables;
    } else // parse given query
    rval1 = parse(query);
    return rval1;
};
/**
 * Parses a fragment into a path and query. This method will take a URI
 * fragment and break it up as if it were the main URI. For example:
 *    /bar/baz?a=1&b=2
 * results in:
 *    {
 *       path: ["bar", "baz"],
 *       query: {"k1": ["v1"], "k2": ["v2"]}
 *    }
 *
 * @return object with a path array and query object.
 */ util.parseFragment = function(fragment) {
    // default to whole fragment
    var fp = fragment;
    var fq = '';
    // split into path and query if possible at the first '?'
    var pos = fragment.indexOf('?');
    if (pos > 0) {
        fp = fragment.substring(0, pos);
        fq = fragment.substring(pos + 1);
    }
    // split path based on '/' and ignore first element if empty
    var path = fp.split('/');
    if (path.length > 0 && path[0] === '') path.shift();
    // convert query into object
    var query = fq === '' ? {
    } : util.getQueryVariables(fq);
    return {
        pathString: fp,
        queryString: fq,
        path: path,
        query: query
    };
};
/**
 * Makes a request out of a URI-like request string. This is intended to
 * be used where a fragment id (after a URI '#') is parsed as a URI with
 * path and query parts. The string should have a path beginning and
 * delimited by '/' and optional query parameters following a '?'. The
 * query should be a standard URL set of key value pairs delimited by
 * '&'. For backwards compatibility the initial '/' on the path is not
 * required. The request object has the following API, (fully described
 * in the method code):
 *    {
 *       path: <the path string part>.
 *       query: <the query string part>,
 *       getPath(i): get part or all of the split path array,
 *       getQuery(k, i): get part or all of a query key array,
 *       getQueryLast(k, _default): get last element of a query key array.
 *    }
 *
 * @return object with request parameters.
 */ util.makeRequest = function(reqString) {
    var frag = util.parseFragment(reqString);
    var req = {
        // full path string
        path: frag.pathString,
        // full query string
        query: frag.queryString,
        /**
     * Get path or element in path.
     *
     * @param i optional path index.
     *
     * @return path or part of path if i provided.
     */ getPath: function(i) {
            return typeof i === 'undefined' ? frag.path : frag.path[i];
        },
        /**
     * Get query, values for a key, or value for a key index.
     *
     * @param k optional query key.
     * @param i optional query key index.
     *
     * @return query, values for a key, or value for a key index.
     */ getQuery: function(k, i) {
            var rval;
            if (typeof k === 'undefined') rval = frag.query;
            else {
                rval = frag.query[k];
                if (rval && typeof i !== 'undefined') rval = rval[i];
            }
            return rval;
        },
        getQueryLast: function(k, _default) {
            var rval;
            var vals = req.getQuery(k);
            if (vals) rval = vals[vals.length - 1];
            else rval = _default;
            return rval;
        }
    };
    return req;
};
/**
 * Makes a URI out of a path, an object with query parameters, and a
 * fragment. Uses jQuery.param() internally for query string creation.
 * If the path is an array, it will be joined with '/'.
 *
 * @param path string path or array of strings.
 * @param query object with query parameters. (optional)
 * @param fragment fragment string. (optional)
 *
 * @return string object with request parameters.
 */ util.makeLink = function(path, query, fragment) {
    // join path parts if needed
    path = jQuery.isArray(path) ? path.join('/') : path;
    var qstr = jQuery.param(query || {
    });
    fragment = fragment || '';
    return path + (qstr.length > 0 ? '?' + qstr : '') + (fragment.length > 0 ? '#' + fragment : '');
};
/**
 * Check if an object is empty.
 *
 * Taken from:
 * http://stackoverflow.com/questions/679915/how-do-i-test-for-an-empty-javascript-object-from-json/679937#679937
 *
 * @param object the object to check.
 */ util.isEmpty = function(obj) {
    for(var prop in obj){
        if (obj.hasOwnProperty(prop)) return false;
    }
    return true;
};
/**
 * Format with simple printf-style interpolation.
 *
 * %%: literal '%'
 * %s,%o: convert next argument into a string.
 *
 * @param format the string to format.
 * @param ... arguments to interpolate into the format string.
 */ util.format = function(format) {
    var re = /%./g;
    // current match
    var match;
    // current part
    var part;
    // current arg index
    var argi = 0;
    // collected parts to recombine later
    var parts = [];
    // last index found
    var last = 0;
    // loop while matches remain
    while(match = re.exec(format)){
        part = format.substring(last, re.lastIndex - 2);
        // don't add empty strings (ie, parts between %s%s)
        if (part.length > 0) parts.push(part);
        last = re.lastIndex;
        // switch on % code
        var code = match[0][1];
        switch(code){
            case 's':
            case 'o':
                // check if enough arguments were given
                if (argi < arguments.length) parts.push(arguments[(argi++) + 1]);
                else parts.push('<?>');
                break;
            // FIXME: do proper formating for numbers, etc
            //case 'f':
            //case 'd':
            case '%':
                parts.push('%');
                break;
            default:
                parts.push('<%' + code + '?>');
        }
    }
    // add trailing part of format string
    parts.push(format.substring(last));
    return parts.join('');
};
/**
 * Formats a number.
 *
 * http://snipplr.com/view/5945/javascript-numberformat--ported-from-php/
 */ util.formatNumber = function(number, decimals, dec_point, thousands_sep) {
    // http://kevin.vanzonneveld.net
    // +   original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +     bugfix by: Michael White (http://crestidg.com)
    // +     bugfix by: Benjamin Lupton
    // +     bugfix by: Allan Jensen (http://www.winternet.no)
    // +    revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
    // *     example 1: number_format(1234.5678, 2, '.', '');
    // *     returns 1: 1234.57
    var n = number, c = isNaN(decimals = Math.abs(decimals)) ? 2 : decimals;
    var d = dec_point === undefined ? ',' : dec_point;
    var t = thousands_sep === undefined ? '.' : thousands_sep, s = n < 0 ? '-' : '';
    var i = parseInt(n = Math.abs(+n || 0).toFixed(c), 10) + '';
    var j = i.length > 3 ? i.length % 3 : 0;
    return s + (j ? i.substr(0, j) + t : '') + i.substr(j).replace(/(\d{3})(?=\d)/g, '$1' + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : '');
};
/**
 * Formats a byte size.
 *
 * http://snipplr.com/view/5949/format-humanize-file-byte-size-presentation-in-javascript/
 */ util.formatSize = function(size) {
    if (size >= 1073741824) size = util.formatNumber(size / 1073741824, 2, '.', '') + ' GiB';
    else if (size >= 1048576) size = util.formatNumber(size / 1048576, 2, '.', '') + ' MiB';
    else if (size >= 1024) size = util.formatNumber(size / 1024, 0) + ' KiB';
    else size = util.formatNumber(size, 0) + ' bytes';
    return size;
};
/**
 * Converts an IPv4 or IPv6 string representation into bytes (in network order).
 *
 * @param ip the IPv4 or IPv6 address to convert.
 *
 * @return the 4-byte IPv6 or 16-byte IPv6 address or null if the address can't
 *         be parsed.
 */ util.bytesFromIP = function(ip) {
    if (ip.indexOf('.') !== -1) return util.bytesFromIPv4(ip);
    if (ip.indexOf(':') !== -1) return util.bytesFromIPv6(ip);
    return null;
};
/**
 * Converts an IPv4 string representation into bytes (in network order).
 *
 * @param ip the IPv4 address to convert.
 *
 * @return the 4-byte address or null if the address can't be parsed.
 */ util.bytesFromIPv4 = function(ip) {
    ip = ip.split('.');
    if (ip.length !== 4) return null;
    var b = util.createBuffer();
    for(var i = 0; i < ip.length; ++i){
        var num = parseInt(ip[i], 10);
        if (isNaN(num)) return null;
        b.putByte(num);
    }
    return b.getBytes();
};
/**
 * Converts an IPv6 string representation into bytes (in network order).
 *
 * @param ip the IPv6 address to convert.
 *
 * @return the 16-byte address or null if the address can't be parsed.
 */ util.bytesFromIPv6 = function(ip) {
    var blanks = 0;
    ip = ip.split(':').filter(function(e) {
        if (e.length === 0) ++blanks;
        return true;
    });
    var zeros = (8 - ip.length + blanks) * 2;
    var b = util.createBuffer();
    for(var i = 0; i < 8; ++i){
        if (!ip[i] || ip[i].length === 0) {
            b.fillWithByte(0, zeros);
            zeros = 0;
            continue;
        }
        var bytes = util.hexToBytes(ip[i]);
        if (bytes.length < 2) b.putByte(0);
        b.putBytes(bytes);
    }
    return b.getBytes();
};
/**
 * Converts 4-bytes into an IPv4 string representation or 16-bytes into
 * an IPv6 string representation. The bytes must be in network order.
 *
 * @param bytes the bytes to convert.
 *
 * @return the IPv4 or IPv6 string representation if 4 or 16 bytes,
 *         respectively, are given, otherwise null.
 */ util.bytesToIP = function(bytes) {
    if (bytes.length === 4) return util.bytesToIPv4(bytes);
    if (bytes.length === 16) return util.bytesToIPv6(bytes);
    return null;
};
/**
 * Converts 4-bytes into an IPv4 string representation. The bytes must be
 * in network order.
 *
 * @param bytes the bytes to convert.
 *
 * @return the IPv4 string representation or null for an invalid # of bytes.
 */ util.bytesToIPv4 = function(bytes) {
    if (bytes.length !== 4) return null;
    var ip = [];
    for(var i = 0; i < bytes.length; ++i)ip.push(bytes.charCodeAt(i));
    return ip.join('.');
};
/**
 * Converts 16-bytes into an IPv16 string representation. The bytes must be
 * in network order.
 *
 * @param bytes the bytes to convert.
 *
 * @return the IPv16 string representation or null for an invalid # of bytes.
 */ util.bytesToIPv6 = function(bytes) {
    if (bytes.length !== 16) return null;
    var ip = [];
    var zeroGroups = [];
    var zeroMaxGroup = 0;
    for(var i = 0; i < bytes.length; i += 2){
        var hex = util.bytesToHex(bytes[i] + bytes[i + 1]);
        // canonicalize zero representation
        while(hex[0] === '0' && hex !== '0')hex = hex.substr(1);
        if (hex === '0') {
            var last = zeroGroups[zeroGroups.length - 1];
            var idx = ip.length;
            if (!last || idx !== last.end + 1) zeroGroups.push({
                start: idx,
                end: idx
            });
            else {
                last.end = idx;
                if (last.end - last.start > zeroGroups[zeroMaxGroup].end - zeroGroups[zeroMaxGroup].start) zeroMaxGroup = zeroGroups.length - 1;
            }
        }
        ip.push(hex);
    }
    if (zeroGroups.length > 0) {
        var group = zeroGroups[zeroMaxGroup];
        // only shorten group of length > 0
        if (group.end - group.start > 0) {
            ip.splice(group.start, group.end - group.start + 1, '');
            if (group.start === 0) ip.unshift('');
            if (group.end === 7) ip.push('');
        }
    }
    return ip.join(':');
};
/**
 * Estimates the number of processes that can be run concurrently. If
 * creating Web Workers, keep in mind that the main JavaScript process needs
 * its own core.
 *
 * @param options the options to use:
 *          update true to force an update (not use the cached value).
 * @param callback(err, max) called once the operation completes.
 */ util.estimateCores = function(options, callback1) {
    if (typeof options === 'function') {
        callback1 = options;
        options = {
        };
    }
    options = options || {
    };
    if ('cores' in util && !options.update) return callback1(null, util.cores);
    if (typeof navigator !== 'undefined' && 'hardwareConcurrency' in navigator && navigator.hardwareConcurrency > 0) {
        util.cores = navigator.hardwareConcurrency;
        return callback1(null, util.cores);
    }
    if (typeof Worker === 'undefined') {
        // workers not available
        util.cores = 1;
        return callback1(null, util.cores);
    }
    if (typeof Blob === 'undefined') {
        // can't estimate, default to 2
        util.cores = 2;
        return callback1(null, util.cores);
    }
    // create worker concurrency estimation code as blob
    var blobUrl = URL.createObjectURL(new Blob([
        '(',
        (function() {
            self.addEventListener('message', function(e) {
                // run worker for 4 ms
                var st = Date.now();
                var et = st + 4;
                while(Date.now() < et);
                self.postMessage({
                    st: st,
                    et: et
                });
            });
        }).toString(),
        ')()'
    ], {
        type: 'application/javascript'
    }));
    // take 5 samples using 16 workers
    sample([], 5, 16);
    function sample(max, samples, numWorkers) {
        if (samples === 0) {
            // get overlap average
            var avg1 = Math.floor(max.reduce(function(avg, x) {
                return avg + x;
            }, 0) / max.length);
            util.cores = Math.max(1, avg1);
            URL.revokeObjectURL(blobUrl);
            return callback1(null, util.cores);
        }
        map(numWorkers, function(err, results) {
            max.push(reduce(numWorkers, results));
            sample(max, samples - 1, numWorkers);
        });
    }
    function map(numWorkers, callback) {
        var workers = [];
        var results = [];
        for(var i1 = 0; i1 < numWorkers; ++i1){
            var worker = new Worker(blobUrl);
            worker.addEventListener('message', function(e) {
                results.push(e.data);
                if (results.length === numWorkers) {
                    for(var i = 0; i < numWorkers; ++i)workers[i].terminate();
                    callback(null, results);
                }
            });
            workers.push(worker);
        }
        for(var i1 = 0; i1 < numWorkers; ++i1)workers[i1].postMessage(i1);
    }
    function reduce(numWorkers, results) {
        // find overlapping time windows
        var overlaps = [];
        for(var n = 0; n < numWorkers; ++n){
            var r1 = results[n];
            var overlap = overlaps[n] = [];
            for(var i = 0; i < numWorkers; ++i){
                if (n === i) continue;
                var r2 = results[i];
                if (r1.st > r2.st && r1.st < r2.et || r2.st > r1.st && r2.st < r1.et) overlap.push(i);
            }
        }
        // get maximum overlaps ... don't include overlapping worker itself
        // as the main JS process was also being scheduled during the work and
        // would have to be subtracted from the estimate anyway
        return overlaps.reduce(function(max, overlap) {
            return Math.max(max, overlap.length);
        }, 0);
    }
};

},{"buffer":"joWnX","process":"joWnX","./forge":"7AnVp","./baseN":"aABfp"}],"aABfp":[function(require,module,exports) {
var Buffer = require("buffer").Buffer;
/**
 * Base-N/Base-X encoding/decoding functions.
 *
 * Original implementation from base-x:
 * https://github.com/cryptocoinjs/base-x
 *
 * Which is MIT licensed:
 *
 * The MIT License (MIT)
 *
 * Copyright base-x contributors (c) 2016
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */ var api = {
};
module.exports = api;
// baseN alphabet indexes
var _reverseAlphabets = {
};
/**
 * BaseN-encodes a Uint8Array using the given alphabet.
 *
 * @param input the Uint8Array to encode.
 * @param maxline the maximum number of encoded characters per line to use,
 *          defaults to none.
 *
 * @return the baseN-encoded output string.
 */ api.encode = function(input, alphabet, maxline) {
    if (typeof alphabet !== 'string') throw new TypeError('"alphabet" must be a string.');
    if (maxline !== undefined && typeof maxline !== 'number') throw new TypeError('"maxline" must be a number.');
    var output = '';
    if (!(input instanceof Uint8Array)) // assume forge byte buffer
    output = _encodeWithByteBuffer(input, alphabet);
    else {
        var i = 0;
        var base = alphabet.length;
        var first = alphabet.charAt(0);
        var digits = [
            0
        ];
        for(i = 0; i < input.length; ++i){
            for(var j = 0, carry = input[i]; j < digits.length; ++j){
                carry += digits[j] << 8;
                digits[j] = carry % base;
                carry = carry / base | 0;
            }
            while(carry > 0){
                digits.push(carry % base);
                carry = carry / base | 0;
            }
        }
        // deal with leading zeros
        for(i = 0; input[i] === 0 && i < input.length - 1; ++i)output += first;
        // convert digits to a string
        for(i = digits.length - 1; i >= 0; --i)output += alphabet[digits[i]];
    }
    if (maxline) {
        var regex = new RegExp('.{1,' + maxline + '}', 'g');
        output = output.match(regex).join('\r\n');
    }
    return output;
};
/**
 * Decodes a baseN-encoded (using the given alphabet) string to a
 * Uint8Array.
 *
 * @param input the baseN-encoded input string.
 *
 * @return the Uint8Array.
 */ api.decode = function(input, alphabet) {
    if (typeof input !== 'string') throw new TypeError('"input" must be a string.');
    if (typeof alphabet !== 'string') throw new TypeError('"alphabet" must be a string.');
    var table = _reverseAlphabets[alphabet];
    if (!table) {
        // compute reverse alphabet
        table = _reverseAlphabets[alphabet] = [];
        for(var i = 0; i < alphabet.length; ++i)table[alphabet.charCodeAt(i)] = i;
    }
    // remove whitespace characters
    input = input.replace(/\s/g, '');
    var base = alphabet.length;
    var first = alphabet.charAt(0);
    var bytes = [
        0
    ];
    for(var i = 0; i < input.length; i++){
        var value = table[input.charCodeAt(i)];
        if (value === undefined) return;
        for(var j = 0, carry = value; j < bytes.length; ++j){
            carry += bytes[j] * base;
            bytes[j] = carry & 255;
            carry >>= 8;
        }
        while(carry > 0){
            bytes.push(carry & 255);
            carry >>= 8;
        }
    }
    // deal with leading zeros
    for(var k = 0; input[k] === first && k < input.length - 1; ++k)bytes.push(0);
    if (typeof Buffer !== 'undefined') return Buffer.from(bytes.reverse());
    return new Uint8Array(bytes.reverse());
};
function _encodeWithByteBuffer(input, alphabet) {
    var i = 0;
    var base = alphabet.length;
    var first = alphabet.charAt(0);
    var digits = [
        0
    ];
    for(i = 0; i < input.length(); ++i){
        for(var j = 0, carry = input.at(i); j < digits.length; ++j){
            carry += digits[j] << 8;
            digits[j] = carry % base;
            carry = carry / base | 0;
        }
        while(carry > 0){
            digits.push(carry % base);
            carry = carry / base | 0;
        }
    }
    var output = '';
    // deal with leading zeros
    for(i = 0; input.at(i) === 0 && i < input.length() - 1; ++i)output += first;
    // convert digits to a string
    for(i = digits.length - 1; i >= 0; --i)output += alphabet[digits[i]];
    return output;
}

},{"buffer":"joWnX"}],"iymJu":[function(require,module,exports) {
/**
 * Object IDs for ASN.1.
 *
 * @author Dave Longley
 *
 * Copyright (c) 2010-2013 Digital Bazaar, Inc.
 */ var forge = require('./forge');
forge.pki = forge.pki || {
};
var oids = module.exports = forge.pki.oids = forge.oids = forge.oids || {
};
// set id to name mapping and name to id mapping
function _IN(id, name) {
    oids[id] = name;
    oids[name] = id;
}
// set id to name mapping only
function _I_(id, name) {
    oids[id] = name;
}
// algorithm OIDs
_IN('1.2.840.113549.1.1.1', 'rsaEncryption');
// Note: md2 & md4 not implemented
//_IN('1.2.840.113549.1.1.2', 'md2WithRSAEncryption');
//_IN('1.2.840.113549.1.1.3', 'md4WithRSAEncryption');
_IN('1.2.840.113549.1.1.4', 'md5WithRSAEncryption');
_IN('1.2.840.113549.1.1.5', 'sha1WithRSAEncryption');
_IN('1.2.840.113549.1.1.7', 'RSAES-OAEP');
_IN('1.2.840.113549.1.1.8', 'mgf1');
_IN('1.2.840.113549.1.1.9', 'pSpecified');
_IN('1.2.840.113549.1.1.10', 'RSASSA-PSS');
_IN('1.2.840.113549.1.1.11', 'sha256WithRSAEncryption');
_IN('1.2.840.113549.1.1.12', 'sha384WithRSAEncryption');
_IN('1.2.840.113549.1.1.13', 'sha512WithRSAEncryption');
// Edwards-curve Digital Signature Algorithm (EdDSA) Ed25519
_IN('1.3.101.112', 'EdDSA25519');
_IN('1.2.840.10040.4.3', 'dsa-with-sha1');
_IN('1.3.14.3.2.7', 'desCBC');
_IN('1.3.14.3.2.26', 'sha1');
_IN('2.16.840.1.101.3.4.2.1', 'sha256');
_IN('2.16.840.1.101.3.4.2.2', 'sha384');
_IN('2.16.840.1.101.3.4.2.3', 'sha512');
_IN('1.2.840.113549.2.5', 'md5');
// pkcs#7 content types
_IN('1.2.840.113549.1.7.1', 'data');
_IN('1.2.840.113549.1.7.2', 'signedData');
_IN('1.2.840.113549.1.7.3', 'envelopedData');
_IN('1.2.840.113549.1.7.4', 'signedAndEnvelopedData');
_IN('1.2.840.113549.1.7.5', 'digestedData');
_IN('1.2.840.113549.1.7.6', 'encryptedData');
// pkcs#9 oids
_IN('1.2.840.113549.1.9.1', 'emailAddress');
_IN('1.2.840.113549.1.9.2', 'unstructuredName');
_IN('1.2.840.113549.1.9.3', 'contentType');
_IN('1.2.840.113549.1.9.4', 'messageDigest');
_IN('1.2.840.113549.1.9.5', 'signingTime');
_IN('1.2.840.113549.1.9.6', 'counterSignature');
_IN('1.2.840.113549.1.9.7', 'challengePassword');
_IN('1.2.840.113549.1.9.8', 'unstructuredAddress');
_IN('1.2.840.113549.1.9.14', 'extensionRequest');
_IN('1.2.840.113549.1.9.20', 'friendlyName');
_IN('1.2.840.113549.1.9.21', 'localKeyId');
_IN('1.2.840.113549.1.9.22.1', 'x509Certificate');
// pkcs#12 safe bags
_IN('1.2.840.113549.1.12.10.1.1', 'keyBag');
_IN('1.2.840.113549.1.12.10.1.2', 'pkcs8ShroudedKeyBag');
_IN('1.2.840.113549.1.12.10.1.3', 'certBag');
_IN('1.2.840.113549.1.12.10.1.4', 'crlBag');
_IN('1.2.840.113549.1.12.10.1.5', 'secretBag');
_IN('1.2.840.113549.1.12.10.1.6', 'safeContentsBag');
// password-based-encryption for pkcs#12
_IN('1.2.840.113549.1.5.13', 'pkcs5PBES2');
_IN('1.2.840.113549.1.5.12', 'pkcs5PBKDF2');
_IN('1.2.840.113549.1.12.1.1', 'pbeWithSHAAnd128BitRC4');
_IN('1.2.840.113549.1.12.1.2', 'pbeWithSHAAnd40BitRC4');
_IN('1.2.840.113549.1.12.1.3', 'pbeWithSHAAnd3-KeyTripleDES-CBC');
_IN('1.2.840.113549.1.12.1.4', 'pbeWithSHAAnd2-KeyTripleDES-CBC');
_IN('1.2.840.113549.1.12.1.5', 'pbeWithSHAAnd128BitRC2-CBC');
_IN('1.2.840.113549.1.12.1.6', 'pbewithSHAAnd40BitRC2-CBC');
// hmac OIDs
_IN('1.2.840.113549.2.7', 'hmacWithSHA1');
_IN('1.2.840.113549.2.8', 'hmacWithSHA224');
_IN('1.2.840.113549.2.9', 'hmacWithSHA256');
_IN('1.2.840.113549.2.10', 'hmacWithSHA384');
_IN('1.2.840.113549.2.11', 'hmacWithSHA512');
// symmetric key algorithm oids
_IN('1.2.840.113549.3.7', 'des-EDE3-CBC');
_IN('2.16.840.1.101.3.4.1.2', 'aes128-CBC');
_IN('2.16.840.1.101.3.4.1.22', 'aes192-CBC');
_IN('2.16.840.1.101.3.4.1.42', 'aes256-CBC');
// certificate issuer/subject OIDs
_IN('2.5.4.3', 'commonName');
_IN('2.5.4.5', 'serialName');
_IN('2.5.4.6', 'countryName');
_IN('2.5.4.7', 'localityName');
_IN('2.5.4.8', 'stateOrProvinceName');
_IN('2.5.4.9', 'streetAddress');
_IN('2.5.4.10', 'organizationName');
_IN('2.5.4.11', 'organizationalUnitName');
_IN('2.5.4.13', 'description');
_IN('2.5.4.15', 'businessCategory');
_IN('2.5.4.17', 'postalCode');
_IN('1.3.6.1.4.1.311.60.2.1.2', 'jurisdictionOfIncorporationStateOrProvinceName');
_IN('1.3.6.1.4.1.311.60.2.1.3', 'jurisdictionOfIncorporationCountryName');
// X.509 extension OIDs
_IN('2.16.840.1.113730.1.1', 'nsCertType');
_IN('2.16.840.1.113730.1.13', 'nsComment'); // deprecated in theory; still widely used
_I_('2.5.29.1', 'authorityKeyIdentifier'); // deprecated, use .35
_I_('2.5.29.2', 'keyAttributes'); // obsolete use .37 or .15
_I_('2.5.29.3', 'certificatePolicies'); // deprecated, use .32
_I_('2.5.29.4', 'keyUsageRestriction'); // obsolete use .37 or .15
_I_('2.5.29.5', 'policyMapping'); // deprecated use .33
_I_('2.5.29.6', 'subtreesConstraint'); // obsolete use .30
_I_('2.5.29.7', 'subjectAltName'); // deprecated use .17
_I_('2.5.29.8', 'issuerAltName'); // deprecated use .18
_I_('2.5.29.9', 'subjectDirectoryAttributes');
_I_('2.5.29.10', 'basicConstraints'); // deprecated use .19
_I_('2.5.29.11', 'nameConstraints'); // deprecated use .30
_I_('2.5.29.12', 'policyConstraints'); // deprecated use .36
_I_('2.5.29.13', 'basicConstraints'); // deprecated use .19
_IN('2.5.29.14', 'subjectKeyIdentifier');
_IN('2.5.29.15', 'keyUsage');
_I_('2.5.29.16', 'privateKeyUsagePeriod');
_IN('2.5.29.17', 'subjectAltName');
_IN('2.5.29.18', 'issuerAltName');
_IN('2.5.29.19', 'basicConstraints');
_I_('2.5.29.20', 'cRLNumber');
_I_('2.5.29.21', 'cRLReason');
_I_('2.5.29.22', 'expirationDate');
_I_('2.5.29.23', 'instructionCode');
_I_('2.5.29.24', 'invalidityDate');
_I_('2.5.29.25', 'cRLDistributionPoints'); // deprecated use .31
_I_('2.5.29.26', 'issuingDistributionPoint'); // deprecated use .28
_I_('2.5.29.27', 'deltaCRLIndicator');
_I_('2.5.29.28', 'issuingDistributionPoint');
_I_('2.5.29.29', 'certificateIssuer');
_I_('2.5.29.30', 'nameConstraints');
_IN('2.5.29.31', 'cRLDistributionPoints');
_IN('2.5.29.32', 'certificatePolicies');
_I_('2.5.29.33', 'policyMappings');
_I_('2.5.29.34', 'policyConstraints'); // deprecated use .36
_IN('2.5.29.35', 'authorityKeyIdentifier');
_I_('2.5.29.36', 'policyConstraints');
_IN('2.5.29.37', 'extKeyUsage');
_I_('2.5.29.46', 'freshestCRL');
_I_('2.5.29.54', 'inhibitAnyPolicy');
// extKeyUsage purposes
_IN('1.3.6.1.4.1.11129.2.4.2', 'timestampList');
_IN('1.3.6.1.5.5.7.1.1', 'authorityInfoAccess');
_IN('1.3.6.1.5.5.7.3.1', 'serverAuth');
_IN('1.3.6.1.5.5.7.3.2', 'clientAuth');
_IN('1.3.6.1.5.5.7.3.3', 'codeSigning');
_IN('1.3.6.1.5.5.7.3.4', 'emailProtection');
_IN('1.3.6.1.5.5.7.3.8', 'timeStamping');

},{"./forge":"7AnVp"}],"klwlu":[function(require,module,exports) {
/**
 * Password-based encryption functions.
 *
 * @author Dave Longley
 * @author Stefan Siegl <stesie@brokenpipe.de>
 *
 * Copyright (c) 2010-2013 Digital Bazaar, Inc.
 * Copyright (c) 2012 Stefan Siegl <stesie@brokenpipe.de>
 *
 * An EncryptedPrivateKeyInfo:
 *
 * EncryptedPrivateKeyInfo ::= SEQUENCE {
 *   encryptionAlgorithm  EncryptionAlgorithmIdentifier,
 *   encryptedData        EncryptedData }
 *
 * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
 *
 * EncryptedData ::= OCTET STRING
 */ var forge = require('./forge');
require('./aes');
require('./asn1');
require('./des');
require('./md');
require('./oids');
require('./pbkdf2');
require('./pem');
require('./random');
require('./rc2');
require('./rsa');
require('./util');
if (typeof BigInteger === 'undefined') var BigInteger = forge.jsbn.BigInteger;
// shortcut for asn.1 API
var asn1 = forge.asn1;
/* Password-based encryption implementation. */ var pki = forge.pki = forge.pki || {
};
module.exports = pki.pbe = forge.pbe = forge.pbe || {
};
var oids = pki.oids;
// validator for an EncryptedPrivateKeyInfo structure
// Note: Currently only works w/algorithm params
var encryptedPrivateKeyValidator = {
    name: 'EncryptedPrivateKeyInfo',
    tagClass: asn1.Class.UNIVERSAL,
    type: asn1.Type.SEQUENCE,
    constructed: true,
    value: [
        {
            name: 'EncryptedPrivateKeyInfo.encryptionAlgorithm',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.SEQUENCE,
            constructed: true,
            value: [
                {
                    name: 'AlgorithmIdentifier.algorithm',
                    tagClass: asn1.Class.UNIVERSAL,
                    type: asn1.Type.OID,
                    constructed: false,
                    capture: 'encryptionOid'
                },
                {
                    name: 'AlgorithmIdentifier.parameters',
                    tagClass: asn1.Class.UNIVERSAL,
                    type: asn1.Type.SEQUENCE,
                    constructed: true,
                    captureAsn1: 'encryptionParams'
                }
            ]
        },
        {
            // encryptedData
            name: 'EncryptedPrivateKeyInfo.encryptedData',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.OCTETSTRING,
            constructed: false,
            capture: 'encryptedData'
        }
    ]
};
// validator for a PBES2Algorithms structure
// Note: Currently only works w/PBKDF2 + AES encryption schemes
var PBES2AlgorithmsValidator = {
    name: 'PBES2Algorithms',
    tagClass: asn1.Class.UNIVERSAL,
    type: asn1.Type.SEQUENCE,
    constructed: true,
    value: [
        {
            name: 'PBES2Algorithms.keyDerivationFunc',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.SEQUENCE,
            constructed: true,
            value: [
                {
                    name: 'PBES2Algorithms.keyDerivationFunc.oid',
                    tagClass: asn1.Class.UNIVERSAL,
                    type: asn1.Type.OID,
                    constructed: false,
                    capture: 'kdfOid'
                },
                {
                    name: 'PBES2Algorithms.params',
                    tagClass: asn1.Class.UNIVERSAL,
                    type: asn1.Type.SEQUENCE,
                    constructed: true,
                    value: [
                        {
                            name: 'PBES2Algorithms.params.salt',
                            tagClass: asn1.Class.UNIVERSAL,
                            type: asn1.Type.OCTETSTRING,
                            constructed: false,
                            capture: 'kdfSalt'
                        },
                        {
                            name: 'PBES2Algorithms.params.iterationCount',
                            tagClass: asn1.Class.UNIVERSAL,
                            type: asn1.Type.INTEGER,
                            constructed: false,
                            capture: 'kdfIterationCount'
                        },
                        {
                            name: 'PBES2Algorithms.params.keyLength',
                            tagClass: asn1.Class.UNIVERSAL,
                            type: asn1.Type.INTEGER,
                            constructed: false,
                            optional: true,
                            capture: 'keyLength'
                        },
                        {
                            // prf
                            name: 'PBES2Algorithms.params.prf',
                            tagClass: asn1.Class.UNIVERSAL,
                            type: asn1.Type.SEQUENCE,
                            constructed: true,
                            optional: true,
                            value: [
                                {
                                    name: 'PBES2Algorithms.params.prf.algorithm',
                                    tagClass: asn1.Class.UNIVERSAL,
                                    type: asn1.Type.OID,
                                    constructed: false,
                                    capture: 'prfOid'
                                }
                            ]
                        }
                    ]
                }
            ]
        },
        {
            name: 'PBES2Algorithms.encryptionScheme',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.SEQUENCE,
            constructed: true,
            value: [
                {
                    name: 'PBES2Algorithms.encryptionScheme.oid',
                    tagClass: asn1.Class.UNIVERSAL,
                    type: asn1.Type.OID,
                    constructed: false,
                    capture: 'encOid'
                },
                {
                    name: 'PBES2Algorithms.encryptionScheme.iv',
                    tagClass: asn1.Class.UNIVERSAL,
                    type: asn1.Type.OCTETSTRING,
                    constructed: false,
                    capture: 'encIv'
                }
            ]
        }
    ]
};
var pkcs12PbeParamsValidator = {
    name: 'pkcs-12PbeParams',
    tagClass: asn1.Class.UNIVERSAL,
    type: asn1.Type.SEQUENCE,
    constructed: true,
    value: [
        {
            name: 'pkcs-12PbeParams.salt',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.OCTETSTRING,
            constructed: false,
            capture: 'salt'
        },
        {
            name: 'pkcs-12PbeParams.iterations',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.INTEGER,
            constructed: false,
            capture: 'iterations'
        }
    ]
};
/**
 * Encrypts a ASN.1 PrivateKeyInfo object, producing an EncryptedPrivateKeyInfo.
 *
 * PBES2Algorithms ALGORITHM-IDENTIFIER ::=
 *   { {PBES2-params IDENTIFIED BY id-PBES2}, ...}
 *
 * id-PBES2 OBJECT IDENTIFIER ::= {pkcs-5 13}
 *
 * PBES2-params ::= SEQUENCE {
 *   keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}},
 *   encryptionScheme AlgorithmIdentifier {{PBES2-Encs}}
 * }
 *
 * PBES2-KDFs ALGORITHM-IDENTIFIER ::=
 *   { {PBKDF2-params IDENTIFIED BY id-PBKDF2}, ... }
 *
 * PBES2-Encs ALGORITHM-IDENTIFIER ::= { ... }
 *
 * PBKDF2-params ::= SEQUENCE {
 *   salt CHOICE {
 *     specified OCTET STRING,
 *     otherSource AlgorithmIdentifier {{PBKDF2-SaltSources}}
 *   },
 *   iterationCount INTEGER (1..MAX),
 *   keyLength INTEGER (1..MAX) OPTIONAL,
 *   prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1
 * }
 *
 * @param obj the ASN.1 PrivateKeyInfo object.
 * @param password the password to encrypt with.
 * @param options:
 *          algorithm the encryption algorithm to use
 *            ('aes128', 'aes192', 'aes256', '3des'), defaults to 'aes128'.
 *          count the iteration count to use.
 *          saltSize the salt size to use.
 *          prfAlgorithm the PRF message digest algorithm to use
 *            ('sha1', 'sha224', 'sha256', 'sha384', 'sha512')
 *
 * @return the ASN.1 EncryptedPrivateKeyInfo.
 */ pki.encryptPrivateKeyInfo = function(obj, password, options) {
    // set default options
    options = options || {
    };
    options.saltSize = options.saltSize || 8;
    options.count = options.count || 2048;
    options.algorithm = options.algorithm || 'aes128';
    options.prfAlgorithm = options.prfAlgorithm || 'sha1';
    // generate PBE params
    var salt = forge.random.getBytesSync(options.saltSize);
    var count = options.count;
    var countBytes = asn1.integerToDer(count);
    var dkLen;
    var encryptionAlgorithm;
    var encryptedData;
    if (options.algorithm.indexOf('aes') === 0 || options.algorithm === 'des') {
        // do PBES2
        var ivLen, encOid, cipherFn;
        switch(options.algorithm){
            case 'aes128':
                dkLen = 16;
                ivLen = 16;
                encOid = oids['aes128-CBC'];
                cipherFn = forge.aes.createEncryptionCipher;
                break;
            case 'aes192':
                dkLen = 24;
                ivLen = 16;
                encOid = oids['aes192-CBC'];
                cipherFn = forge.aes.createEncryptionCipher;
                break;
            case 'aes256':
                dkLen = 32;
                ivLen = 16;
                encOid = oids['aes256-CBC'];
                cipherFn = forge.aes.createEncryptionCipher;
                break;
            case 'des':
                dkLen = 8;
                ivLen = 8;
                encOid = oids['desCBC'];
                cipherFn = forge.des.createEncryptionCipher;
                break;
            default:
                var error = new Error('Cannot encrypt private key. Unknown encryption algorithm.');
                error.algorithm = options.algorithm;
                throw error;
        }
        // get PRF message digest
        var prfAlgorithm = 'hmacWith' + options.prfAlgorithm.toUpperCase();
        var md = prfAlgorithmToMessageDigest(prfAlgorithm);
        // encrypt private key using pbe SHA-1 and AES/DES
        var dk = forge.pkcs5.pbkdf2(password, salt, count, dkLen, md);
        var iv = forge.random.getBytesSync(ivLen);
        var cipher = cipherFn(dk);
        cipher.start(iv);
        cipher.update(asn1.toDer(obj));
        cipher.finish();
        encryptedData = cipher.output.getBytes();
        // get PBKDF2-params
        var params = createPbkdf2Params(salt, countBytes, dkLen, prfAlgorithm);
        encryptionAlgorithm = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
            asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(oids['pkcs5PBES2']).getBytes()),
            asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
                // keyDerivationFunc
                asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
                    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(oids['pkcs5PBKDF2']).getBytes()),
                    // PBKDF2-params
                    params
                ]),
                // encryptionScheme
                asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
                    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(encOid).getBytes()),
                    // iv
                    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, iv)
                ])
            ])
        ]);
    } else if (options.algorithm === '3des') {
        // Do PKCS12 PBE
        dkLen = 24;
        var saltBytes = new forge.util.ByteBuffer(salt);
        var dk = pki.pbe.generatePkcs12Key(password, saltBytes, 1, count, dkLen);
        var iv = pki.pbe.generatePkcs12Key(password, saltBytes, 2, count, dkLen);
        var cipher = forge.des.createEncryptionCipher(dk);
        cipher.start(iv);
        cipher.update(asn1.toDer(obj));
        cipher.finish();
        encryptedData = cipher.output.getBytes();
        encryptionAlgorithm = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
            asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(oids['pbeWithSHAAnd3-KeyTripleDES-CBC']).getBytes()),
            // pkcs-12PbeParams
            asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
                // salt
                asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, salt),
                // iteration count
                asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, countBytes.getBytes())
            ])
        ]);
    } else {
        var error = new Error('Cannot encrypt private key. Unknown encryption algorithm.');
        error.algorithm = options.algorithm;
        throw error;
    }
    // EncryptedPrivateKeyInfo
    var rval = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
        // encryptionAlgorithm
        encryptionAlgorithm,
        // encryptedData
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, encryptedData)
    ]);
    return rval;
};
/**
 * Decrypts a ASN.1 PrivateKeyInfo object.
 *
 * @param obj the ASN.1 EncryptedPrivateKeyInfo object.
 * @param password the password to decrypt with.
 *
 * @return the ASN.1 PrivateKeyInfo on success, null on failure.
 */ pki.decryptPrivateKeyInfo = function(obj, password) {
    var rval = null;
    // get PBE params
    var capture = {
    };
    var errors = [];
    if (!asn1.validate(obj, encryptedPrivateKeyValidator, capture, errors)) {
        var error = new Error("Cannot read encrypted private key. ASN.1 object is not a supported EncryptedPrivateKeyInfo.");
        error.errors = errors;
        throw error;
    }
    // get cipher
    var oid = asn1.derToOid(capture.encryptionOid);
    var cipher = pki.pbe.getCipher(oid, capture.encryptionParams, password);
    // get encrypted data
    var encrypted = forge.util.createBuffer(capture.encryptedData);
    cipher.update(encrypted);
    if (cipher.finish()) rval = asn1.fromDer(cipher.output);
    return rval;
};
/**
 * Converts a EncryptedPrivateKeyInfo to PEM format.
 *
 * @param epki the EncryptedPrivateKeyInfo.
 * @param maxline the maximum characters per line, defaults to 64.
 *
 * @return the PEM-formatted encrypted private key.
 */ pki.encryptedPrivateKeyToPem = function(epki, maxline) {
    // convert to DER, then PEM-encode
    var msg = {
        type: 'ENCRYPTED PRIVATE KEY',
        body: asn1.toDer(epki).getBytes()
    };
    return forge.pem.encode(msg, {
        maxline: maxline
    });
};
/**
 * Converts a PEM-encoded EncryptedPrivateKeyInfo to ASN.1 format. Decryption
 * is not performed.
 *
 * @param pem the EncryptedPrivateKeyInfo in PEM-format.
 *
 * @return the ASN.1 EncryptedPrivateKeyInfo.
 */ pki.encryptedPrivateKeyFromPem = function(pem) {
    var msg = forge.pem.decode(pem)[0];
    if (msg.type !== 'ENCRYPTED PRIVATE KEY') {
        var error = new Error("Could not convert encrypted private key from PEM; PEM header type is \"ENCRYPTED PRIVATE KEY\".");
        error.headerType = msg.type;
        throw error;
    }
    if (msg.procType && msg.procType.type === 'ENCRYPTED') throw new Error("Could not convert encrypted private key from PEM; PEM is encrypted.");
    // convert DER to ASN.1 object
    return asn1.fromDer(msg.body);
};
/**
 * Encrypts an RSA private key. By default, the key will be wrapped in
 * a PrivateKeyInfo and encrypted to produce a PKCS#8 EncryptedPrivateKeyInfo.
 * This is the standard, preferred way to encrypt a private key.
 *
 * To produce a non-standard PEM-encrypted private key that uses encapsulated
 * headers to indicate the encryption algorithm (old-style non-PKCS#8 OpenSSL
 * private key encryption), set the 'legacy' option to true. Note: Using this
 * option will cause the iteration count to be forced to 1.
 *
 * Note: The 'des' algorithm is supported, but it is not considered to be
 * secure because it only uses a single 56-bit key. If possible, it is highly
 * recommended that a different algorithm be used.
 *
 * @param rsaKey the RSA key to encrypt.
 * @param password the password to use.
 * @param options:
 *          algorithm: the encryption algorithm to use
 *            ('aes128', 'aes192', 'aes256', '3des', 'des').
 *          count: the iteration count to use.
 *          saltSize: the salt size to use.
 *          legacy: output an old non-PKCS#8 PEM-encrypted+encapsulated
 *            headers (DEK-Info) private key.
 *
 * @return the PEM-encoded ASN.1 EncryptedPrivateKeyInfo.
 */ pki.encryptRsaPrivateKey = function(rsaKey, password, options) {
    // standard PKCS#8
    options = options || {
    };
    if (!options.legacy) {
        // encrypt PrivateKeyInfo
        var rval = pki.wrapRsaPrivateKey(pki.privateKeyToAsn1(rsaKey));
        rval = pki.encryptPrivateKeyInfo(rval, password, options);
        return pki.encryptedPrivateKeyToPem(rval);
    }
    // legacy non-PKCS#8
    var algorithm;
    var iv;
    var dkLen;
    var cipherFn;
    switch(options.algorithm){
        case 'aes128':
            algorithm = 'AES-128-CBC';
            dkLen = 16;
            iv = forge.random.getBytesSync(16);
            cipherFn = forge.aes.createEncryptionCipher;
            break;
        case 'aes192':
            algorithm = 'AES-192-CBC';
            dkLen = 24;
            iv = forge.random.getBytesSync(16);
            cipherFn = forge.aes.createEncryptionCipher;
            break;
        case 'aes256':
            algorithm = 'AES-256-CBC';
            dkLen = 32;
            iv = forge.random.getBytesSync(16);
            cipherFn = forge.aes.createEncryptionCipher;
            break;
        case '3des':
            algorithm = 'DES-EDE3-CBC';
            dkLen = 24;
            iv = forge.random.getBytesSync(8);
            cipherFn = forge.des.createEncryptionCipher;
            break;
        case 'des':
            algorithm = 'DES-CBC';
            dkLen = 8;
            iv = forge.random.getBytesSync(8);
            cipherFn = forge.des.createEncryptionCipher;
            break;
        default:
            var error = new Error("Could not encrypt RSA private key; unsupported encryption algorithm \"" + options.algorithm + '".');
            error.algorithm = options.algorithm;
            throw error;
    }
    // encrypt private key using OpenSSL legacy key derivation
    var dk = forge.pbe.opensslDeriveBytes(password, iv.substr(0, 8), dkLen);
    var cipher = cipherFn(dk);
    cipher.start(iv);
    cipher.update(asn1.toDer(pki.privateKeyToAsn1(rsaKey)));
    cipher.finish();
    var msg = {
        type: 'RSA PRIVATE KEY',
        procType: {
            version: '4',
            type: 'ENCRYPTED'
        },
        dekInfo: {
            algorithm: algorithm,
            parameters: forge.util.bytesToHex(iv).toUpperCase()
        },
        body: cipher.output.getBytes()
    };
    return forge.pem.encode(msg);
};
/**
 * Decrypts an RSA private key.
 *
 * @param pem the PEM-formatted EncryptedPrivateKeyInfo to decrypt.
 * @param password the password to use.
 *
 * @return the RSA key on success, null on failure.
 */ pki.decryptRsaPrivateKey = function(pem, password) {
    var rval = null;
    var msg = forge.pem.decode(pem)[0];
    if (msg.type !== 'ENCRYPTED PRIVATE KEY' && msg.type !== 'PRIVATE KEY' && msg.type !== 'RSA PRIVATE KEY') {
        var error = new Error("Could not convert private key from PEM; PEM header type is not \"ENCRYPTED PRIVATE KEY\", \"PRIVATE KEY\", or \"RSA PRIVATE KEY\".");
        error.headerType = error;
        throw error;
    }
    if (msg.procType && msg.procType.type === 'ENCRYPTED') {
        var dkLen;
        var cipherFn;
        switch(msg.dekInfo.algorithm){
            case 'DES-CBC':
                dkLen = 8;
                cipherFn = forge.des.createDecryptionCipher;
                break;
            case 'DES-EDE3-CBC':
                dkLen = 24;
                cipherFn = forge.des.createDecryptionCipher;
                break;
            case 'AES-128-CBC':
                dkLen = 16;
                cipherFn = forge.aes.createDecryptionCipher;
                break;
            case 'AES-192-CBC':
                dkLen = 24;
                cipherFn = forge.aes.createDecryptionCipher;
                break;
            case 'AES-256-CBC':
                dkLen = 32;
                cipherFn = forge.aes.createDecryptionCipher;
                break;
            case 'RC2-40-CBC':
                dkLen = 5;
                cipherFn = function(key) {
                    return forge.rc2.createDecryptionCipher(key, 40);
                };
                break;
            case 'RC2-64-CBC':
                dkLen = 8;
                cipherFn = function(key) {
                    return forge.rc2.createDecryptionCipher(key, 64);
                };
                break;
            case 'RC2-128-CBC':
                dkLen = 16;
                cipherFn = function(key) {
                    return forge.rc2.createDecryptionCipher(key, 128);
                };
                break;
            default:
                var error = new Error("Could not decrypt private key; unsupported encryption algorithm \"" + msg.dekInfo.algorithm + '".');
                error.algorithm = msg.dekInfo.algorithm;
                throw error;
        }
        // use OpenSSL legacy key derivation
        var iv = forge.util.hexToBytes(msg.dekInfo.parameters);
        var dk = forge.pbe.opensslDeriveBytes(password, iv.substr(0, 8), dkLen);
        var cipher = cipherFn(dk);
        cipher.start(iv);
        cipher.update(forge.util.createBuffer(msg.body));
        if (cipher.finish()) rval = cipher.output.getBytes();
        else return rval;
    } else rval = msg.body;
    if (msg.type === 'ENCRYPTED PRIVATE KEY') rval = pki.decryptPrivateKeyInfo(asn1.fromDer(rval), password);
    else // decryption already performed above
    rval = asn1.fromDer(rval);
    if (rval !== null) rval = pki.privateKeyFromAsn1(rval);
    return rval;
};
/**
 * Derives a PKCS#12 key.
 *
 * @param password the password to derive the key material from, null or
 *          undefined for none.
 * @param salt the salt, as a ByteBuffer, to use.
 * @param id the PKCS#12 ID byte (1 = key material, 2 = IV, 3 = MAC).
 * @param iter the iteration count.
 * @param n the number of bytes to derive from the password.
 * @param md the message digest to use, defaults to SHA-1.
 *
 * @return a ByteBuffer with the bytes derived from the password.
 */ pki.pbe.generatePkcs12Key = function(password, salt, id, iter, n, md) {
    var j, l;
    if (typeof md === 'undefined' || md === null) {
        if (!('sha1' in forge.md)) throw new Error('"sha1" hash algorithm unavailable.');
        md = forge.md.sha1.create();
    }
    var u = md.digestLength;
    var v = md.blockLength;
    var result = new forge.util.ByteBuffer();
    /* Convert password to Unicode byte buffer + trailing 0-byte. */ var passBuf = new forge.util.ByteBuffer();
    if (password !== null && password !== undefined) {
        for(l = 0; l < password.length; l++)passBuf.putInt16(password.charCodeAt(l));
        passBuf.putInt16(0);
    }
    /* Length of salt and password in BYTES. */ var p = passBuf.length();
    var s = salt.length();
    /* 1. Construct a string, D (the "diversifier"), by concatenating
        v copies of ID. */ var D = new forge.util.ByteBuffer();
    D.fillWithByte(id, v);
    /* 2. Concatenate copies of the salt together to create a string S of length
        v * ceil(s / v) bytes (the final copy of the salt may be trunacted
        to create S).
        Note that if the salt is the empty string, then so is S. */ var Slen = v * Math.ceil(s / v);
    var S = new forge.util.ByteBuffer();
    for(l = 0; l < Slen; l++)S.putByte(salt.at(l % s));
    /* 3. Concatenate copies of the password together to create a string P of
        length v * ceil(p / v) bytes (the final copy of the password may be
        truncated to create P).
        Note that if the password is the empty string, then so is P. */ var Plen = v * Math.ceil(p / v);
    var P = new forge.util.ByteBuffer();
    for(l = 0; l < Plen; l++)P.putByte(passBuf.at(l % p));
    /* 4. Set I=S||P to be the concatenation of S and P. */ var I = S;
    I.putBuffer(P);
    /* 5. Set c=ceil(n / u). */ var c = Math.ceil(n / u);
    /* 6. For i=1, 2, ..., c, do the following: */ for(var i = 1; i <= c; i++){
        /* a) Set Ai=H^r(D||I). (l.e. the rth hash of D||I, H(H(H(...H(D||I)))) */ var buf = new forge.util.ByteBuffer();
        buf.putBytes(D.bytes());
        buf.putBytes(I.bytes());
        for(var round = 0; round < iter; round++){
            md.start();
            md.update(buf.getBytes());
            buf = md.digest();
        }
        /* b) Concatenate copies of Ai to create a string B of length v bytes (the
          final copy of Ai may be truncated to create B). */ var B = new forge.util.ByteBuffer();
        for(l = 0; l < v; l++)B.putByte(buf.at(l % u));
        /* c) Treating I as a concatenation I0, I1, ..., Ik-1 of v-byte blocks,
          where k=ceil(s / v) + ceil(p / v), modify I by setting
          Ij=(Ij+B+1) mod 2v for each j.  */ var k = Math.ceil(s / v) + Math.ceil(p / v);
        var Inew = new forge.util.ByteBuffer();
        for(j = 0; j < k; j++){
            var chunk = new forge.util.ByteBuffer(I.getBytes(v));
            var x = 511;
            for(l = B.length() - 1; l >= 0; l--){
                x = x >> 8;
                x += B.at(l) + chunk.at(l);
                chunk.setAt(l, x & 255);
            }
            Inew.putBuffer(chunk);
        }
        I = Inew;
        /* Add Ai to A. */ result.putBuffer(buf);
    }
    result.truncate(result.length() - n);
    return result;
};
/**
 * Get new Forge cipher object instance.
 *
 * @param oid the OID (in string notation).
 * @param params the ASN.1 params object.
 * @param password the password to decrypt with.
 *
 * @return new cipher object instance.
 */ pki.pbe.getCipher = function(oid, params, password) {
    switch(oid){
        case pki.oids['pkcs5PBES2']:
            return pki.pbe.getCipherForPBES2(oid, params, password);
        case pki.oids['pbeWithSHAAnd3-KeyTripleDES-CBC']:
        case pki.oids['pbewithSHAAnd40BitRC2-CBC']:
            return pki.pbe.getCipherForPKCS12PBE(oid, params, password);
        default:
            var error = new Error('Cannot read encrypted PBE data block. Unsupported OID.');
            error.oid = oid;
            error.supportedOids = [
                'pkcs5PBES2',
                'pbeWithSHAAnd3-KeyTripleDES-CBC',
                'pbewithSHAAnd40BitRC2-CBC'
            ];
            throw error;
    }
};
/**
 * Get new Forge cipher object instance according to PBES2 params block.
 *
 * The returned cipher instance is already started using the IV
 * from PBES2 parameter block.
 *
 * @param oid the PKCS#5 PBKDF2 OID (in string notation).
 * @param params the ASN.1 PBES2-params object.
 * @param password the password to decrypt with.
 *
 * @return new cipher object instance.
 */ pki.pbe.getCipherForPBES2 = function(oid, params, password) {
    // get PBE params
    var capture = {
    };
    var errors = [];
    if (!asn1.validate(params, PBES2AlgorithmsValidator, capture, errors)) {
        var error = new Error("Cannot read password-based-encryption algorithm parameters. ASN.1 object is not a supported EncryptedPrivateKeyInfo.");
        error.errors = errors;
        throw error;
    }
    // check oids
    oid = asn1.derToOid(capture.kdfOid);
    if (oid !== pki.oids['pkcs5PBKDF2']) {
        var error = new Error("Cannot read encrypted private key. Unsupported key derivation function OID.");
        error.oid = oid;
        error.supportedOids = [
            'pkcs5PBKDF2'
        ];
        throw error;
    }
    oid = asn1.derToOid(capture.encOid);
    if (oid !== pki.oids['aes128-CBC'] && oid !== pki.oids['aes192-CBC'] && oid !== pki.oids['aes256-CBC'] && oid !== pki.oids['des-EDE3-CBC'] && oid !== pki.oids['desCBC']) {
        var error = new Error("Cannot read encrypted private key. Unsupported encryption scheme OID.");
        error.oid = oid;
        error.supportedOids = [
            'aes128-CBC',
            'aes192-CBC',
            'aes256-CBC',
            'des-EDE3-CBC',
            'desCBC'
        ];
        throw error;
    }
    // set PBE params
    var salt = capture.kdfSalt;
    var count = forge.util.createBuffer(capture.kdfIterationCount);
    count = count.getInt(count.length() << 3);
    var dkLen;
    var cipherFn;
    switch(pki.oids[oid]){
        case 'aes128-CBC':
            dkLen = 16;
            cipherFn = forge.aes.createDecryptionCipher;
            break;
        case 'aes192-CBC':
            dkLen = 24;
            cipherFn = forge.aes.createDecryptionCipher;
            break;
        case 'aes256-CBC':
            dkLen = 32;
            cipherFn = forge.aes.createDecryptionCipher;
            break;
        case 'des-EDE3-CBC':
            dkLen = 24;
            cipherFn = forge.des.createDecryptionCipher;
            break;
        case 'desCBC':
            dkLen = 8;
            cipherFn = forge.des.createDecryptionCipher;
            break;
    }
    // get PRF message digest
    var md = prfOidToMessageDigest(capture.prfOid);
    // decrypt private key using pbe with chosen PRF and AES/DES
    var dk = forge.pkcs5.pbkdf2(password, salt, count, dkLen, md);
    var iv = capture.encIv;
    var cipher = cipherFn(dk);
    cipher.start(iv);
    return cipher;
};
/**
 * Get new Forge cipher object instance for PKCS#12 PBE.
 *
 * The returned cipher instance is already started using the key & IV
 * derived from the provided password and PKCS#12 PBE salt.
 *
 * @param oid The PKCS#12 PBE OID (in string notation).
 * @param params The ASN.1 PKCS#12 PBE-params object.
 * @param password The password to decrypt with.
 *
 * @return the new cipher object instance.
 */ pki.pbe.getCipherForPKCS12PBE = function(oid, params, password) {
    // get PBE params
    var capture = {
    };
    var errors = [];
    if (!asn1.validate(params, pkcs12PbeParamsValidator, capture, errors)) {
        var error = new Error("Cannot read password-based-encryption algorithm parameters. ASN.1 object is not a supported EncryptedPrivateKeyInfo.");
        error.errors = errors;
        throw error;
    }
    var salt = forge.util.createBuffer(capture.salt);
    var count = forge.util.createBuffer(capture.iterations);
    count = count.getInt(count.length() << 3);
    var dkLen, dIvLen, cipherFn;
    switch(oid){
        case pki.oids['pbeWithSHAAnd3-KeyTripleDES-CBC']:
            dkLen = 24;
            dIvLen = 8;
            cipherFn = forge.des.startDecrypting;
            break;
        case pki.oids['pbewithSHAAnd40BitRC2-CBC']:
            dkLen = 5;
            dIvLen = 8;
            cipherFn = function(key, iv) {
                var cipher = forge.rc2.createDecryptionCipher(key, 40);
                cipher.start(iv, null);
                return cipher;
            };
            break;
        default:
            var error = new Error('Cannot read PKCS #12 PBE data block. Unsupported OID.');
            error.oid = oid;
            throw error;
    }
    // get PRF message digest
    var md = prfOidToMessageDigest(capture.prfOid);
    var key1 = pki.pbe.generatePkcs12Key(password, salt, 1, count, dkLen, md);
    md.start();
    var iv1 = pki.pbe.generatePkcs12Key(password, salt, 2, count, dIvLen, md);
    return cipherFn(key1, iv1);
};
/**
 * OpenSSL's legacy key derivation function.
 *
 * See: http://www.openssl.org/docs/crypto/EVP_BytesToKey.html
 *
 * @param password the password to derive the key from.
 * @param salt the salt to use, null for none.
 * @param dkLen the number of bytes needed for the derived key.
 * @param [options] the options to use:
 *          [md] an optional message digest object to use.
 */ pki.pbe.opensslDeriveBytes = function(password, salt, dkLen, md) {
    if (typeof md === 'undefined' || md === null) {
        if (!('md5' in forge.md)) throw new Error('"md5" hash algorithm unavailable.');
        md = forge.md.md5.create();
    }
    if (salt === null) salt = '';
    var digests = [
        hash(md, password + salt)
    ];
    for(var length = 16, i = 1; length < dkLen; ++i, length += 16)digests.push(hash(md, digests[i - 1] + password + salt));
    return digests.join('').substr(0, dkLen);
};
function hash(md, bytes) {
    return md.start().update(bytes).digest().getBytes();
}
function prfOidToMessageDigest(prfOid) {
    // get PRF algorithm, default to SHA-1
    var prfAlgorithm;
    if (!prfOid) prfAlgorithm = 'hmacWithSHA1';
    else {
        prfAlgorithm = pki.oids[asn1.derToOid(prfOid)];
        if (!prfAlgorithm) {
            var error = new Error('Unsupported PRF OID.');
            error.oid = prfOid;
            error.supported = [
                'hmacWithSHA1',
                'hmacWithSHA224',
                'hmacWithSHA256',
                'hmacWithSHA384',
                'hmacWithSHA512'
            ];
            throw error;
        }
    }
    return prfAlgorithmToMessageDigest(prfAlgorithm);
}
function prfAlgorithmToMessageDigest(prfAlgorithm) {
    var factory = forge.md;
    switch(prfAlgorithm){
        case 'hmacWithSHA224':
            factory = forge.md.sha512;
        case 'hmacWithSHA1':
        case 'hmacWithSHA256':
        case 'hmacWithSHA384':
        case 'hmacWithSHA512':
            prfAlgorithm = prfAlgorithm.substr(8).toLowerCase();
            break;
        default:
            var error = new Error('Unsupported PRF algorithm.');
            error.algorithm = prfAlgorithm;
            error.supported = [
                'hmacWithSHA1',
                'hmacWithSHA224',
                'hmacWithSHA256',
                'hmacWithSHA384',
                'hmacWithSHA512'
            ];
            throw error;
    }
    if (!factory || !(prfAlgorithm in factory)) throw new Error('Unknown hash algorithm: ' + prfAlgorithm);
    return factory[prfAlgorithm].create();
}
function createPbkdf2Params(salt, countBytes, dkLen, prfAlgorithm) {
    var params = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
        // salt
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, salt),
        // iteration count
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, countBytes.getBytes())
    ]);
    // when PRF algorithm is not SHA-1 default, add key length and PRF algorithm
    if (prfAlgorithm !== 'hmacWithSHA1') params.value.push(// key length
    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, forge.util.hexToBytes(dkLen.toString(16))), // AlgorithmIdentifier
    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
        // algorithm
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(pki.oids[prfAlgorithm]).getBytes()),
        // parameters (null)
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '')
    ]));
    return params;
}

},{"./forge":"7AnVp","./aes":"jgIby","./asn1":"fLyrX","./des":"6QyDg","./md":"9dnCj","./oids":"iymJu","./pbkdf2":"j4d8T","./pem":"axmYn","./random":"7GrCn","./rc2":"2vA0U","./rsa":"2GXRz","./util":"cHj6b"}],"jgIby":[function(require,module,exports) {
/**
 * Advanced Encryption Standard (AES) implementation.
 *
 * This implementation is based on the public domain library 'jscrypto' which
 * was written by:
 *
 * Emily Stark (estark@stanford.edu)
 * Mike Hamburg (mhamburg@stanford.edu)
 * Dan Boneh (dabo@cs.stanford.edu)
 *
 * Parts of this code are based on the OpenSSL implementation of AES:
 * http://www.openssl.org
 *
 * @author Dave Longley
 *
 * Copyright (c) 2010-2014 Digital Bazaar, Inc.
 */ var forge = require('./forge');
require('./cipher');
require('./cipherModes');
require('./util');
/* AES API */ module.exports = forge.aes = forge.aes || {
};
/**
 * Deprecated. Instead, use:
 *
 * var cipher = forge.cipher.createCipher('AES-<mode>', key);
 * cipher.start({iv: iv});
 *
 * Creates an AES cipher object to encrypt data using the given symmetric key.
 * The output will be stored in the 'output' member of the returned cipher.
 *
 * The key and iv may be given as a string of bytes, an array of bytes,
 * a byte buffer, or an array of 32-bit words.
 *
 * @param key the symmetric key to use.
 * @param iv the initialization vector to use.
 * @param output the buffer to write to, null to create one.
 * @param mode the cipher mode to use (default: 'CBC').
 *
 * @return the cipher.
 */ forge.aes.startEncrypting = function(key, iv, output, mode) {
    var cipher = _createCipher({
        key: key,
        output: output,
        decrypt: false,
        mode: mode
    });
    cipher.start(iv);
    return cipher;
};
/**
 * Deprecated. Instead, use:
 *
 * var cipher = forge.cipher.createCipher('AES-<mode>', key);
 *
 * Creates an AES cipher object to encrypt data using the given symmetric key.
 *
 * The key may be given as a string of bytes, an array of bytes, a
 * byte buffer, or an array of 32-bit words.
 *
 * @param key the symmetric key to use.
 * @param mode the cipher mode to use (default: 'CBC').
 *
 * @return the cipher.
 */ forge.aes.createEncryptionCipher = function(key, mode) {
    return _createCipher({
        key: key,
        output: null,
        decrypt: false,
        mode: mode
    });
};
/**
 * Deprecated. Instead, use:
 *
 * var decipher = forge.cipher.createDecipher('AES-<mode>', key);
 * decipher.start({iv: iv});
 *
 * Creates an AES cipher object to decrypt data using the given symmetric key.
 * The output will be stored in the 'output' member of the returned cipher.
 *
 * The key and iv may be given as a string of bytes, an array of bytes,
 * a byte buffer, or an array of 32-bit words.
 *
 * @param key the symmetric key to use.
 * @param iv the initialization vector to use.
 * @param output the buffer to write to, null to create one.
 * @param mode the cipher mode to use (default: 'CBC').
 *
 * @return the cipher.
 */ forge.aes.startDecrypting = function(key, iv, output, mode) {
    var cipher = _createCipher({
        key: key,
        output: output,
        decrypt: true,
        mode: mode
    });
    cipher.start(iv);
    return cipher;
};
/**
 * Deprecated. Instead, use:
 *
 * var decipher = forge.cipher.createDecipher('AES-<mode>', key);
 *
 * Creates an AES cipher object to decrypt data using the given symmetric key.
 *
 * The key may be given as a string of bytes, an array of bytes, a
 * byte buffer, or an array of 32-bit words.
 *
 * @param key the symmetric key to use.
 * @param mode the cipher mode to use (default: 'CBC').
 *
 * @return the cipher.
 */ forge.aes.createDecryptionCipher = function(key, mode) {
    return _createCipher({
        key: key,
        output: null,
        decrypt: true,
        mode: mode
    });
};
/**
 * Creates a new AES cipher algorithm object.
 *
 * @param name the name of the algorithm.
 * @param mode the mode factory function.
 *
 * @return the AES algorithm object.
 */ forge.aes.Algorithm = function(name, mode) {
    if (!init) initialize();
    var self = this;
    self.name = name;
    self.mode = new mode({
        blockSize: 16,
        cipher: {
            encrypt: function(inBlock, outBlock) {
                return _updateBlock(self._w, inBlock, outBlock, false);
            },
            decrypt: function(inBlock, outBlock) {
                return _updateBlock(self._w, inBlock, outBlock, true);
            }
        }
    });
    self._init = false;
};
/**
 * Initializes this AES algorithm by expanding its key.
 *
 * @param options the options to use.
 *          key the key to use with this algorithm.
 *          decrypt true if the algorithm should be initialized for decryption,
 *            false for encryption.
 */ forge.aes.Algorithm.prototype.initialize = function(options) {
    if (this._init) return;
    var key = options.key;
    var tmp;
    /* Note: The key may be a string of bytes, an array of bytes, a byte
    buffer, or an array of 32-bit integers. If the key is in bytes, then
    it must be 16, 24, or 32 bytes in length. If it is in 32-bit
    integers, it must be 4, 6, or 8 integers long. */ if (typeof key === 'string' && (key.length === 16 || key.length === 24 || key.length === 32)) // convert key string into byte buffer
    key = forge.util.createBuffer(key);
    else if (forge.util.isArray(key) && (key.length === 16 || key.length === 24 || key.length === 32)) {
        // convert key integer array into byte buffer
        tmp = key;
        key = forge.util.createBuffer();
        for(var i = 0; i < tmp.length; ++i)key.putByte(tmp[i]);
    }
    // convert key byte buffer into 32-bit integer array
    if (!forge.util.isArray(key)) {
        tmp = key;
        key = [];
        // key lengths of 16, 24, 32 bytes allowed
        var len = tmp.length();
        if (len === 16 || len === 24 || len === 32) {
            len = len >>> 2;
            for(var i = 0; i < len; ++i)key.push(tmp.getInt32());
        }
    }
    // key must be an array of 32-bit integers by now
    if (!forge.util.isArray(key) || !(key.length === 4 || key.length === 6 || key.length === 8)) throw new Error('Invalid key parameter.');
    // encryption operation is always used for these modes
    var mode = this.mode.name;
    var encryptOp = [
        'CFB',
        'OFB',
        'CTR',
        'GCM'
    ].indexOf(mode) !== -1;
    // do key expansion
    this._w = _expandKey(key, options.decrypt && !encryptOp);
    this._init = true;
};
/**
 * Expands a key. Typically only used for testing.
 *
 * @param key the symmetric key to expand, as an array of 32-bit words.
 * @param decrypt true to expand for decryption, false for encryption.
 *
 * @return the expanded key.
 */ forge.aes._expandKey = function(key, decrypt) {
    if (!init) initialize();
    return _expandKey(key, decrypt);
};
/**
 * Updates a single block. Typically only used for testing.
 *
 * @param w the expanded key to use.
 * @param input an array of block-size 32-bit words.
 * @param output an array of block-size 32-bit words.
 * @param decrypt true to decrypt, false to encrypt.
 */ forge.aes._updateBlock = _updateBlock;
/** Register AES algorithms **/ registerAlgorithm('AES-ECB', forge.cipher.modes.ecb);
registerAlgorithm('AES-CBC', forge.cipher.modes.cbc);
registerAlgorithm('AES-CFB', forge.cipher.modes.cfb);
registerAlgorithm('AES-OFB', forge.cipher.modes.ofb);
registerAlgorithm('AES-CTR', forge.cipher.modes.ctr);
registerAlgorithm('AES-GCM', forge.cipher.modes.gcm);
function registerAlgorithm(name, mode) {
    var factory = function() {
        return new forge.aes.Algorithm(name, mode);
    };
    forge.cipher.registerAlgorithm(name, factory);
}
/** AES implementation **/ var init = false; // not yet initialized
var Nb = 4; // number of words comprising the state (AES = 4)
var sbox; // non-linear substitution table used in key expansion
var isbox; // inversion of sbox
var rcon; // round constant word array
var mix; // mix-columns table
var imix; // inverse mix-columns table
/**
 * Performs initialization, ie: precomputes tables to optimize for speed.
 *
 * One way to understand how AES works is to imagine that 'addition' and
 * 'multiplication' are interfaces that require certain mathematical
 * properties to hold true (ie: they are associative) but they might have
 * different implementations and produce different kinds of results ...
 * provided that their mathematical properties remain true. AES defines
 * its own methods of addition and multiplication but keeps some important
 * properties the same, ie: associativity and distributivity. The
 * explanation below tries to shed some light on how AES defines addition
 * and multiplication of bytes and 32-bit words in order to perform its
 * encryption and decryption algorithms.
 *
 * The basics:
 *
 * The AES algorithm views bytes as binary representations of polynomials
 * that have either 1 or 0 as the coefficients. It defines the addition
 * or subtraction of two bytes as the XOR operation. It also defines the
 * multiplication of two bytes as a finite field referred to as GF(2^8)
 * (Note: 'GF' means "Galois Field" which is a field that contains a finite
 * number of elements so GF(2^8) has 256 elements).
 *
 * This means that any two bytes can be represented as binary polynomials;
 * when they multiplied together and modularly reduced by an irreducible
 * polynomial of the 8th degree, the results are the field GF(2^8). The
 * specific irreducible polynomial that AES uses in hexadecimal is 0x11b.
 * This multiplication is associative with 0x01 as the identity:
 *
 * (b * 0x01 = GF(b, 0x01) = b).
 *
 * The operation GF(b, 0x02) can be performed at the byte level by left
 * shifting b once and then XOR'ing it (to perform the modular reduction)
 * with 0x11b if b is >= 128. Repeated application of the multiplication
 * of 0x02 can be used to implement the multiplication of any two bytes.
 *
 * For instance, multiplying 0x57 and 0x13, denoted as GF(0x57, 0x13), can
 * be performed by factoring 0x13 into 0x01, 0x02, and 0x10. Then these
 * factors can each be multiplied by 0x57 and then added together. To do
 * the multiplication, values for 0x57 multiplied by each of these 3 factors
 * can be precomputed and stored in a table. To add them, the values from
 * the table are XOR'd together.
 *
 * AES also defines addition and multiplication of words, that is 4-byte
 * numbers represented as polynomials of 3 degrees where the coefficients
 * are the values of the bytes.
 *
 * The word [a0, a1, a2, a3] is a polynomial a3x^3 + a2x^2 + a1x + a0.
 *
 * Addition is performed by XOR'ing like powers of x. Multiplication
 * is performed in two steps, the first is an algebriac expansion as
 * you would do normally (where addition is XOR). But the result is
 * a polynomial larger than 3 degrees and thus it cannot fit in a word. So
 * next the result is modularly reduced by an AES-specific polynomial of
 * degree 4 which will always produce a polynomial of less than 4 degrees
 * such that it will fit in a word. In AES, this polynomial is x^4 + 1.
 *
 * The modular product of two polynomials 'a' and 'b' is thus:
 *
 * d(x) = d3x^3 + d2x^2 + d1x + d0
 * with
 * d0 = GF(a0, b0) ^ GF(a3, b1) ^ GF(a2, b2) ^ GF(a1, b3)
 * d1 = GF(a1, b0) ^ GF(a0, b1) ^ GF(a3, b2) ^ GF(a2, b3)
 * d2 = GF(a2, b0) ^ GF(a1, b1) ^ GF(a0, b2) ^ GF(a3, b3)
 * d3 = GF(a3, b0) ^ GF(a2, b1) ^ GF(a1, b2) ^ GF(a0, b3)
 *
 * As a matrix:
 *
 * [d0] = [a0 a3 a2 a1][b0]
 * [d1]   [a1 a0 a3 a2][b1]
 * [d2]   [a2 a1 a0 a3][b2]
 * [d3]   [a3 a2 a1 a0][b3]
 *
 * Special polynomials defined by AES (0x02 == {02}):
 * a(x)    = {03}x^3 + {01}x^2 + {01}x + {02}
 * a^-1(x) = {0b}x^3 + {0d}x^2 + {09}x + {0e}.
 *
 * These polynomials are used in the MixColumns() and InverseMixColumns()
 * operations, respectively, to cause each element in the state to affect
 * the output (referred to as diffusing).
 *
 * RotWord() uses: a0 = a1 = a2 = {00} and a3 = {01}, which is the
 * polynomial x3.
 *
 * The ShiftRows() method modifies the last 3 rows in the state (where
 * the state is 4 words with 4 bytes per word) by shifting bytes cyclically.
 * The 1st byte in the second row is moved to the end of the row. The 1st
 * and 2nd bytes in the third row are moved to the end of the row. The 1st,
 * 2nd, and 3rd bytes are moved in the fourth row.
 *
 * More details on how AES arithmetic works:
 *
 * In the polynomial representation of binary numbers, XOR performs addition
 * and subtraction and multiplication in GF(2^8) denoted as GF(a, b)
 * corresponds with the multiplication of polynomials modulo an irreducible
 * polynomial of degree 8. In other words, for AES, GF(a, b) will multiply
 * polynomial 'a' with polynomial 'b' and then do a modular reduction by
 * an AES-specific irreducible polynomial of degree 8.
 *
 * A polynomial is irreducible if its only divisors are one and itself. For
 * the AES algorithm, this irreducible polynomial is:
 *
 * m(x) = x^8 + x^4 + x^3 + x + 1,
 *
 * or {01}{1b} in hexadecimal notation, where each coefficient is a bit:
 * 100011011 = 283 = 0x11b.
 *
 * For example, GF(0x57, 0x83) = 0xc1 because
 *
 * 0x57 = 87  = 01010111 = x^6 + x^4 + x^2 + x + 1
 * 0x85 = 131 = 10000101 = x^7 + x + 1
 *
 * (x^6 + x^4 + x^2 + x + 1) * (x^7 + x + 1)
 * =  x^13 + x^11 + x^9 + x^8 + x^7 +
 *    x^7 + x^5 + x^3 + x^2 + x +
 *    x^6 + x^4 + x^2 + x + 1
 * =  x^13 + x^11 + x^9 + x^8 + x^6 + x^5 + x^4 + x^3 + 1 = y
 *    y modulo (x^8 + x^4 + x^3 + x + 1)
 * =  x^7 + x^6 + 1.
 *
 * The modular reduction by m(x) guarantees the result will be a binary
 * polynomial of less than degree 8, so that it can fit in a byte.
 *
 * The operation to multiply a binary polynomial b with x (the polynomial
 * x in binary representation is 00000010) is:
 *
 * b_7x^8 + b_6x^7 + b_5x^6 + b_4x^5 + b_3x^4 + b_2x^3 + b_1x^2 + b_0x^1
 *
 * To get GF(b, x) we must reduce that by m(x). If b_7 is 0 (that is the
 * most significant bit is 0 in b) then the result is already reduced. If
 * it is 1, then we can reduce it by subtracting m(x) via an XOR.
 *
 * It follows that multiplication by x (00000010 or 0x02) can be implemented
 * by performing a left shift followed by a conditional bitwise XOR with
 * 0x1b. This operation on bytes is denoted by xtime(). Multiplication by
 * higher powers of x can be implemented by repeated application of xtime().
 *
 * By adding intermediate results, multiplication by any constant can be
 * implemented. For instance:
 *
 * GF(0x57, 0x13) = 0xfe because:
 *
 * xtime(b) = (b & 128) ? (b << 1 ^ 0x11b) : (b << 1)
 *
 * Note: We XOR with 0x11b instead of 0x1b because in javascript our
 * datatype for b can be larger than 1 byte, so a left shift will not
 * automatically eliminate bits that overflow a byte ... by XOR'ing the
 * overflow bit with 1 (the extra one from 0x11b) we zero it out.
 *
 * GF(0x57, 0x02) = xtime(0x57) = 0xae
 * GF(0x57, 0x04) = xtime(0xae) = 0x47
 * GF(0x57, 0x08) = xtime(0x47) = 0x8e
 * GF(0x57, 0x10) = xtime(0x8e) = 0x07
 *
 * GF(0x57, 0x13) = GF(0x57, (0x01 ^ 0x02 ^ 0x10))
 *
 * And by the distributive property (since XOR is addition and GF() is
 * multiplication):
 *
 * = GF(0x57, 0x01) ^ GF(0x57, 0x02) ^ GF(0x57, 0x10)
 * = 0x57 ^ 0xae ^ 0x07
 * = 0xfe.
 */ function initialize() {
    init = true;
    /* Populate the Rcon table. These are the values given by
    [x^(i-1),{00},{00},{00}] where x^(i-1) are powers of x (and x = 0x02)
    in the field of GF(2^8), where i starts at 1.

    rcon[0] = [0x00, 0x00, 0x00, 0x00]
    rcon[1] = [0x01, 0x00, 0x00, 0x00] 2^(1-1) = 2^0 = 1
    rcon[2] = [0x02, 0x00, 0x00, 0x00] 2^(2-1) = 2^1 = 2
    ...
    rcon[9]  = [0x1B, 0x00, 0x00, 0x00] 2^(9-1)  = 2^8 = 0x1B
    rcon[10] = [0x36, 0x00, 0x00, 0x00] 2^(10-1) = 2^9 = 0x36

    We only store the first byte because it is the only one used.
  */ rcon = [
        0,
        1,
        2,
        4,
        8,
        16,
        32,
        64,
        128,
        27,
        54
    ];
    // compute xtime table which maps i onto GF(i, 0x02)
    var xtime = new Array(256);
    for(var i = 0; i < 128; ++i){
        xtime[i] = i << 1;
        xtime[i + 128] = i + 128 << 1 ^ 283;
    }
    // compute all other tables
    sbox = new Array(256);
    isbox = new Array(256);
    mix = new Array(4);
    imix = new Array(4);
    for(var i = 0; i < 4; ++i){
        mix[i] = new Array(256);
        imix[i] = new Array(256);
    }
    var e = 0, ei = 0, e2, e4, e8, sx, sx2, me, ime;
    for(var i = 0; i < 256; ++i){
        /* We need to generate the SubBytes() sbox and isbox tables so that
      we can perform byte substitutions. This requires us to traverse
      all of the elements in GF, find their multiplicative inverses,
      and apply to each the following affine transformation:

      bi' = bi ^ b(i + 4) mod 8 ^ b(i + 5) mod 8 ^ b(i + 6) mod 8 ^
            b(i + 7) mod 8 ^ ci
      for 0 <= i < 8, where bi is the ith bit of the byte, and ci is the
      ith bit of a byte c with the value {63} or {01100011}.

      It is possible to traverse every possible value in a Galois field
      using what is referred to as a 'generator'. There are many
      generators (128 out of 256): 3,5,6,9,11,82 to name a few. To fully
      traverse GF we iterate 255 times, multiplying by our generator
      each time.

      On each iteration we can determine the multiplicative inverse for
      the current element.

      Suppose there is an element in GF 'e'. For a given generator 'g',
      e = g^x. The multiplicative inverse of e is g^(255 - x). It turns
      out that if use the inverse of a generator as another generator
      it will produce all of the corresponding multiplicative inverses
      at the same time. For this reason, we choose 5 as our inverse
      generator because it only requires 2 multiplies and 1 add and its
      inverse, 82, requires relatively few operations as well.

      In order to apply the affine transformation, the multiplicative
      inverse 'ei' of 'e' can be repeatedly XOR'd (4 times) with a
      bit-cycling of 'ei'. To do this 'ei' is first stored in 's' and
      'x'. Then 's' is left shifted and the high bit of 's' is made the
      low bit. The resulting value is stored in 's'. Then 'x' is XOR'd
      with 's' and stored in 'x'. On each subsequent iteration the same
      operation is performed. When 4 iterations are complete, 'x' is
      XOR'd with 'c' (0x63) and the transformed value is stored in 'x'.
      For example:

      s = 01000001
      x = 01000001

      iteration 1: s = 10000010, x ^= s
      iteration 2: s = 00000101, x ^= s
      iteration 3: s = 00001010, x ^= s
      iteration 4: s = 00010100, x ^= s
      x ^= 0x63

      This can be done with a loop where s = (s << 1) | (s >> 7). However,
      it can also be done by using a single 16-bit (in this case 32-bit)
      number 'sx'. Since XOR is an associative operation, we can set 'sx'
      to 'ei' and then XOR it with 'sx' left-shifted 1,2,3, and 4 times.
      The most significant bits will flow into the high 8 bit positions
      and be correctly XOR'd with one another. All that remains will be
      to cycle the high 8 bits by XOR'ing them all with the lower 8 bits
      afterwards.

      At the same time we're populating sbox and isbox we can precompute
      the multiplication we'll need to do to do MixColumns() later.
    */ // apply affine transformation
        sx = ei ^ ei << 1 ^ ei << 2 ^ ei << 3 ^ ei << 4;
        sx = sx >> 8 ^ sx & 255 ^ 99;
        // update tables
        sbox[e] = sx;
        isbox[sx] = e;
        /* Mixing columns is done using matrix multiplication. The columns
      that are to be mixed are each a single word in the current state.
      The state has Nb columns (4 columns). Therefore each column is a
      4 byte word. So to mix the columns in a single column 'c' where
      its rows are r0, r1, r2, and r3, we use the following matrix
      multiplication:

      [2 3 1 1]*[r0,c]=[r'0,c]
      [1 2 3 1] [r1,c] [r'1,c]
      [1 1 2 3] [r2,c] [r'2,c]
      [3 1 1 2] [r3,c] [r'3,c]

      r0, r1, r2, and r3 are each 1 byte of one of the words in the
      state (a column). To do matrix multiplication for each mixed
      column c' we multiply the corresponding row from the left matrix
      with the corresponding column from the right matrix. In total, we
      get 4 equations:

      r0,c' = 2*r0,c + 3*r1,c + 1*r2,c + 1*r3,c
      r1,c' = 1*r0,c + 2*r1,c + 3*r2,c + 1*r3,c
      r2,c' = 1*r0,c + 1*r1,c + 2*r2,c + 3*r3,c
      r3,c' = 3*r0,c + 1*r1,c + 1*r2,c + 2*r3,c

      As usual, the multiplication is as previously defined and the
      addition is XOR. In order to optimize mixing columns we can store
      the multiplication results in tables. If you think of the whole
      column as a word (it might help to visualize by mentally rotating
      the equations above by counterclockwise 90 degrees) then you can
      see that it would be useful to map the multiplications performed on
      each byte (r0, r1, r2, r3) onto a word as well. For instance, we
      could map 2*r0,1*r0,1*r0,3*r0 onto a word by storing 2*r0 in the
      highest 8 bits and 3*r0 in the lowest 8 bits (with the other two
      respectively in the middle). This means that a table can be
      constructed that uses r0 as an index to the word. We can do the
      same with r1, r2, and r3, creating a total of 4 tables.

      To construct a full c', we can just look up each byte of c in
      their respective tables and XOR the results together.

      Also, to build each table we only have to calculate the word
      for 2,1,1,3 for every byte ... which we can do on each iteration
      of this loop since we will iterate over every byte. After we have
      calculated 2,1,1,3 we can get the results for the other tables
      by cycling the byte at the end to the beginning. For instance
      we can take the result of table 2,1,1,3 and produce table 3,2,1,1
      by moving the right most byte to the left most position just like
      how you can imagine the 3 moved out of 2,1,1,3 and to the front
      to produce 3,2,1,1.

      There is another optimization in that the same multiples of
      the current element we need in order to advance our generator
      to the next iteration can be reused in performing the 2,1,1,3
      calculation. We also calculate the inverse mix column tables,
      with e,9,d,b being the inverse of 2,1,1,3.

      When we're done, and we need to actually mix columns, the first
      byte of each state word should be put through mix[0] (2,1,1,3),
      the second through mix[1] (3,2,1,1) and so forth. Then they should
      be XOR'd together to produce the fully mixed column.
    */ // calculate mix and imix table values
        sx2 = xtime[sx];
        e2 = xtime[e];
        e4 = xtime[e2];
        e8 = xtime[e4];
        me = sx2 << 24 ^ sx << 16 ^ sx << 8 ^ (sx ^ sx2); // 3
        ime = (e2 ^ e4 ^ e8) << 24 ^ (e ^ e8) << 16 ^ (e ^ e4 ^ e8) << 8 ^ (e ^ e2 ^ e8); // B (11)
        // produce each of the mix tables by rotating the 2,1,1,3 value
        for(var n = 0; n < 4; ++n){
            mix[n][e] = me;
            imix[n][sx] = ime;
            // cycle the right most byte to the left most position
            // ie: 2,1,1,3 becomes 3,2,1,1
            me = me << 24 | me >>> 8;
            ime = ime << 24 | ime >>> 8;
        }
        // get next element and inverse
        if (e === 0) // 1 is the inverse of 1
        e = ei = 1;
        else {
            // e = 2e + 2*2*2*(10e)) = multiply e by 82 (chosen generator)
            // ei = ei + 2*2*ei = multiply ei by 5 (inverse generator)
            e = e2 ^ xtime[xtime[xtime[e2 ^ e8]]];
            ei ^= xtime[xtime[ei]];
        }
    }
}
/**
 * Generates a key schedule using the AES key expansion algorithm.
 *
 * The AES algorithm takes the Cipher Key, K, and performs a Key Expansion
 * routine to generate a key schedule. The Key Expansion generates a total
 * of Nb*(Nr + 1) words: the algorithm requires an initial set of Nb words,
 * and each of the Nr rounds requires Nb words of key data. The resulting
 * key schedule consists of a linear array of 4-byte words, denoted [wi ],
 * with i in the range 0 <= i < Nb(Nr + 1).
 *
 * KeyExpansion(byte key[4*Nk], word w[Nb*(Nr+1)], Nk)
 * AES-128 (Nb=4, Nk=4, Nr=10)
 * AES-192 (Nb=4, Nk=6, Nr=12)
 * AES-256 (Nb=4, Nk=8, Nr=14)
 * Note: Nr=Nk+6.
 *
 * Nb is the number of columns (32-bit words) comprising the State (or
 * number of bytes in a block). For AES, Nb=4.
 *
 * @param key the key to schedule (as an array of 32-bit words).
 * @param decrypt true to modify the key schedule to decrypt, false not to.
 *
 * @return the generated key schedule.
 */ function _expandKey(key, decrypt) {
    // copy the key's words to initialize the key schedule
    var w = key.slice(0);
    /* RotWord() will rotate a word, moving the first byte to the last
    byte's position (shifting the other bytes left).

    We will be getting the value of Rcon at i / Nk. 'i' will iterate
    from Nk to (Nb * Nr+1). Nk = 4 (4 byte key), Nb = 4 (4 words in
    a block), Nr = Nk + 6 (10). Therefore 'i' will iterate from
    4 to 44 (exclusive). Each time we iterate 4 times, i / Nk will
    increase by 1. We use a counter iNk to keep track of this.
   */ // go through the rounds expanding the key
    var temp, iNk = 1;
    var Nk = w.length;
    var Nr1 = Nk + 6 + 1;
    var end = Nb * Nr1;
    for(var i = Nk; i < end; ++i){
        temp = w[i - 1];
        if (i % Nk === 0) {
            // temp = SubWord(RotWord(temp)) ^ Rcon[i / Nk]
            temp = sbox[temp >>> 16 & 255] << 24 ^ sbox[temp >>> 8 & 255] << 16 ^ sbox[temp & 255] << 8 ^ sbox[temp >>> 24] ^ rcon[iNk] << 24;
            iNk++;
        } else if (Nk > 6 && i % Nk === 4) // temp = SubWord(temp)
        temp = sbox[temp >>> 24] << 24 ^ sbox[temp >>> 16 & 255] << 16 ^ sbox[temp >>> 8 & 255] << 8 ^ sbox[temp & 255];
        w[i] = w[i - Nk] ^ temp;
    }
    /* When we are updating a cipher block we always use the code path for
     encryption whether we are decrypting or not (to shorten code and
     simplify the generation of look up tables). However, because there
     are differences in the decryption algorithm, other than just swapping
     in different look up tables, we must transform our key schedule to
     account for these changes:

     1. The decryption algorithm gets its key rounds in reverse order.
     2. The decryption algorithm adds the round key before mixing columns
       instead of afterwards.

     We don't need to modify our key schedule to handle the first case,
     we can just traverse the key schedule in reverse order when decrypting.

     The second case requires a little work.

     The tables we built for performing rounds will take an input and then
     perform SubBytes() and MixColumns() or, for the decrypt version,
     InvSubBytes() and InvMixColumns(). But the decrypt algorithm requires
     us to AddRoundKey() before InvMixColumns(). This means we'll need to
     apply some transformations to the round key to inverse-mix its columns
     so they'll be correct for moving AddRoundKey() to after the state has
     had its columns inverse-mixed.

     To inverse-mix the columns of the state when we're decrypting we use a
     lookup table that will apply InvSubBytes() and InvMixColumns() at the
     same time. However, the round key's bytes are not inverse-substituted
     in the decryption algorithm. To get around this problem, we can first
     substitute the bytes in the round key so that when we apply the
     transformation via the InvSubBytes()+InvMixColumns() table, it will
     undo our substitution leaving us with the original value that we
     want -- and then inverse-mix that value.

     This change will correctly alter our key schedule so that we can XOR
     each round key with our already transformed decryption state. This
     allows us to use the same code path as the encryption algorithm.

     We make one more change to the decryption key. Since the decryption
     algorithm runs in reverse from the encryption algorithm, we reverse
     the order of the round keys to avoid having to iterate over the key
     schedule backwards when running the encryption algorithm later in
     decryption mode. In addition to reversing the order of the round keys,
     we also swap each round key's 2nd and 4th rows. See the comments
     section where rounds are performed for more details about why this is
     done. These changes are done inline with the other substitution
     described above.
  */ if (decrypt) {
        var tmp;
        var m0 = imix[0];
        var m1 = imix[1];
        var m2 = imix[2];
        var m3 = imix[3];
        var wnew = w.slice(0);
        end = w.length;
        for(var i = 0, wi = end - Nb; i < end; i += Nb, wi -= Nb){
            // do not sub the first or last round key (round keys are Nb
            // words) as no column mixing is performed before they are added,
            // but do change the key order
            if (i === 0 || i === end - Nb) {
                wnew[i] = w[wi];
                wnew[i + 1] = w[wi + 3];
                wnew[i + 2] = w[wi + 2];
                wnew[i + 3] = w[wi + 1];
            } else // substitute each round key byte because the inverse-mix
            // table will inverse-substitute it (effectively cancel the
            // substitution because round key bytes aren't sub'd in
            // decryption mode) and swap indexes 3 and 1
            for(var n = 0; n < Nb; ++n){
                tmp = w[wi + n];
                wnew[i + (3 & -n)] = m0[sbox[tmp >>> 24]] ^ m1[sbox[tmp >>> 16 & 255]] ^ m2[sbox[tmp >>> 8 & 255]] ^ m3[sbox[tmp & 255]];
            }
        }
        w = wnew;
    }
    return w;
}
/**
 * Updates a single block (16 bytes) using AES. The update will either
 * encrypt or decrypt the block.
 *
 * @param w the key schedule.
 * @param input the input block (an array of 32-bit words).
 * @param output the updated output block.
 * @param decrypt true to decrypt the block, false to encrypt it.
 */ function _updateBlock(w, input, output, decrypt) {
    /*
  Cipher(byte in[4*Nb], byte out[4*Nb], word w[Nb*(Nr+1)])
  begin
    byte state[4,Nb]
    state = in
    AddRoundKey(state, w[0, Nb-1])
    for round = 1 step 1 to Nr-1
      SubBytes(state)
      ShiftRows(state)
      MixColumns(state)
      AddRoundKey(state, w[round*Nb, (round+1)*Nb-1])
    end for
    SubBytes(state)
    ShiftRows(state)
    AddRoundKey(state, w[Nr*Nb, (Nr+1)*Nb-1])
    out = state
  end

  InvCipher(byte in[4*Nb], byte out[4*Nb], word w[Nb*(Nr+1)])
  begin
    byte state[4,Nb]
    state = in
    AddRoundKey(state, w[Nr*Nb, (Nr+1)*Nb-1])
    for round = Nr-1 step -1 downto 1
      InvShiftRows(state)
      InvSubBytes(state)
      AddRoundKey(state, w[round*Nb, (round+1)*Nb-1])
      InvMixColumns(state)
    end for
    InvShiftRows(state)
    InvSubBytes(state)
    AddRoundKey(state, w[0, Nb-1])
    out = state
  end
  */ // Encrypt: AddRoundKey(state, w[0, Nb-1])
    // Decrypt: AddRoundKey(state, w[Nr*Nb, (Nr+1)*Nb-1])
    var Nr = w.length / 4 - 1;
    var m0, m1, m2, m3, sub;
    if (decrypt) {
        m0 = imix[0];
        m1 = imix[1];
        m2 = imix[2];
        m3 = imix[3];
        sub = isbox;
    } else {
        m0 = mix[0];
        m1 = mix[1];
        m2 = mix[2];
        m3 = mix[3];
        sub = sbox;
    }
    var a, b, c, d, a2, b2, c2;
    a = input[0] ^ w[0];
    b = input[decrypt ? 3 : 1] ^ w[1];
    c = input[2] ^ w[2];
    d = input[decrypt ? 1 : 3] ^ w[3];
    var i = 3;
    /* In order to share code we follow the encryption algorithm when both
    encrypting and decrypting. To account for the changes required in the
    decryption algorithm, we use different lookup tables when decrypting
    and use a modified key schedule to account for the difference in the
    order of transformations applied when performing rounds. We also get
    key rounds in reverse order (relative to encryption). */ for(var round = 1; round < Nr; ++round){
        /* As described above, we'll be using table lookups to perform the
      column mixing. Each column is stored as a word in the state (the
      array 'input' has one column as a word at each index). In order to
      mix a column, we perform these transformations on each row in c,
      which is 1 byte in each word. The new column for c0 is c'0:

               m0      m1      m2      m3
      r0,c'0 = 2*r0,c0 + 3*r1,c0 + 1*r2,c0 + 1*r3,c0
      r1,c'0 = 1*r0,c0 + 2*r1,c0 + 3*r2,c0 + 1*r3,c0
      r2,c'0 = 1*r0,c0 + 1*r1,c0 + 2*r2,c0 + 3*r3,c0
      r3,c'0 = 3*r0,c0 + 1*r1,c0 + 1*r2,c0 + 2*r3,c0

      So using mix tables where c0 is a word with r0 being its upper
      8 bits and r3 being its lower 8 bits:

      m0[c0 >> 24] will yield this word: [2*r0,1*r0,1*r0,3*r0]
      ...
      m3[c0 & 255] will yield this word: [1*r3,1*r3,3*r3,2*r3]

      Therefore to mix the columns in each word in the state we
      do the following (& 255 omitted for brevity):
      c'0,r0 = m0[c0 >> 24] ^ m1[c1 >> 16] ^ m2[c2 >> 8] ^ m3[c3]
      c'0,r1 = m0[c0 >> 24] ^ m1[c1 >> 16] ^ m2[c2 >> 8] ^ m3[c3]
      c'0,r2 = m0[c0 >> 24] ^ m1[c1 >> 16] ^ m2[c2 >> 8] ^ m3[c3]
      c'0,r3 = m0[c0 >> 24] ^ m1[c1 >> 16] ^ m2[c2 >> 8] ^ m3[c3]

      However, before mixing, the algorithm requires us to perform
      ShiftRows(). The ShiftRows() transformation cyclically shifts the
      last 3 rows of the state over different offsets. The first row
      (r = 0) is not shifted.

      s'_r,c = s_r,(c + shift(r, Nb) mod Nb
      for 0 < r < 4 and 0 <= c < Nb and
      shift(1, 4) = 1
      shift(2, 4) = 2
      shift(3, 4) = 3.

      This causes the first byte in r = 1 to be moved to the end of
      the row, the first 2 bytes in r = 2 to be moved to the end of
      the row, the first 3 bytes in r = 3 to be moved to the end of
      the row:

      r1: [c0 c1 c2 c3] => [c1 c2 c3 c0]
      r2: [c0 c1 c2 c3]    [c2 c3 c0 c1]
      r3: [c0 c1 c2 c3]    [c3 c0 c1 c2]

      We can make these substitutions inline with our column mixing to
      generate an updated set of equations to produce each word in the
      state (note the columns have changed positions):

      c0 c1 c2 c3 => c0 c1 c2 c3
      c0 c1 c2 c3    c1 c2 c3 c0  (cycled 1 byte)
      c0 c1 c2 c3    c2 c3 c0 c1  (cycled 2 bytes)
      c0 c1 c2 c3    c3 c0 c1 c2  (cycled 3 bytes)

      Therefore:

      c'0 = 2*r0,c0 + 3*r1,c1 + 1*r2,c2 + 1*r3,c3
      c'0 = 1*r0,c0 + 2*r1,c1 + 3*r2,c2 + 1*r3,c3
      c'0 = 1*r0,c0 + 1*r1,c1 + 2*r2,c2 + 3*r3,c3
      c'0 = 3*r0,c0 + 1*r1,c1 + 1*r2,c2 + 2*r3,c3

      c'1 = 2*r0,c1 + 3*r1,c2 + 1*r2,c3 + 1*r3,c0
      c'1 = 1*r0,c1 + 2*r1,c2 + 3*r2,c3 + 1*r3,c0
      c'1 = 1*r0,c1 + 1*r1,c2 + 2*r2,c3 + 3*r3,c0
      c'1 = 3*r0,c1 + 1*r1,c2 + 1*r2,c3 + 2*r3,c0

      ... and so forth for c'2 and c'3. The important distinction is
      that the columns are cycling, with c0 being used with the m0
      map when calculating c0, but c1 being used with the m0 map when
      calculating c1 ... and so forth.

      When performing the inverse we transform the mirror image and
      skip the bottom row, instead of the top one, and move upwards:

      c3 c2 c1 c0 => c0 c3 c2 c1  (cycled 3 bytes) *same as encryption
      c3 c2 c1 c0    c1 c0 c3 c2  (cycled 2 bytes)
      c3 c2 c1 c0    c2 c1 c0 c3  (cycled 1 byte)  *same as encryption
      c3 c2 c1 c0    c3 c2 c1 c0

      If you compare the resulting matrices for ShiftRows()+MixColumns()
      and for InvShiftRows()+InvMixColumns() the 2nd and 4th columns are
      different (in encrypt mode vs. decrypt mode). So in order to use
      the same code to handle both encryption and decryption, we will
      need to do some mapping.

      If in encryption mode we let a=c0, b=c1, c=c2, d=c3, and r<N> be
      a row number in the state, then the resulting matrix in encryption
      mode for applying the above transformations would be:

      r1: a b c d
      r2: b c d a
      r3: c d a b
      r4: d a b c

      If we did the same in decryption mode we would get:

      r1: a d c b
      r2: b a d c
      r3: c b a d
      r4: d c b a

      If instead we swap d and b (set b=c3 and d=c1), then we get:

      r1: a b c d
      r2: d a b c
      r3: c d a b
      r4: b c d a

      Now the 1st and 3rd rows are the same as the encryption matrix. All
      we need to do then to make the mapping exactly the same is to swap
      the 2nd and 4th rows when in decryption mode. To do this without
      having to do it on each iteration, we swapped the 2nd and 4th rows
      in the decryption key schedule. We also have to do the swap above
      when we first pull in the input and when we set the final output. */ a2 = m0[a >>> 24] ^ m1[b >>> 16 & 255] ^ m2[c >>> 8 & 255] ^ m3[d & 255] ^ w[++i];
        b2 = m0[b >>> 24] ^ m1[c >>> 16 & 255] ^ m2[d >>> 8 & 255] ^ m3[a & 255] ^ w[++i];
        c2 = m0[c >>> 24] ^ m1[d >>> 16 & 255] ^ m2[a >>> 8 & 255] ^ m3[b & 255] ^ w[++i];
        d = m0[d >>> 24] ^ m1[a >>> 16 & 255] ^ m2[b >>> 8 & 255] ^ m3[c & 255] ^ w[++i];
        a = a2;
        b = b2;
        c = c2;
    }
    /*
    Encrypt:
    SubBytes(state)
    ShiftRows(state)
    AddRoundKey(state, w[Nr*Nb, (Nr+1)*Nb-1])

    Decrypt:
    InvShiftRows(state)
    InvSubBytes(state)
    AddRoundKey(state, w[0, Nb-1])
   */ // Note: rows are shifted inline
    output[0] = sub[a >>> 24] << 24 ^ sub[b >>> 16 & 255] << 16 ^ sub[c >>> 8 & 255] << 8 ^ sub[d & 255] ^ w[++i];
    output[decrypt ? 3 : 1] = sub[b >>> 24] << 24 ^ sub[c >>> 16 & 255] << 16 ^ sub[d >>> 8 & 255] << 8 ^ sub[a & 255] ^ w[++i];
    output[2] = sub[c >>> 24] << 24 ^ sub[d >>> 16 & 255] << 16 ^ sub[a >>> 8 & 255] << 8 ^ sub[b & 255] ^ w[++i];
    output[decrypt ? 1 : 3] = sub[d >>> 24] << 24 ^ sub[a >>> 16 & 255] << 16 ^ sub[b >>> 8 & 255] << 8 ^ sub[c & 255] ^ w[++i];
}
/**
 * Deprecated. Instead, use:
 *
 * forge.cipher.createCipher('AES-<mode>', key);
 * forge.cipher.createDecipher('AES-<mode>', key);
 *
 * Creates a deprecated AES cipher object. This object's mode will default to
 * CBC (cipher-block-chaining).
 *
 * The key and iv may be given as a string of bytes, an array of bytes, a
 * byte buffer, or an array of 32-bit words.
 *
 * @param options the options to use.
 *          key the symmetric key to use.
 *          output the buffer to write to.
 *          decrypt true for decryption, false for encryption.
 *          mode the cipher mode to use (default: 'CBC').
 *
 * @return the cipher.
 */ function _createCipher(options1) {
    options1 = options1 || {
    };
    var mode = (options1.mode || 'CBC').toUpperCase();
    var algorithm = 'AES-' + mode;
    var cipher;
    if (options1.decrypt) cipher = forge.cipher.createDecipher(algorithm, options1.key);
    else cipher = forge.cipher.createCipher(algorithm, options1.key);
    // backwards compatible start API
    var start = cipher.start;
    cipher.start = function(iv, options) {
        // backwards compatibility: support second arg as output buffer
        var output = null;
        if (options instanceof forge.util.ByteBuffer) {
            output = options;
            options = {
            };
        }
        options = options || {
        };
        options.output = output;
        options.iv = iv;
        start.call(cipher, options);
    };
    return cipher;
}

},{"./forge":"7AnVp","./cipher":"5QMkm","./cipherModes":"3KxX9","./util":"cHj6b"}],"5QMkm":[function(require,module,exports) {
/**
 * Cipher base API.
 *
 * @author Dave Longley
 *
 * Copyright (c) 2010-2014 Digital Bazaar, Inc.
 */ var forge = require('./forge');
require('./util');
module.exports = forge.cipher = forge.cipher || {
};
// registered algorithms
forge.cipher.algorithms = forge.cipher.algorithms || {
};
/**
 * Creates a cipher object that can be used to encrypt data using the given
 * algorithm and key. The algorithm may be provided as a string value for a
 * previously registered algorithm or it may be given as a cipher algorithm
 * API object.
 *
 * @param algorithm the algorithm to use, either a string or an algorithm API
 *          object.
 * @param key the key to use, as a binary-encoded string of bytes or a
 *          byte buffer.
 *
 * @return the cipher.
 */ forge.cipher.createCipher = function(algorithm, key) {
    var api = algorithm;
    if (typeof api === 'string') {
        api = forge.cipher.getAlgorithm(api);
        if (api) api = api();
    }
    if (!api) throw new Error('Unsupported algorithm: ' + algorithm);
    // assume block cipher
    return new forge.cipher.BlockCipher({
        algorithm: api,
        key: key,
        decrypt: false
    });
};
/**
 * Creates a decipher object that can be used to decrypt data using the given
 * algorithm and key. The algorithm may be provided as a string value for a
 * previously registered algorithm or it may be given as a cipher algorithm
 * API object.
 *
 * @param algorithm the algorithm to use, either a string or an algorithm API
 *          object.
 * @param key the key to use, as a binary-encoded string of bytes or a
 *          byte buffer.
 *
 * @return the cipher.
 */ forge.cipher.createDecipher = function(algorithm, key) {
    var api = algorithm;
    if (typeof api === 'string') {
        api = forge.cipher.getAlgorithm(api);
        if (api) api = api();
    }
    if (!api) throw new Error('Unsupported algorithm: ' + algorithm);
    // assume block cipher
    return new forge.cipher.BlockCipher({
        algorithm: api,
        key: key,
        decrypt: true
    });
};
/**
 * Registers an algorithm by name. If the name was already registered, the
 * algorithm API object will be overwritten.
 *
 * @param name the name of the algorithm.
 * @param algorithm the algorithm API object.
 */ forge.cipher.registerAlgorithm = function(name, algorithm) {
    name = name.toUpperCase();
    forge.cipher.algorithms[name] = algorithm;
};
/**
 * Gets a registered algorithm by name.
 *
 * @param name the name of the algorithm.
 *
 * @return the algorithm, if found, null if not.
 */ forge.cipher.getAlgorithm = function(name) {
    name = name.toUpperCase();
    if (name in forge.cipher.algorithms) return forge.cipher.algorithms[name];
    return null;
};
var BlockCipher = forge.cipher.BlockCipher = function(options) {
    this.algorithm = options.algorithm;
    this.mode = this.algorithm.mode;
    this.blockSize = this.mode.blockSize;
    this._finish = false;
    this._input = null;
    this.output = null;
    this._op = options.decrypt ? this.mode.decrypt : this.mode.encrypt;
    this._decrypt = options.decrypt;
    this.algorithm.initialize(options);
};
/**
 * Starts or restarts the encryption or decryption process, whichever
 * was previously configured.
 *
 * For non-GCM mode, the IV may be a binary-encoded string of bytes, an array
 * of bytes, a byte buffer, or an array of 32-bit integers. If the IV is in
 * bytes, then it must be Nb (16) bytes in length. If the IV is given in as
 * 32-bit integers, then it must be 4 integers long.
 *
 * Note: an IV is not required or used in ECB mode.
 *
 * For GCM-mode, the IV must be given as a binary-encoded string of bytes or
 * a byte buffer. The number of bytes should be 12 (96 bits) as recommended
 * by NIST SP-800-38D but another length may be given.
 *
 * @param options the options to use:
 *          iv the initialization vector to use as a binary-encoded string of
 *            bytes, null to reuse the last ciphered block from a previous
 *            update() (this "residue" method is for legacy support only).
 *          additionalData additional authentication data as a binary-encoded
 *            string of bytes, for 'GCM' mode, (default: none).
 *          tagLength desired length of authentication tag, in bits, for
 *            'GCM' mode (0-128, default: 128).
 *          tag the authentication tag to check if decrypting, as a
 *             binary-encoded string of bytes.
 *          output the output the buffer to write to, null to create one.
 */ BlockCipher.prototype.start = function(options) {
    options = options || {
    };
    var opts = {
    };
    for(var key in options)opts[key] = options[key];
    opts.decrypt = this._decrypt;
    this._finish = false;
    this._input = forge.util.createBuffer();
    this.output = options.output || forge.util.createBuffer();
    this.mode.start(opts);
};
/**
 * Updates the next block according to the cipher mode.
 *
 * @param input the buffer to read from.
 */ BlockCipher.prototype.update = function(input) {
    if (input) // input given, so empty it into the input buffer
    this._input.putBuffer(input);
    // do cipher operation until it needs more input and not finished
    while(!this._op.call(this.mode, this._input, this.output, this._finish) && !this._finish);
    // free consumed memory from input buffer
    this._input.compact();
};
/**
 * Finishes encrypting or decrypting.
 *
 * @param pad a padding function to use in CBC mode, null for default,
 *          signature(blockSize, buffer, decrypt).
 *
 * @return true if successful, false on error.
 */ BlockCipher.prototype.finish = function(pad) {
    // backwards-compatibility w/deprecated padding API
    // Note: will overwrite padding functions even after another start() call
    if (pad && (this.mode.name === 'ECB' || this.mode.name === 'CBC')) {
        this.mode.pad = function(input) {
            return pad(this.blockSize, input, false);
        };
        this.mode.unpad = function(output) {
            return pad(this.blockSize, output, true);
        };
    }
    // build options for padding and afterFinish functions
    var options = {
    };
    options.decrypt = this._decrypt;
    // get # of bytes that won't fill a block
    options.overflow = this._input.length() % this.blockSize;
    if (!this._decrypt && this.mode.pad) {
        if (!this.mode.pad(this._input, options)) return false;
    }
    // do final update
    this._finish = true;
    this.update();
    if (this._decrypt && this.mode.unpad) {
        if (!this.mode.unpad(this.output, options)) return false;
    }
    if (this.mode.afterFinish) {
        if (!this.mode.afterFinish(this.output, options)) return false;
    }
    return true;
};

},{"./forge":"7AnVp","./util":"cHj6b"}],"3KxX9":[function(require,module,exports) {
/**
 * Supported cipher modes.
 *
 * @author Dave Longley
 *
 * Copyright (c) 2010-2014 Digital Bazaar, Inc.
 */ var forge = require('./forge');
require('./util');
forge.cipher = forge.cipher || {
};
// supported cipher modes
var modes = module.exports = forge.cipher.modes = forge.cipher.modes || {
};
/** Electronic codebook (ECB) (Don't use this; it's not secure) **/ modes.ecb = function(options) {
    options = options || {
    };
    this.name = 'ECB';
    this.cipher = options.cipher;
    this.blockSize = options.blockSize || 16;
    this._ints = this.blockSize / 4;
    this._inBlock = new Array(this._ints);
    this._outBlock = new Array(this._ints);
};
modes.ecb.prototype.start = function(options) {
};
modes.ecb.prototype.encrypt = function(input, output, finish) {
    // not enough input to encrypt
    if (input.length() < this.blockSize && !(finish && input.length() > 0)) return true;
    // get next block
    for(var i = 0; i < this._ints; ++i)this._inBlock[i] = input.getInt32();
    // encrypt block
    this.cipher.encrypt(this._inBlock, this._outBlock);
    // write output
    for(var i = 0; i < this._ints; ++i)output.putInt32(this._outBlock[i]);
};
modes.ecb.prototype.decrypt = function(input, output, finish) {
    // not enough input to decrypt
    if (input.length() < this.blockSize && !(finish && input.length() > 0)) return true;
    // get next block
    for(var i = 0; i < this._ints; ++i)this._inBlock[i] = input.getInt32();
    // decrypt block
    this.cipher.decrypt(this._inBlock, this._outBlock);
    // write output
    for(var i = 0; i < this._ints; ++i)output.putInt32(this._outBlock[i]);
};
modes.ecb.prototype.pad = function(input, options) {
    // add PKCS#7 padding to block (each pad byte is the
    // value of the number of pad bytes)
    var padding = input.length() === this.blockSize ? this.blockSize : this.blockSize - input.length();
    input.fillWithByte(padding, padding);
    return true;
};
modes.ecb.prototype.unpad = function(output, options) {
    // check for error: input data not a multiple of blockSize
    if (options.overflow > 0) return false;
    // ensure padding byte count is valid
    var len = output.length();
    var count = output.at(len - 1);
    if (count > this.blockSize << 2) return false;
    // trim off padding bytes
    output.truncate(count);
    return true;
};
/** Cipher-block Chaining (CBC) **/ modes.cbc = function(options) {
    options = options || {
    };
    this.name = 'CBC';
    this.cipher = options.cipher;
    this.blockSize = options.blockSize || 16;
    this._ints = this.blockSize / 4;
    this._inBlock = new Array(this._ints);
    this._outBlock = new Array(this._ints);
};
modes.cbc.prototype.start = function(options) {
    // Note: legacy support for using IV residue (has security flaws)
    // if IV is null, reuse block from previous processing
    if (options.iv === null) {
        // must have a previous block
        if (!this._prev) throw new Error('Invalid IV parameter.');
        this._iv = this._prev.slice(0);
    } else if (!('iv' in options)) throw new Error('Invalid IV parameter.');
    else {
        // save IV as "previous" block
        this._iv = transformIV(options.iv, this.blockSize);
        this._prev = this._iv.slice(0);
    }
};
modes.cbc.prototype.encrypt = function(input, output, finish) {
    // not enough input to encrypt
    if (input.length() < this.blockSize && !(finish && input.length() > 0)) return true;
    // get next block
    // CBC XOR's IV (or previous block) with plaintext
    for(var i = 0; i < this._ints; ++i)this._inBlock[i] = this._prev[i] ^ input.getInt32();
    // encrypt block
    this.cipher.encrypt(this._inBlock, this._outBlock);
    // write output, save previous block
    for(var i = 0; i < this._ints; ++i)output.putInt32(this._outBlock[i]);
    this._prev = this._outBlock;
};
modes.cbc.prototype.decrypt = function(input, output, finish) {
    // not enough input to decrypt
    if (input.length() < this.blockSize && !(finish && input.length() > 0)) return true;
    // get next block
    for(var i = 0; i < this._ints; ++i)this._inBlock[i] = input.getInt32();
    // decrypt block
    this.cipher.decrypt(this._inBlock, this._outBlock);
    // write output, save previous ciphered block
    // CBC XOR's IV (or previous block) with ciphertext
    for(var i = 0; i < this._ints; ++i)output.putInt32(this._prev[i] ^ this._outBlock[i]);
    this._prev = this._inBlock.slice(0);
};
modes.cbc.prototype.pad = function(input, options) {
    // add PKCS#7 padding to block (each pad byte is the
    // value of the number of pad bytes)
    var padding = input.length() === this.blockSize ? this.blockSize : this.blockSize - input.length();
    input.fillWithByte(padding, padding);
    return true;
};
modes.cbc.prototype.unpad = function(output, options) {
    // check for error: input data not a multiple of blockSize
    if (options.overflow > 0) return false;
    // ensure padding byte count is valid
    var len = output.length();
    var count = output.at(len - 1);
    if (count > this.blockSize << 2) return false;
    // trim off padding bytes
    output.truncate(count);
    return true;
};
/** Cipher feedback (CFB) **/ modes.cfb = function(options) {
    options = options || {
    };
    this.name = 'CFB';
    this.cipher = options.cipher;
    this.blockSize = options.blockSize || 16;
    this._ints = this.blockSize / 4;
    this._inBlock = null;
    this._outBlock = new Array(this._ints);
    this._partialBlock = new Array(this._ints);
    this._partialOutput = forge.util.createBuffer();
    this._partialBytes = 0;
};
modes.cfb.prototype.start = function(options) {
    if (!('iv' in options)) throw new Error('Invalid IV parameter.');
    // use IV as first input
    this._iv = transformIV(options.iv, this.blockSize);
    this._inBlock = this._iv.slice(0);
    this._partialBytes = 0;
};
modes.cfb.prototype.encrypt = function(input, output, finish) {
    // not enough input to encrypt
    var inputLength = input.length();
    if (inputLength === 0) return true;
    // encrypt block
    this.cipher.encrypt(this._inBlock, this._outBlock);
    // handle full block
    if (this._partialBytes === 0 && inputLength >= this.blockSize) {
        // XOR input with output, write input as output
        for(var i = 0; i < this._ints; ++i){
            this._inBlock[i] = input.getInt32() ^ this._outBlock[i];
            output.putInt32(this._inBlock[i]);
        }
        return;
    }
    // handle partial block
    var partialBytes = (this.blockSize - inputLength) % this.blockSize;
    if (partialBytes > 0) partialBytes = this.blockSize - partialBytes;
    // XOR input with output, write input as partial output
    this._partialOutput.clear();
    for(var i = 0; i < this._ints; ++i){
        this._partialBlock[i] = input.getInt32() ^ this._outBlock[i];
        this._partialOutput.putInt32(this._partialBlock[i]);
    }
    if (partialBytes > 0) // block still incomplete, restore input buffer
    input.read -= this.blockSize;
    else // block complete, update input block
    for(var i = 0; i < this._ints; ++i)this._inBlock[i] = this._partialBlock[i];
    // skip any previous partial bytes
    if (this._partialBytes > 0) this._partialOutput.getBytes(this._partialBytes);
    if (partialBytes > 0 && !finish) {
        output.putBytes(this._partialOutput.getBytes(partialBytes - this._partialBytes));
        this._partialBytes = partialBytes;
        return true;
    }
    output.putBytes(this._partialOutput.getBytes(inputLength - this._partialBytes));
    this._partialBytes = 0;
};
modes.cfb.prototype.decrypt = function(input, output, finish) {
    // not enough input to decrypt
    var inputLength = input.length();
    if (inputLength === 0) return true;
    // encrypt block (CFB always uses encryption mode)
    this.cipher.encrypt(this._inBlock, this._outBlock);
    // handle full block
    if (this._partialBytes === 0 && inputLength >= this.blockSize) {
        // XOR input with output, write input as output
        for(var i = 0; i < this._ints; ++i){
            this._inBlock[i] = input.getInt32();
            output.putInt32(this._inBlock[i] ^ this._outBlock[i]);
        }
        return;
    }
    // handle partial block
    var partialBytes = (this.blockSize - inputLength) % this.blockSize;
    if (partialBytes > 0) partialBytes = this.blockSize - partialBytes;
    // XOR input with output, write input as partial output
    this._partialOutput.clear();
    for(var i = 0; i < this._ints; ++i){
        this._partialBlock[i] = input.getInt32();
        this._partialOutput.putInt32(this._partialBlock[i] ^ this._outBlock[i]);
    }
    if (partialBytes > 0) // block still incomplete, restore input buffer
    input.read -= this.blockSize;
    else // block complete, update input block
    for(var i = 0; i < this._ints; ++i)this._inBlock[i] = this._partialBlock[i];
    // skip any previous partial bytes
    if (this._partialBytes > 0) this._partialOutput.getBytes(this._partialBytes);
    if (partialBytes > 0 && !finish) {
        output.putBytes(this._partialOutput.getBytes(partialBytes - this._partialBytes));
        this._partialBytes = partialBytes;
        return true;
    }
    output.putBytes(this._partialOutput.getBytes(inputLength - this._partialBytes));
    this._partialBytes = 0;
};
/** Output feedback (OFB) **/ modes.ofb = function(options) {
    options = options || {
    };
    this.name = 'OFB';
    this.cipher = options.cipher;
    this.blockSize = options.blockSize || 16;
    this._ints = this.blockSize / 4;
    this._inBlock = null;
    this._outBlock = new Array(this._ints);
    this._partialOutput = forge.util.createBuffer();
    this._partialBytes = 0;
};
modes.ofb.prototype.start = function(options) {
    if (!('iv' in options)) throw new Error('Invalid IV parameter.');
    // use IV as first input
    this._iv = transformIV(options.iv, this.blockSize);
    this._inBlock = this._iv.slice(0);
    this._partialBytes = 0;
};
modes.ofb.prototype.encrypt = function(input, output, finish) {
    // not enough input to encrypt
    var inputLength = input.length();
    if (input.length() === 0) return true;
    // encrypt block (OFB always uses encryption mode)
    this.cipher.encrypt(this._inBlock, this._outBlock);
    // handle full block
    if (this._partialBytes === 0 && inputLength >= this.blockSize) {
        // XOR input with output and update next input
        for(var i = 0; i < this._ints; ++i){
            output.putInt32(input.getInt32() ^ this._outBlock[i]);
            this._inBlock[i] = this._outBlock[i];
        }
        return;
    }
    // handle partial block
    var partialBytes = (this.blockSize - inputLength) % this.blockSize;
    if (partialBytes > 0) partialBytes = this.blockSize - partialBytes;
    // XOR input with output
    this._partialOutput.clear();
    for(var i = 0; i < this._ints; ++i)this._partialOutput.putInt32(input.getInt32() ^ this._outBlock[i]);
    if (partialBytes > 0) // block still incomplete, restore input buffer
    input.read -= this.blockSize;
    else // block complete, update input block
    for(var i = 0; i < this._ints; ++i)this._inBlock[i] = this._outBlock[i];
    // skip any previous partial bytes
    if (this._partialBytes > 0) this._partialOutput.getBytes(this._partialBytes);
    if (partialBytes > 0 && !finish) {
        output.putBytes(this._partialOutput.getBytes(partialBytes - this._partialBytes));
        this._partialBytes = partialBytes;
        return true;
    }
    output.putBytes(this._partialOutput.getBytes(inputLength - this._partialBytes));
    this._partialBytes = 0;
};
modes.ofb.prototype.decrypt = modes.ofb.prototype.encrypt;
/** Counter (CTR) **/ modes.ctr = function(options) {
    options = options || {
    };
    this.name = 'CTR';
    this.cipher = options.cipher;
    this.blockSize = options.blockSize || 16;
    this._ints = this.blockSize / 4;
    this._inBlock = null;
    this._outBlock = new Array(this._ints);
    this._partialOutput = forge.util.createBuffer();
    this._partialBytes = 0;
};
modes.ctr.prototype.start = function(options) {
    if (!('iv' in options)) throw new Error('Invalid IV parameter.');
    // use IV as first input
    this._iv = transformIV(options.iv, this.blockSize);
    this._inBlock = this._iv.slice(0);
    this._partialBytes = 0;
};
modes.ctr.prototype.encrypt = function(input, output, finish) {
    // not enough input to encrypt
    var inputLength = input.length();
    if (inputLength === 0) return true;
    // encrypt block (CTR always uses encryption mode)
    this.cipher.encrypt(this._inBlock, this._outBlock);
    // handle full block
    if (this._partialBytes === 0 && inputLength >= this.blockSize) // XOR input with output
    for(var i = 0; i < this._ints; ++i)output.putInt32(input.getInt32() ^ this._outBlock[i]);
    else {
        // handle partial block
        var partialBytes = (this.blockSize - inputLength) % this.blockSize;
        if (partialBytes > 0) partialBytes = this.blockSize - partialBytes;
        // XOR input with output
        this._partialOutput.clear();
        for(var i = 0; i < this._ints; ++i)this._partialOutput.putInt32(input.getInt32() ^ this._outBlock[i]);
        if (partialBytes > 0) // block still incomplete, restore input buffer
        input.read -= this.blockSize;
        // skip any previous partial bytes
        if (this._partialBytes > 0) this._partialOutput.getBytes(this._partialBytes);
        if (partialBytes > 0 && !finish) {
            output.putBytes(this._partialOutput.getBytes(partialBytes - this._partialBytes));
            this._partialBytes = partialBytes;
            return true;
        }
        output.putBytes(this._partialOutput.getBytes(inputLength - this._partialBytes));
        this._partialBytes = 0;
    }
    // block complete, increment counter (input block)
    inc32(this._inBlock);
};
modes.ctr.prototype.decrypt = modes.ctr.prototype.encrypt;
/** Galois/Counter Mode (GCM) **/ modes.gcm = function(options) {
    options = options || {
    };
    this.name = 'GCM';
    this.cipher = options.cipher;
    this.blockSize = options.blockSize || 16;
    this._ints = this.blockSize / 4;
    this._inBlock = new Array(this._ints);
    this._outBlock = new Array(this._ints);
    this._partialOutput = forge.util.createBuffer();
    this._partialBytes = 0;
    // R is actually this value concatenated with 120 more zero bits, but
    // we only XOR against R so the other zeros have no effect -- we just
    // apply this value to the first integer in a block
    this._R = 3774873600;
};
modes.gcm.prototype.start = function(options) {
    if (!('iv' in options)) throw new Error('Invalid IV parameter.');
    // ensure IV is a byte buffer
    var iv = forge.util.createBuffer(options.iv);
    // no ciphered data processed yet
    this._cipherLength = 0;
    // default additional data is none
    var additionalData;
    if ('additionalData' in options) additionalData = forge.util.createBuffer(options.additionalData);
    else additionalData = forge.util.createBuffer();
    // default tag length is 128 bits
    if ('tagLength' in options) this._tagLength = options.tagLength;
    else this._tagLength = 128;
    // if tag is given, ensure tag matches tag length
    this._tag = null;
    if (options.decrypt) {
        // save tag to check later
        this._tag = forge.util.createBuffer(options.tag).getBytes();
        if (this._tag.length !== this._tagLength / 8) throw new Error('Authentication tag does not match tag length.');
    }
    // create tmp storage for hash calculation
    this._hashBlock = new Array(this._ints);
    // no tag generated yet
    this.tag = null;
    // generate hash subkey
    // (apply block cipher to "zero" block)
    this._hashSubkey = new Array(this._ints);
    this.cipher.encrypt([
        0,
        0,
        0,
        0
    ], this._hashSubkey);
    // generate table M
    // use 4-bit tables (32 component decomposition of a 16 byte value)
    // 8-bit tables take more space and are known to have security
    // vulnerabilities (in native implementations)
    this.componentBits = 4;
    this._m = this.generateHashTable(this._hashSubkey, this.componentBits);
    // Note: support IV length different from 96 bits? (only supporting
    // 96 bits is recommended by NIST SP-800-38D)
    // generate J_0
    var ivLength = iv.length();
    if (ivLength === 12) // 96-bit IV
    this._j0 = [
        iv.getInt32(),
        iv.getInt32(),
        iv.getInt32(),
        1
    ];
    else {
        // IV is NOT 96-bits
        this._j0 = [
            0,
            0,
            0,
            0
        ];
        while(iv.length() > 0)this._j0 = this.ghash(this._hashSubkey, this._j0, [
            iv.getInt32(),
            iv.getInt32(),
            iv.getInt32(),
            iv.getInt32()
        ]);
        this._j0 = this.ghash(this._hashSubkey, this._j0, [
            0,
            0
        ].concat(from64To32(ivLength * 8)));
    }
    // generate ICB (initial counter block)
    this._inBlock = this._j0.slice(0);
    inc32(this._inBlock);
    this._partialBytes = 0;
    // consume authentication data
    additionalData = forge.util.createBuffer(additionalData);
    // save additional data length as a BE 64-bit number
    this._aDataLength = from64To32(additionalData.length() * 8);
    // pad additional data to 128 bit (16 byte) block size
    var overflow = additionalData.length() % this.blockSize;
    if (overflow) additionalData.fillWithByte(0, this.blockSize - overflow);
    this._s = [
        0,
        0,
        0,
        0
    ];
    while(additionalData.length() > 0)this._s = this.ghash(this._hashSubkey, this._s, [
        additionalData.getInt32(),
        additionalData.getInt32(),
        additionalData.getInt32(),
        additionalData.getInt32()
    ]);
};
modes.gcm.prototype.encrypt = function(input, output, finish) {
    // not enough input to encrypt
    var inputLength = input.length();
    if (inputLength === 0) return true;
    // encrypt block
    this.cipher.encrypt(this._inBlock, this._outBlock);
    // handle full block
    if (this._partialBytes === 0 && inputLength >= this.blockSize) {
        // XOR input with output
        for(var i = 0; i < this._ints; ++i)output.putInt32(this._outBlock[i] ^= input.getInt32());
        this._cipherLength += this.blockSize;
    } else {
        // handle partial block
        var partialBytes = (this.blockSize - inputLength) % this.blockSize;
        if (partialBytes > 0) partialBytes = this.blockSize - partialBytes;
        // XOR input with output
        this._partialOutput.clear();
        for(var i = 0; i < this._ints; ++i)this._partialOutput.putInt32(input.getInt32() ^ this._outBlock[i]);
        if (partialBytes <= 0 || finish) {
            // handle overflow prior to hashing
            if (finish) {
                // get block overflow
                var overflow = inputLength % this.blockSize;
                this._cipherLength += overflow;
                // truncate for hash function
                this._partialOutput.truncate(this.blockSize - overflow);
            } else this._cipherLength += this.blockSize;
            // get output block for hashing
            for(var i = 0; i < this._ints; ++i)this._outBlock[i] = this._partialOutput.getInt32();
            this._partialOutput.read -= this.blockSize;
        }
        // skip any previous partial bytes
        if (this._partialBytes > 0) this._partialOutput.getBytes(this._partialBytes);
        if (partialBytes > 0 && !finish) {
            // block still incomplete, restore input buffer, get partial output,
            // and return early
            input.read -= this.blockSize;
            output.putBytes(this._partialOutput.getBytes(partialBytes - this._partialBytes));
            this._partialBytes = partialBytes;
            return true;
        }
        output.putBytes(this._partialOutput.getBytes(inputLength - this._partialBytes));
        this._partialBytes = 0;
    }
    // update hash block S
    this._s = this.ghash(this._hashSubkey, this._s, this._outBlock);
    // increment counter (input block)
    inc32(this._inBlock);
};
modes.gcm.prototype.decrypt = function(input, output, finish) {
    // not enough input to decrypt
    var inputLength = input.length();
    if (inputLength < this.blockSize && !(finish && inputLength > 0)) return true;
    // encrypt block (GCM always uses encryption mode)
    this.cipher.encrypt(this._inBlock, this._outBlock);
    // increment counter (input block)
    inc32(this._inBlock);
    // update hash block S
    this._hashBlock[0] = input.getInt32();
    this._hashBlock[1] = input.getInt32();
    this._hashBlock[2] = input.getInt32();
    this._hashBlock[3] = input.getInt32();
    this._s = this.ghash(this._hashSubkey, this._s, this._hashBlock);
    // XOR hash input with output
    for(var i = 0; i < this._ints; ++i)output.putInt32(this._outBlock[i] ^ this._hashBlock[i]);
    // increment cipher data length
    if (inputLength < this.blockSize) this._cipherLength += inputLength % this.blockSize;
    else this._cipherLength += this.blockSize;
};
modes.gcm.prototype.afterFinish = function(output, options) {
    var rval = true;
    // handle overflow
    if (options.decrypt && options.overflow) output.truncate(this.blockSize - options.overflow);
    // handle authentication tag
    this.tag = forge.util.createBuffer();
    // concatenate additional data length with cipher length
    var lengths = this._aDataLength.concat(from64To32(this._cipherLength * 8));
    // include lengths in hash
    this._s = this.ghash(this._hashSubkey, this._s, lengths);
    // do GCTR(J_0, S)
    var tag = [];
    this.cipher.encrypt(this._j0, tag);
    for(var i = 0; i < this._ints; ++i)this.tag.putInt32(this._s[i] ^ tag[i]);
    // trim tag to length
    this.tag.truncate(this.tag.length() % (this._tagLength / 8));
    // check authentication tag
    if (options.decrypt && this.tag.bytes() !== this._tag) rval = false;
    return rval;
};
/**
 * See NIST SP-800-38D 6.3 (Algorithm 1). This function performs Galois
 * field multiplication. The field, GF(2^128), is defined by the polynomial:
 *
 * x^128 + x^7 + x^2 + x + 1
 *
 * Which is represented in little-endian binary form as: 11100001 (0xe1). When
 * the value of a coefficient is 1, a bit is set. The value R, is the
 * concatenation of this value and 120 zero bits, yielding a 128-bit value
 * which matches the block size.
 *
 * This function will multiply two elements (vectors of bytes), X and Y, in
 * the field GF(2^128). The result is initialized to zero. For each bit of
 * X (out of 128), x_i, if x_i is set, then the result is multiplied (XOR'd)
 * by the current value of Y. For each bit, the value of Y will be raised by
 * a power of x (multiplied by the polynomial x). This can be achieved by
 * shifting Y once to the right. If the current value of Y, prior to being
 * multiplied by x, has 0 as its LSB, then it is a 127th degree polynomial.
 * Otherwise, we must divide by R after shifting to find the remainder.
 *
 * @param x the first block to multiply by the second.
 * @param y the second block to multiply by the first.
 *
 * @return the block result of the multiplication.
 */ modes.gcm.prototype.multiply = function(x, y) {
    var z_i = [
        0,
        0,
        0,
        0
    ];
    var v_i = y.slice(0);
    // calculate Z_128 (block has 128 bits)
    for(var i = 0; i < 128; ++i){
        // if x_i is 0, Z_{i+1} = Z_i (unchanged)
        // else Z_{i+1} = Z_i ^ V_i
        // get x_i by finding 32-bit int position, then left shift 1 by remainder
        var x_i = x[i / 32 | 0] & 1 << 31 - i % 32;
        if (x_i) {
            z_i[0] ^= v_i[0];
            z_i[1] ^= v_i[1];
            z_i[2] ^= v_i[2];
            z_i[3] ^= v_i[3];
        }
        // if LSB(V_i) is 1, V_i = V_i >> 1
        // else V_i = (V_i >> 1) ^ R
        this.pow(v_i, v_i);
    }
    return z_i;
};
modes.gcm.prototype.pow = function(x, out) {
    // if LSB(x) is 1, x = x >>> 1
    // else x = (x >>> 1) ^ R
    var lsb = x[3] & 1;
    // always do x >>> 1:
    // starting with the rightmost integer, shift each integer to the right
    // one bit, pulling in the bit from the integer to the left as its top
    // most bit (do this for the last 3 integers)
    for(var i = 3; i > 0; --i)out[i] = x[i] >>> 1 | (x[i - 1] & 1) << 31;
    // shift the first integer normally
    out[0] = x[0] >>> 1;
    // if lsb was not set, then polynomial had a degree of 127 and doesn't
    // need to divided; otherwise, XOR with R to find the remainder; we only
    // need to XOR the first integer since R technically ends w/120 zero bits
    if (lsb) out[0] ^= this._R;
};
modes.gcm.prototype.tableMultiply = function(x) {
    // assumes 4-bit tables are used
    var z = [
        0,
        0,
        0,
        0
    ];
    for(var i = 0; i < 32; ++i){
        var idx = i / 8 | 0;
        var x_i = x[idx] >>> (7 - i % 8) * 4 & 15;
        var ah = this._m[i][x_i];
        z[0] ^= ah[0];
        z[1] ^= ah[1];
        z[2] ^= ah[2];
        z[3] ^= ah[3];
    }
    return z;
};
/**
 * A continuing version of the GHASH algorithm that operates on a single
 * block. The hash block, last hash value (Ym) and the new block to hash
 * are given.
 *
 * @param h the hash block.
 * @param y the previous value for Ym, use [0, 0, 0, 0] for a new hash.
 * @param x the block to hash.
 *
 * @return the hashed value (Ym).
 */ modes.gcm.prototype.ghash = function(h, y, x) {
    y[0] ^= x[0];
    y[1] ^= x[1];
    y[2] ^= x[2];
    y[3] ^= x[3];
    return this.tableMultiply(y);
//return this.multiply(y, h);
};
/**
 * Precomputes a table for multiplying against the hash subkey. This
 * mechanism provides a substantial speed increase over multiplication
 * performed without a table. The table-based multiplication this table is
 * for solves X * H by multiplying each component of X by H and then
 * composing the results together using XOR.
 *
 * This function can be used to generate tables with different bit sizes
 * for the components, however, this implementation assumes there are
 * 32 components of X (which is a 16 byte vector), therefore each component
 * takes 4-bits (so the table is constructed with bits=4).
 *
 * @param h the hash subkey.
 * @param bits the bit size for a component.
 */ modes.gcm.prototype.generateHashTable = function(h, bits) {
    // TODO: There are further optimizations that would use only the
    // first table M_0 (or some variant) along with a remainder table;
    // this can be explored in the future
    var multiplier = 8 / bits;
    var perInt = 4 * multiplier;
    var size = 16 * multiplier;
    var m = new Array(size);
    for(var i = 0; i < size; ++i){
        var tmp = [
            0,
            0,
            0,
            0
        ];
        var idx = i / perInt | 0;
        var shft = (perInt - 1 - i % perInt) * bits;
        tmp[idx] = 1 << bits - 1 << shft;
        m[i] = this.generateSubHashTable(this.multiply(tmp, h), bits);
    }
    return m;
};
/**
 * Generates a table for multiplying against the hash subkey for one
 * particular component (out of all possible component values).
 *
 * @param mid the pre-multiplied value for the middle key of the table.
 * @param bits the bit size for a component.
 */ modes.gcm.prototype.generateSubHashTable = function(mid, bits) {
    // compute the table quickly by minimizing the number of
    // POW operations -- they only need to be performed for powers of 2,
    // all other entries can be composed from those powers using XOR
    var size = 1 << bits;
    var half = size >>> 1;
    var m = new Array(size);
    m[half] = mid.slice(0);
    var i = half >>> 1;
    while(i > 0){
        // raise m0[2 * i] and store in m0[i]
        this.pow(m[2 * i], m[i] = []);
        i >>= 1;
    }
    i = 2;
    while(i < half){
        for(var j = 1; j < i; ++j){
            var m_i = m[i];
            var m_j = m[j];
            m[i + j] = [
                m_i[0] ^ m_j[0],
                m_i[1] ^ m_j[1],
                m_i[2] ^ m_j[2],
                m_i[3] ^ m_j[3]
            ];
        }
        i *= 2;
    }
    m[0] = [
        0,
        0,
        0,
        0
    ];
    /* Note: We could avoid storing these by doing composition during multiply
  calculate top half using composition by speed is preferred. */ for(i = half + 1; i < size; ++i){
        var c = m[i ^ half];
        m[i] = [
            mid[0] ^ c[0],
            mid[1] ^ c[1],
            mid[2] ^ c[2],
            mid[3] ^ c[3]
        ];
    }
    return m;
};
/** Utility functions */ function transformIV(iv, blockSize) {
    if (typeof iv === 'string') // convert iv string into byte buffer
    iv = forge.util.createBuffer(iv);
    if (forge.util.isArray(iv) && iv.length > 4) {
        // convert iv byte array into byte buffer
        var tmp = iv;
        iv = forge.util.createBuffer();
        for(var i = 0; i < tmp.length; ++i)iv.putByte(tmp[i]);
    }
    if (iv.length() < blockSize) throw new Error('Invalid IV length; got ' + iv.length() + ' bytes and expected ' + blockSize + ' bytes.');
    if (!forge.util.isArray(iv)) {
        // convert iv byte buffer into 32-bit integer array
        var ints = [];
        var blocks = blockSize / 4;
        for(var i = 0; i < blocks; ++i)ints.push(iv.getInt32());
        iv = ints;
    }
    return iv;
}
function inc32(block) {
    // increment last 32 bits of block only
    block[block.length - 1] = block[block.length - 1] + 1 & 4294967295;
}
function from64To32(num) {
    // convert 64-bit number to two BE Int32s
    return [
        num / 4294967296 | 0,
        num & 4294967295
    ];
}

},{"./forge":"7AnVp","./util":"cHj6b"}],"6QyDg":[function(require,module,exports) {
/**
 * DES (Data Encryption Standard) implementation.
 *
 * This implementation supports DES as well as 3DES-EDE in ECB and CBC mode.
 * It is based on the BSD-licensed implementation by Paul Tero:
 *
 * Paul Tero, July 2001
 * http://www.tero.co.uk/des/
 *
 * Optimised for performance with large blocks by
 * Michael Hayworth, November 2001
 * http://www.netdealing.com
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * @author Stefan Siegl
 * @author Dave Longley
 *
 * Copyright (c) 2012 Stefan Siegl <stesie@brokenpipe.de>
 * Copyright (c) 2012-2014 Digital Bazaar, Inc.
 */ var forge = require('./forge');
require('./cipher');
require('./cipherModes');
require('./util');
/* DES API */ module.exports = forge.des = forge.des || {
};
/**
 * Deprecated. Instead, use:
 *
 * var cipher = forge.cipher.createCipher('DES-<mode>', key);
 * cipher.start({iv: iv});
 *
 * Creates an DES cipher object to encrypt data using the given symmetric key.
 * The output will be stored in the 'output' member of the returned cipher.
 *
 * The key and iv may be given as binary-encoded strings of bytes or
 * byte buffers.
 *
 * @param key the symmetric key to use (64 or 192 bits).
 * @param iv the initialization vector to use.
 * @param output the buffer to write to, null to create one.
 * @param mode the cipher mode to use (default: 'CBC' if IV is
 *          given, 'ECB' if null).
 *
 * @return the cipher.
 */ forge.des.startEncrypting = function(key, iv, output, mode) {
    var cipher = _createCipher({
        key: key,
        output: output,
        decrypt: false,
        mode: mode || (iv === null ? 'ECB' : 'CBC')
    });
    cipher.start(iv);
    return cipher;
};
/**
 * Deprecated. Instead, use:
 *
 * var cipher = forge.cipher.createCipher('DES-<mode>', key);
 *
 * Creates an DES cipher object to encrypt data using the given symmetric key.
 *
 * The key may be given as a binary-encoded string of bytes or a byte buffer.
 *
 * @param key the symmetric key to use (64 or 192 bits).
 * @param mode the cipher mode to use (default: 'CBC').
 *
 * @return the cipher.
 */ forge.des.createEncryptionCipher = function(key, mode) {
    return _createCipher({
        key: key,
        output: null,
        decrypt: false,
        mode: mode
    });
};
/**
 * Deprecated. Instead, use:
 *
 * var decipher = forge.cipher.createDecipher('DES-<mode>', key);
 * decipher.start({iv: iv});
 *
 * Creates an DES cipher object to decrypt data using the given symmetric key.
 * The output will be stored in the 'output' member of the returned cipher.
 *
 * The key and iv may be given as binary-encoded strings of bytes or
 * byte buffers.
 *
 * @param key the symmetric key to use (64 or 192 bits).
 * @param iv the initialization vector to use.
 * @param output the buffer to write to, null to create one.
 * @param mode the cipher mode to use (default: 'CBC' if IV is
 *          given, 'ECB' if null).
 *
 * @return the cipher.
 */ forge.des.startDecrypting = function(key, iv, output, mode) {
    var cipher = _createCipher({
        key: key,
        output: output,
        decrypt: true,
        mode: mode || (iv === null ? 'ECB' : 'CBC')
    });
    cipher.start(iv);
    return cipher;
};
/**
 * Deprecated. Instead, use:
 *
 * var decipher = forge.cipher.createDecipher('DES-<mode>', key);
 *
 * Creates an DES cipher object to decrypt data using the given symmetric key.
 *
 * The key may be given as a binary-encoded string of bytes or a byte buffer.
 *
 * @param key the symmetric key to use (64 or 192 bits).
 * @param mode the cipher mode to use (default: 'CBC').
 *
 * @return the cipher.
 */ forge.des.createDecryptionCipher = function(key, mode) {
    return _createCipher({
        key: key,
        output: null,
        decrypt: true,
        mode: mode
    });
};
/**
 * Creates a new DES cipher algorithm object.
 *
 * @param name the name of the algorithm.
 * @param mode the mode factory function.
 *
 * @return the DES algorithm object.
 */ forge.des.Algorithm = function(name, mode) {
    var self = this;
    self.name = name;
    self.mode = new mode({
        blockSize: 8,
        cipher: {
            encrypt: function(inBlock, outBlock) {
                return _updateBlock(self._keys, inBlock, outBlock, false);
            },
            decrypt: function(inBlock, outBlock) {
                return _updateBlock(self._keys, inBlock, outBlock, true);
            }
        }
    });
    self._init = false;
};
/**
 * Initializes this DES algorithm by expanding its key.
 *
 * @param options the options to use.
 *          key the key to use with this algorithm.
 *          decrypt true if the algorithm should be initialized for decryption,
 *            false for encryption.
 */ forge.des.Algorithm.prototype.initialize = function(options) {
    if (this._init) return;
    var key = forge.util.createBuffer(options.key);
    if (this.name.indexOf('3DES') === 0) {
        if (key.length() !== 24) throw new Error('Invalid Triple-DES key size: ' + key.length() * 8);
    }
    // do key expansion to 16 or 48 subkeys (single or triple DES)
    this._keys = _createKeys(key);
    this._init = true;
};
/** Register DES algorithms **/ registerAlgorithm('DES-ECB', forge.cipher.modes.ecb);
registerAlgorithm('DES-CBC', forge.cipher.modes.cbc);
registerAlgorithm('DES-CFB', forge.cipher.modes.cfb);
registerAlgorithm('DES-OFB', forge.cipher.modes.ofb);
registerAlgorithm('DES-CTR', forge.cipher.modes.ctr);
registerAlgorithm('3DES-ECB', forge.cipher.modes.ecb);
registerAlgorithm('3DES-CBC', forge.cipher.modes.cbc);
registerAlgorithm('3DES-CFB', forge.cipher.modes.cfb);
registerAlgorithm('3DES-OFB', forge.cipher.modes.ofb);
registerAlgorithm('3DES-CTR', forge.cipher.modes.ctr);
function registerAlgorithm(name, mode) {
    var factory = function() {
        return new forge.des.Algorithm(name, mode);
    };
    forge.cipher.registerAlgorithm(name, factory);
}
/** DES implementation **/ var spfunction1 = [
    16843776,
    0,
    65536,
    16843780,
    16842756,
    66564,
    4,
    65536,
    1024,
    16843776,
    16843780,
    1024,
    16778244,
    16842756,
    16777216,
    4,
    1028,
    16778240,
    16778240,
    66560,
    66560,
    16842752,
    16842752,
    16778244,
    65540,
    16777220,
    16777220,
    65540,
    0,
    1028,
    66564,
    16777216,
    65536,
    16843780,
    4,
    16842752,
    16843776,
    16777216,
    16777216,
    1024,
    16842756,
    65536,
    66560,
    16777220,
    1024,
    4,
    16778244,
    66564,
    16843780,
    65540,
    16842752,
    16778244,
    16777220,
    1028,
    66564,
    16843776,
    1028,
    16778240,
    16778240,
    0,
    65540,
    66560,
    0,
    16842756
];
var spfunction2 = [
    -2146402272,
    -2147450880,
    32768,
    1081376,
    1048576,
    32,
    -2146435040,
    -2147450848,
    -2147483616,
    -2146402272,
    -2146402304,
    -2147483648,
    -2147450880,
    1048576,
    32,
    -2146435040,
    1081344,
    1048608,
    -2147450848,
    0,
    -2147483648,
    32768,
    1081376,
    -2146435072,
    1048608,
    -2147483616,
    0,
    1081344,
    32800,
    -2146402304,
    -2146435072,
    32800,
    0,
    1081376,
    -2146435040,
    1048576,
    -2147450848,
    -2146435072,
    -2146402304,
    32768,
    -2146435072,
    -2147450880,
    32,
    -2146402272,
    1081376,
    32,
    32768,
    -2147483648,
    32800,
    -2146402304,
    1048576,
    -2147483616,
    1048608,
    -2147450848,
    -2147483616,
    1048608,
    1081344,
    0,
    -2147450880,
    32800,
    -2147483648,
    -2146435040,
    -2146402272,
    1081344
];
var spfunction3 = [
    520,
    134349312,
    0,
    134348808,
    134218240,
    0,
    131592,
    134218240,
    131080,
    134217736,
    134217736,
    131072,
    134349320,
    131080,
    134348800,
    520,
    134217728,
    8,
    134349312,
    512,
    131584,
    134348800,
    134348808,
    131592,
    134218248,
    131584,
    131072,
    134218248,
    8,
    134349320,
    512,
    134217728,
    134349312,
    134217728,
    131080,
    520,
    131072,
    134349312,
    134218240,
    0,
    512,
    131080,
    134349320,
    134218240,
    134217736,
    512,
    0,
    134348808,
    134218248,
    131072,
    134217728,
    134349320,
    8,
    131592,
    131584,
    134217736,
    134348800,
    134218248,
    520,
    134348800,
    131592,
    8,
    134348808,
    131584
];
var spfunction4 = [
    8396801,
    8321,
    8321,
    128,
    8396928,
    8388737,
    8388609,
    8193,
    0,
    8396800,
    8396800,
    8396929,
    129,
    0,
    8388736,
    8388609,
    1,
    8192,
    8388608,
    8396801,
    128,
    8388608,
    8193,
    8320,
    8388737,
    1,
    8320,
    8388736,
    8192,
    8396928,
    8396929,
    129,
    8388736,
    8388609,
    8396800,
    8396929,
    129,
    0,
    0,
    8396800,
    8320,
    8388736,
    8388737,
    1,
    8396801,
    8321,
    8321,
    128,
    8396929,
    129,
    1,
    8192,
    8388609,
    8193,
    8396928,
    8388737,
    8193,
    8320,
    8388608,
    8396801,
    128,
    8388608,
    8192,
    8396928
];
var spfunction5 = [
    256,
    34078976,
    34078720,
    1107296512,
    524288,
    256,
    1073741824,
    34078720,
    1074266368,
    524288,
    33554688,
    1074266368,
    1107296512,
    1107820544,
    524544,
    1073741824,
    33554432,
    1074266112,
    1074266112,
    0,
    1073742080,
    1107820800,
    1107820800,
    33554688,
    1107820544,
    1073742080,
    0,
    1107296256,
    34078976,
    33554432,
    1107296256,
    524544,
    524288,
    1107296512,
    256,
    33554432,
    1073741824,
    34078720,
    1107296512,
    1074266368,
    33554688,
    1073741824,
    1107820544,
    34078976,
    1074266368,
    256,
    33554432,
    1107820544,
    1107820800,
    524544,
    1107296256,
    1107820800,
    34078720,
    0,
    1074266112,
    1107296256,
    524544,
    33554688,
    1073742080,
    524288,
    0,
    1074266112,
    34078976,
    1073742080
];
var spfunction6 = [
    536870928,
    541065216,
    16384,
    541081616,
    541065216,
    16,
    541081616,
    4194304,
    536887296,
    4210704,
    4194304,
    536870928,
    4194320,
    536887296,
    536870912,
    16400,
    0,
    4194320,
    536887312,
    16384,
    4210688,
    536887312,
    16,
    541065232,
    541065232,
    0,
    4210704,
    541081600,
    16400,
    4210688,
    541081600,
    536870912,
    536887296,
    16,
    541065232,
    4210688,
    541081616,
    4194304,
    16400,
    536870928,
    4194304,
    536887296,
    536870912,
    16400,
    536870928,
    541081616,
    4210688,
    541065216,
    4210704,
    541081600,
    0,
    541065232,
    16,
    16384,
    541065216,
    4210704,
    16384,
    4194320,
    536887312,
    0,
    541081600,
    536870912,
    4194320,
    536887312
];
var spfunction7 = [
    2097152,
    69206018,
    67110914,
    0,
    2048,
    67110914,
    2099202,
    69208064,
    69208066,
    2097152,
    0,
    67108866,
    2,
    67108864,
    69206018,
    2050,
    67110912,
    2099202,
    2097154,
    67110912,
    67108866,
    69206016,
    69208064,
    2097154,
    69206016,
    2048,
    2050,
    69208066,
    2099200,
    2,
    67108864,
    2099200,
    67108864,
    2099200,
    2097152,
    67110914,
    67110914,
    69206018,
    69206018,
    2,
    2097154,
    67108864,
    67110912,
    2097152,
    69208064,
    2050,
    2099202,
    69208064,
    2050,
    67108866,
    69208066,
    69206016,
    2099200,
    0,
    2,
    69208066,
    0,
    2099202,
    69206016,
    2048,
    67108866,
    67110912,
    2048,
    2097154
];
var spfunction8 = [
    268439616,
    4096,
    262144,
    268701760,
    268435456,
    268439616,
    64,
    268435456,
    262208,
    268697600,
    268701760,
    266240,
    268701696,
    266304,
    4096,
    64,
    268697600,
    268435520,
    268439552,
    4160,
    266240,
    262208,
    268697664,
    268701696,
    4160,
    0,
    0,
    268697664,
    268435520,
    268439552,
    266304,
    262144,
    266304,
    262144,
    268701696,
    4096,
    64,
    268697664,
    4096,
    266304,
    268439552,
    64,
    268435520,
    268697600,
    268697664,
    268435456,
    262144,
    268439616,
    0,
    268701760,
    262208,
    268435520,
    268697600,
    268439552,
    268439616,
    0,
    268701760,
    266240,
    266240,
    4160,
    4160,
    262208,
    268435456,
    268701696
];
/**
 * Create necessary sub keys.
 *
 * @param key the 64-bit or 192-bit key.
 *
 * @return the expanded keys.
 */ function _createKeys(key) {
    var pc2bytes0 = [
        0,
        4,
        536870912,
        536870916,
        65536,
        65540,
        536936448,
        536936452,
        512,
        516,
        536871424,
        536871428,
        66048,
        66052,
        536936960,
        536936964
    ], pc2bytes1 = [
        0,
        1,
        1048576,
        1048577,
        67108864,
        67108865,
        68157440,
        68157441,
        256,
        257,
        1048832,
        1048833,
        67109120,
        67109121,
        68157696,
        68157697
    ], pc2bytes2 = [
        0,
        8,
        2048,
        2056,
        16777216,
        16777224,
        16779264,
        16779272,
        0,
        8,
        2048,
        2056,
        16777216,
        16777224,
        16779264,
        16779272
    ], pc2bytes3 = [
        0,
        2097152,
        134217728,
        136314880,
        8192,
        2105344,
        134225920,
        136323072,
        131072,
        2228224,
        134348800,
        136445952,
        139264,
        2236416,
        134356992,
        136454144
    ], pc2bytes4 = [
        0,
        262144,
        16,
        262160,
        0,
        262144,
        16,
        262160,
        4096,
        266240,
        4112,
        266256,
        4096,
        266240,
        4112,
        266256
    ], pc2bytes5 = [
        0,
        1024,
        32,
        1056,
        0,
        1024,
        32,
        1056,
        33554432,
        33555456,
        33554464,
        33555488,
        33554432,
        33555456,
        33554464,
        33555488
    ], pc2bytes6 = [
        0,
        268435456,
        524288,
        268959744,
        2,
        268435458,
        524290,
        268959746,
        0,
        268435456,
        524288,
        268959744,
        2,
        268435458,
        524290,
        268959746
    ], pc2bytes7 = [
        0,
        65536,
        2048,
        67584,
        536870912,
        536936448,
        536872960,
        536938496,
        131072,
        196608,
        133120,
        198656,
        537001984,
        537067520,
        537004032,
        537069568
    ], pc2bytes8 = [
        0,
        262144,
        0,
        262144,
        2,
        262146,
        2,
        262146,
        33554432,
        33816576,
        33554432,
        33816576,
        33554434,
        33816578,
        33554434,
        33816578
    ], pc2bytes9 = [
        0,
        268435456,
        8,
        268435464,
        0,
        268435456,
        8,
        268435464,
        1024,
        268436480,
        1032,
        268436488,
        1024,
        268436480,
        1032,
        268436488
    ], pc2bytes10 = [
        0,
        32,
        0,
        32,
        1048576,
        1048608,
        1048576,
        1048608,
        8192,
        8224,
        8192,
        8224,
        1056768,
        1056800,
        1056768,
        1056800
    ], pc2bytes11 = [
        0,
        16777216,
        512,
        16777728,
        2097152,
        18874368,
        2097664,
        18874880,
        67108864,
        83886080,
        67109376,
        83886592,
        69206016,
        85983232,
        69206528,
        85983744
    ], pc2bytes12 = [
        0,
        4096,
        134217728,
        134221824,
        524288,
        528384,
        134742016,
        134746112,
        16,
        4112,
        134217744,
        134221840,
        524304,
        528400,
        134742032,
        134746128
    ], pc2bytes13 = [
        0,
        4,
        256,
        260,
        0,
        4,
        256,
        260,
        1,
        5,
        257,
        261,
        1,
        5,
        257,
        261
    ];
    // how many iterations (1 for des, 3 for triple des)
    // changed by Paul 16/6/2007 to use Triple DES for 9+ byte keys
    var iterations = key.length() > 8 ? 3 : 1;
    // stores the return keys
    var keys = [];
    // now define the left shifts which need to be done
    var shifts = [
        0,
        0,
        1,
        1,
        1,
        1,
        1,
        1,
        0,
        1,
        1,
        1,
        1,
        1,
        1,
        0
    ];
    var n = 0, tmp;
    for(var j = 0; j < iterations; j++){
        var left = key.getInt32();
        var right = key.getInt32();
        tmp = (left >>> 4 ^ right) & 252645135;
        right ^= tmp;
        left ^= tmp << 4;
        tmp = (right >>> -16 ^ left) & 65535;
        left ^= tmp;
        right ^= tmp << -16;
        tmp = (left >>> 2 ^ right) & 858993459;
        right ^= tmp;
        left ^= tmp << 2;
        tmp = (right >>> -16 ^ left) & 65535;
        left ^= tmp;
        right ^= tmp << -16;
        tmp = (left >>> 1 ^ right) & 1431655765;
        right ^= tmp;
        left ^= tmp << 1;
        tmp = (right >>> 8 ^ left) & 16711935;
        left ^= tmp;
        right ^= tmp << 8;
        tmp = (left >>> 1 ^ right) & 1431655765;
        right ^= tmp;
        left ^= tmp << 1;
        // right needs to be shifted and OR'd with last four bits of left
        tmp = left << 8 | right >>> 20 & 240;
        // left needs to be put upside down
        left = right << 24 | right << 8 & 16711680 | right >>> 8 & 65280 | right >>> 24 & 240;
        right = tmp;
        // now go through and perform these shifts on the left and right keys
        for(var i = 0; i < shifts.length; ++i){
            //shift the keys either one or two bits to the left
            if (shifts[i]) {
                left = left << 2 | left >>> 26;
                right = right << 2 | right >>> 26;
            } else {
                left = left << 1 | left >>> 27;
                right = right << 1 | right >>> 27;
            }
            left &= -15;
            right &= -15;
            // now apply PC-2, in such a way that E is easier when encrypting or
            // decrypting this conversion will look like PC-2 except only the last 6
            // bits of each byte are used rather than 48 consecutive bits and the
            // order of lines will be according to how the S selection functions will
            // be applied: S2, S4, S6, S8, S1, S3, S5, S7
            var lefttmp = pc2bytes0[left >>> 28] | pc2bytes1[left >>> 24 & 15] | pc2bytes2[left >>> 20 & 15] | pc2bytes3[left >>> 16 & 15] | pc2bytes4[left >>> 12 & 15] | pc2bytes5[left >>> 8 & 15] | pc2bytes6[left >>> 4 & 15];
            var righttmp = pc2bytes7[right >>> 28] | pc2bytes8[right >>> 24 & 15] | pc2bytes9[right >>> 20 & 15] | pc2bytes10[right >>> 16 & 15] | pc2bytes11[right >>> 12 & 15] | pc2bytes12[right >>> 8 & 15] | pc2bytes13[right >>> 4 & 15];
            tmp = (righttmp >>> 16 ^ lefttmp) & 65535;
            keys[n++] = lefttmp ^ tmp;
            keys[n++] = righttmp ^ tmp << 16;
        }
    }
    return keys;
}
/**
 * Updates a single block (1 byte) using DES. The update will either
 * encrypt or decrypt the block.
 *
 * @param keys the expanded keys.
 * @param input the input block (an array of 32-bit words).
 * @param output the updated output block.
 * @param decrypt true to decrypt the block, false to encrypt it.
 */ function _updateBlock(keys, input, output, decrypt) {
    // set up loops for single or triple DES
    var iterations = keys.length === 32 ? 3 : 9;
    var looping;
    if (iterations === 3) looping = decrypt ? [
        30,
        -2,
        -2
    ] : [
        0,
        32,
        2
    ];
    else looping = decrypt ? [
        94,
        62,
        -2,
        32,
        64,
        2,
        30,
        -2,
        -2
    ] : [
        0,
        32,
        2,
        62,
        30,
        -2,
        64,
        96,
        2
    ];
    var tmp;
    var left = input[0];
    var right = input[1];
    // first each 64 bit chunk of the message must be permuted according to IP
    tmp = (left >>> 4 ^ right) & 252645135;
    right ^= tmp;
    left ^= tmp << 4;
    tmp = (left >>> 16 ^ right) & 65535;
    right ^= tmp;
    left ^= tmp << 16;
    tmp = (right >>> 2 ^ left) & 858993459;
    left ^= tmp;
    right ^= tmp << 2;
    tmp = (right >>> 8 ^ left) & 16711935;
    left ^= tmp;
    right ^= tmp << 8;
    tmp = (left >>> 1 ^ right) & 1431655765;
    right ^= tmp;
    left ^= tmp << 1;
    // rotate left 1 bit
    left = left << 1 | left >>> 31;
    right = right << 1 | right >>> 31;
    for(var j = 0; j < iterations; j += 3){
        var endloop = looping[j + 1];
        var loopinc = looping[j + 2];
        // now go through and perform the encryption or decryption
        for(var i = looping[j]; i != endloop; i += loopinc){
            var right1 = right ^ keys[i];
            var right2 = (right >>> 4 | right << 28) ^ keys[i + 1];
            // passing these bytes through the S selection functions
            tmp = left;
            left = right;
            right = tmp ^ (spfunction2[right1 >>> 24 & 63] | spfunction4[right1 >>> 16 & 63] | spfunction6[right1 >>> 8 & 63] | spfunction8[right1 & 63] | spfunction1[right2 >>> 24 & 63] | spfunction3[right2 >>> 16 & 63] | spfunction5[right2 >>> 8 & 63] | spfunction7[right2 & 63]);
        }
        // unreverse left and right
        tmp = left;
        left = right;
        right = tmp;
    }
    // rotate right 1 bit
    left = left >>> 1 | left << 31;
    right = right >>> 1 | right << 31;
    // now perform IP-1, which is IP in the opposite direction
    tmp = (left >>> 1 ^ right) & 1431655765;
    right ^= tmp;
    left ^= tmp << 1;
    tmp = (right >>> 8 ^ left) & 16711935;
    left ^= tmp;
    right ^= tmp << 8;
    tmp = (right >>> 2 ^ left) & 858993459;
    left ^= tmp;
    right ^= tmp << 2;
    tmp = (left >>> 16 ^ right) & 65535;
    right ^= tmp;
    left ^= tmp << 16;
    tmp = (left >>> 4 ^ right) & 252645135;
    right ^= tmp;
    left ^= tmp << 4;
    output[0] = left;
    output[1] = right;
}
/**
 * Deprecated. Instead, use:
 *
 * forge.cipher.createCipher('DES-<mode>', key);
 * forge.cipher.createDecipher('DES-<mode>', key);
 *
 * Creates a deprecated DES cipher object. This object's mode will default to
 * CBC (cipher-block-chaining).
 *
 * The key may be given as a binary-encoded string of bytes or a byte buffer.
 *
 * @param options the options to use.
 *          key the symmetric key to use (64 or 192 bits).
 *          output the buffer to write to.
 *          decrypt true for decryption, false for encryption.
 *          mode the cipher mode to use (default: 'CBC').
 *
 * @return the cipher.
 */ function _createCipher(options1) {
    options1 = options1 || {
    };
    var mode = (options1.mode || 'CBC').toUpperCase();
    var algorithm = 'DES-' + mode;
    var cipher;
    if (options1.decrypt) cipher = forge.cipher.createDecipher(algorithm, options1.key);
    else cipher = forge.cipher.createCipher(algorithm, options1.key);
    // backwards compatible start API
    var start = cipher.start;
    cipher.start = function(iv, options) {
        // backwards compatibility: support second arg as output buffer
        var output = null;
        if (options instanceof forge.util.ByteBuffer) {
            output = options;
            options = {
            };
        }
        options = options || {
        };
        options.output = output;
        options.iv = iv;
        start.call(cipher, options);
    };
    return cipher;
}

},{"./forge":"7AnVp","./cipher":"5QMkm","./cipherModes":"3KxX9","./util":"cHj6b"}],"9dnCj":[function(require,module,exports) {
/**
 * Node.js module for Forge message digests.
 *
 * @author Dave Longley
 *
 * Copyright 2011-2017 Digital Bazaar, Inc.
 */ var forge = require('./forge');
module.exports = forge.md = forge.md || {
};
forge.md.algorithms = forge.md.algorithms || {
};

},{"./forge":"7AnVp"}],"j4d8T":[function(require,module,exports) {
var Buffer = require("buffer").Buffer;
/**
 * Password-Based Key-Derivation Function #2 implementation.
 *
 * See RFC 2898 for details.
 *
 * @author Dave Longley
 *
 * Copyright (c) 2010-2013 Digital Bazaar, Inc.
 */ var forge = require('./forge');
require('./hmac');
require('./md');
require('./util');
var pkcs5 = forge.pkcs5 = forge.pkcs5 || {
};
var crypto;
if (forge.util.isNodejs && !forge.options.usePureJavaScript) crypto = require('crypto');
/**
 * Derives a key from a password.
 *
 * @param p the password as a binary-encoded string of bytes.
 * @param s the salt as a binary-encoded string of bytes.
 * @param c the iteration count, a positive integer.
 * @param dkLen the intended length, in bytes, of the derived key,
 *          (max: 2^32 - 1) * hash length of the PRF.
 * @param [md] the message digest (or algorithm identifier as a string) to use
 *          in the PRF, defaults to SHA-1.
 * @param [callback(err, key)] presence triggers asynchronous version, called
 *          once the operation completes.
 *
 * @return the derived key, as a binary-encoded string of bytes, for the
 *           synchronous version (if no callback is specified).
 */ module.exports = forge.pbkdf2 = pkcs5.pbkdf2 = function(p, s, c, dkLen, md, callback) {
    if (typeof md === 'function') {
        callback = md;
        md = null;
    }
    // use native implementation if possible and not disabled, note that
    // some node versions only support SHA-1, others allow digest to be changed
    if (forge.util.isNodejs && !forge.options.usePureJavaScript && crypto.pbkdf2 && (md === null || typeof md !== 'object') && (crypto.pbkdf2Sync.length > 4 || !md || md === 'sha1')) {
        if (typeof md !== 'string') // default prf to SHA-1
        md = 'sha1';
        p = Buffer.from(p, 'binary');
        s = Buffer.from(s, 'binary');
        if (!callback) {
            if (crypto.pbkdf2Sync.length === 4) return crypto.pbkdf2Sync(p, s, c, dkLen).toString('binary');
            return crypto.pbkdf2Sync(p, s, c, dkLen, md).toString('binary');
        }
        if (crypto.pbkdf2Sync.length === 4) return crypto.pbkdf2(p, s, c, dkLen, function(err, key) {
            if (err) return callback(err);
            callback(null, key.toString('binary'));
        });
        return crypto.pbkdf2(p, s, c, dkLen, md, function(err, key) {
            if (err) return callback(err);
            callback(null, key.toString('binary'));
        });
    }
    if (typeof md === 'undefined' || md === null) // default prf to SHA-1
    md = 'sha1';
    if (typeof md === 'string') {
        if (!(md in forge.md.algorithms)) throw new Error('Unknown hash algorithm: ' + md);
        md = forge.md[md].create();
    }
    var hLen = md.digestLength;
    /* 1. If dkLen > (2^32 - 1) * hLen, output "derived key too long" and
    stop. */ if (dkLen > 4294967295 * hLen) {
        var err1 = new Error('Derived key is too long.');
        if (callback) return callback(err1);
        throw err1;
    }
    /* 2. Let len be the number of hLen-octet blocks in the derived key,
    rounding up, and let r be the number of octets in the last
    block:

    len = CEIL(dkLen / hLen),
    r = dkLen - (len - 1) * hLen. */ var len = Math.ceil(dkLen / hLen);
    var r = dkLen - (len - 1) * hLen;
    /* 3. For each block of the derived key apply the function F defined
    below to the password P, the salt S, the iteration count c, and
    the block index to compute the block:

    T_1 = F(P, S, c, 1),
    T_2 = F(P, S, c, 2),
    ...
    T_len = F(P, S, c, len),

    where the function F is defined as the exclusive-or sum of the
    first c iterates of the underlying pseudorandom function PRF
    applied to the password P and the concatenation of the salt S
    and the block index i:

    F(P, S, c, i) = u_1 XOR u_2 XOR ... XOR u_c

    where

    u_1 = PRF(P, S || INT(i)),
    u_2 = PRF(P, u_1),
    ...
    u_c = PRF(P, u_{c-1}).

    Here, INT(i) is a four-octet encoding of the integer i, most
    significant octet first. */ var prf = forge.hmac.create();
    prf.start(md, p);
    var dk = '';
    var xor, u_c, u_c1;
    // sync version
    if (!callback) {
        for(var i = 1; i <= len; ++i){
            // PRF(P, S || INT(i)) (first iteration)
            prf.start(null, null);
            prf.update(s);
            prf.update(forge.util.int32ToBytes(i));
            xor = u_c1 = prf.digest().getBytes();
            // PRF(P, u_{c-1}) (other iterations)
            for(var j = 2; j <= c; ++j){
                prf.start(null, null);
                prf.update(u_c1);
                u_c = prf.digest().getBytes();
                // F(p, s, c, i)
                xor = forge.util.xorBytes(xor, u_c, hLen);
                u_c1 = u_c;
            }
            /* 4. Concatenate the blocks and extract the first dkLen octets to
        produce a derived key DK:

        DK = T_1 || T_2 ||  ...  || T_len<0..r-1> */ dk += i < len ? xor : xor.substr(0, r);
        }
        /* 5. Output the derived key DK. */ return dk;
    }
    // async version
    var i = 1, j;
    function outer() {
        if (i > len) // done
        return callback(null, dk);
        // PRF(P, S || INT(i)) (first iteration)
        prf.start(null, null);
        prf.update(s);
        prf.update(forge.util.int32ToBytes(i));
        xor = u_c1 = prf.digest().getBytes();
        // PRF(P, u_{c-1}) (other iterations)
        j = 2;
        inner();
    }
    function inner() {
        if (j <= c) {
            prf.start(null, null);
            prf.update(u_c1);
            u_c = prf.digest().getBytes();
            // F(p, s, c, i)
            xor = forge.util.xorBytes(xor, u_c, hLen);
            u_c1 = u_c;
            ++j;
            return forge.util.setImmediate(inner);
        }
        /* 4. Concatenate the blocks and extract the first dkLen octets to
      produce a derived key DK:

      DK = T_1 || T_2 ||  ...  || T_len<0..r-1> */ dk += i < len ? xor : xor.substr(0, r);
        ++i;
        outer();
    }
    outer();
};

},{"buffer":"joWnX","./forge":"7AnVp","./hmac":"1PySD","./md":"9dnCj","./util":"cHj6b","crypto":"joWnX"}],"1PySD":[function(require,module,exports) {
/**
 * Hash-based Message Authentication Code implementation. Requires a message
 * digest object that can be obtained, for example, from forge.md.sha1 or
 * forge.md.md5.
 *
 * @author Dave Longley
 *
 * Copyright (c) 2010-2012 Digital Bazaar, Inc. All rights reserved.
 */ var forge = require('./forge');
require('./md');
require('./util');
/* HMAC API */ var hmac = module.exports = forge.hmac = forge.hmac || {
};
/**
 * Creates an HMAC object that uses the given message digest object.
 *
 * @return an HMAC object.
 */ hmac.create = function() {
    // the hmac key to use
    var _key = null;
    // the message digest to use
    var _md = null;
    // the inner padding
    var _ipadding = null;
    // the outer padding
    var _opadding = null;
    // hmac context
    var ctx = {
    };
    /**
   * Starts or restarts the HMAC with the given key and message digest.
   *
   * @param md the message digest to use, null to reuse the previous one,
   *           a string to use builtin 'sha1', 'md5', 'sha256'.
   * @param key the key to use as a string, array of bytes, byte buffer,
   *           or null to reuse the previous key.
   */ ctx.start = function(md, key) {
        if (md !== null) {
            if (typeof md === 'string') {
                // create builtin message digest
                md = md.toLowerCase();
                if (md in forge.md.algorithms) _md = forge.md.algorithms[md].create();
                else throw new Error('Unknown hash algorithm "' + md + '"');
            } else // store message digest
            _md = md;
        }
        if (key === null) // reuse previous key
        key = _key;
        else {
            if (typeof key === 'string') // convert string into byte buffer
            key = forge.util.createBuffer(key);
            else if (forge.util.isArray(key)) {
                // convert byte array into byte buffer
                var tmp = key;
                key = forge.util.createBuffer();
                for(var i = 0; i < tmp.length; ++i)key.putByte(tmp[i]);
            }
            // if key is longer than blocksize, hash it
            var keylen = key.length();
            if (keylen > _md.blockLength) {
                _md.start();
                _md.update(key.bytes());
                key = _md.digest();
            }
            // mix key into inner and outer padding
            // ipadding = [0x36 * blocksize] ^ key
            // opadding = [0x5C * blocksize] ^ key
            _ipadding = forge.util.createBuffer();
            _opadding = forge.util.createBuffer();
            keylen = key.length();
            for(var i = 0; i < keylen; ++i){
                var tmp = key.at(i);
                _ipadding.putByte(54 ^ tmp);
                _opadding.putByte(92 ^ tmp);
            }
            // if key is shorter than blocksize, add additional padding
            if (keylen < _md.blockLength) {
                var tmp = _md.blockLength - keylen;
                for(var i = 0; i < tmp; ++i){
                    _ipadding.putByte(54);
                    _opadding.putByte(92);
                }
            }
            _key = key;
            _ipadding = _ipadding.bytes();
            _opadding = _opadding.bytes();
        }
        // digest is done like so: hash(opadding | hash(ipadding | message))
        // prepare to do inner hash
        // hash(ipadding | message)
        _md.start();
        _md.update(_ipadding);
    };
    /**
   * Updates the HMAC with the given message bytes.
   *
   * @param bytes the bytes to update with.
   */ ctx.update = function(bytes) {
        _md.update(bytes);
    };
    /**
   * Produces the Message Authentication Code (MAC).
   *
   * @return a byte buffer containing the digest value.
   */ ctx.getMac = function() {
        // digest is done like so: hash(opadding | hash(ipadding | message))
        // here we do the outer hashing
        var inner = _md.digest().bytes();
        _md.start();
        _md.update(_opadding);
        _md.update(inner);
        return _md.digest();
    };
    // alias for getMac
    ctx.digest = ctx.getMac;
    return ctx;
};

},{"./forge":"7AnVp","./md":"9dnCj","./util":"cHj6b"}],"axmYn":[function(require,module,exports) {
/**
 * Javascript implementation of basic PEM (Privacy Enhanced Mail) algorithms.
 *
 * See: RFC 1421.
 *
 * @author Dave Longley
 *
 * Copyright (c) 2013-2014 Digital Bazaar, Inc.
 *
 * A Forge PEM object has the following fields:
 *
 * type: identifies the type of message (eg: "RSA PRIVATE KEY").
 *
 * procType: identifies the type of processing performed on the message,
 *   it has two subfields: version and type, eg: 4,ENCRYPTED.
 *
 * contentDomain: identifies the type of content in the message, typically
 *   only uses the value: "RFC822".
 *
 * dekInfo: identifies the message encryption algorithm and mode and includes
 *   any parameters for the algorithm, it has two subfields: algorithm and
 *   parameters, eg: DES-CBC,F8143EDE5960C597.
 *
 * headers: contains all other PEM encapsulated headers -- where order is
 *   significant (for pairing data like recipient ID + key info).
 *
 * body: the binary-encoded body.
 */ var forge = require('./forge');
require('./util');
// shortcut for pem API
var pem = module.exports = forge.pem = forge.pem || {
};
/**
 * Encodes (serializes) the given PEM object.
 *
 * @param msg the PEM message object to encode.
 * @param options the options to use:
 *          maxline the maximum characters per line for the body, (default: 64).
 *
 * @return the PEM-formatted string.
 */ pem.encode = function(msg, options) {
    options = options || {
    };
    var rval = '-----BEGIN ' + msg.type + '-----\r\n';
    // encode special headers
    var header;
    if (msg.procType) {
        header = {
            name: 'Proc-Type',
            values: [
                String(msg.procType.version),
                msg.procType.type
            ]
        };
        rval += foldHeader(header);
    }
    if (msg.contentDomain) {
        header = {
            name: 'Content-Domain',
            values: [
                msg.contentDomain
            ]
        };
        rval += foldHeader(header);
    }
    if (msg.dekInfo) {
        header = {
            name: 'DEK-Info',
            values: [
                msg.dekInfo.algorithm
            ]
        };
        if (msg.dekInfo.parameters) header.values.push(msg.dekInfo.parameters);
        rval += foldHeader(header);
    }
    if (msg.headers) // encode all other headers
    for(var i = 0; i < msg.headers.length; ++i)rval += foldHeader(msg.headers[i]);
    // terminate header
    if (msg.procType) rval += '\r\n';
    // add body
    rval += forge.util.encode64(msg.body, options.maxline || 64) + '\r\n';
    rval += '-----END ' + msg.type + '-----\r\n';
    return rval;
};
/**
 * Decodes (deserializes) all PEM messages found in the given string.
 *
 * @param str the PEM-formatted string to decode.
 *
 * @return the PEM message objects in an array.
 */ pem.decode = function(str) {
    var rval = [];
    // split string into PEM messages (be lenient w/EOF on BEGIN line)
    var rMessage = /\s*-----BEGIN ([A-Z0-9- ]+)-----\r?\n?([\x21-\x7e\s]+?(?:\r?\n\r?\n))?([:A-Za-z0-9+\/=\s]+?)-----END \1-----/g;
    var rHeader = /([\x21-\x7e]+):\s*([\x21-\x7e\s^:]+)/;
    var rCRLF = /\r?\n/;
    var match;
    while(true){
        match = rMessage.exec(str);
        if (!match) break;
        var msg = {
            type: match[1],
            procType: null,
            contentDomain: null,
            dekInfo: null,
            headers: [],
            body: forge.util.decode64(match[3])
        };
        rval.push(msg);
        // no headers
        if (!match[2]) continue;
        // parse headers
        var lines = match[2].split(rCRLF);
        var li = 0;
        while(match && li < lines.length){
            // get line, trim any rhs whitespace
            var line = lines[li].replace(/\s+$/, '');
            // RFC2822 unfold any following folded lines
            for(var nl = li + 1; nl < lines.length; ++nl){
                var next = lines[nl];
                if (!/\s/.test(next[0])) break;
                line += next;
                li = nl;
            }
            // parse header
            match = line.match(rHeader);
            if (match) {
                var header = {
                    name: match[1],
                    values: []
                };
                var values = match[2].split(',');
                for(var vi = 0; vi < values.length; ++vi)header.values.push(ltrim(values[vi]));
                // Proc-Type must be the first header
                if (!msg.procType) {
                    if (header.name !== 'Proc-Type') throw new Error("Invalid PEM formatted message. The first encapsulated header must be \"Proc-Type\".");
                    else if (header.values.length !== 2) throw new Error("Invalid PEM formatted message. The \"Proc-Type\" header must have two subfields.");
                    msg.procType = {
                        version: values[0],
                        type: values[1]
                    };
                } else if (!msg.contentDomain && header.name === 'Content-Domain') // special-case Content-Domain
                msg.contentDomain = values[0] || '';
                else if (!msg.dekInfo && header.name === 'DEK-Info') {
                    // special-case DEK-Info
                    if (header.values.length === 0) throw new Error("Invalid PEM formatted message. The \"DEK-Info\" header must have at least one subfield.");
                    msg.dekInfo = {
                        algorithm: values[0],
                        parameters: values[1] || null
                    };
                } else msg.headers.push(header);
            }
            ++li;
        }
        if (msg.procType === 'ENCRYPTED' && !msg.dekInfo) throw new Error("Invalid PEM formatted message. The \"DEK-Info\" header must be present if \"Proc-Type\" is \"ENCRYPTED\".");
    }
    if (rval.length === 0) throw new Error('Invalid PEM formatted message.');
    return rval;
};
function foldHeader(header) {
    var rval = header.name + ': ';
    // ensure values with CRLF are folded
    var values = [];
    var insertSpace = function(match, $1) {
        return ' ' + $1;
    };
    for(var i = 0; i < header.values.length; ++i)values.push(header.values[i].replace(/^(\S+\r\n)/, insertSpace));
    rval += values.join(',') + '\r\n';
    // do folding
    var length = 0;
    var candidate = -1;
    for(var i = 0; i < rval.length; ++i, ++length){
        if (length > 65 && candidate !== -1) {
            var insert = rval[candidate];
            if (insert === ',') {
                ++candidate;
                rval = rval.substr(0, candidate) + '\r\n ' + rval.substr(candidate);
            } else rval = rval.substr(0, candidate) + '\r\n' + insert + rval.substr(candidate + 1);
            length = i - candidate - 1;
            candidate = -1;
            ++i;
        } else if (rval[i] === ' ' || rval[i] === '\t' || rval[i] === ',') candidate = i;
    }
    return rval;
}
function ltrim(str) {
    return str.replace(/^\s+/, '');
}

},{"./forge":"7AnVp","./util":"cHj6b"}],"7GrCn":[function(require,module,exports) {
/**
 * An API for getting cryptographically-secure random bytes. The bytes are
 * generated using the Fortuna algorithm devised by Bruce Schneier and
 * Niels Ferguson.
 *
 * Getting strong random bytes is not yet easy to do in javascript. The only
 * truish random entropy that can be collected is from the mouse, keyboard, or
 * from timing with respect to page loads, etc. This generator makes a poor
 * attempt at providing random bytes when those sources haven't yet provided
 * enough entropy to initially seed or to reseed the PRNG.
 *
 * @author Dave Longley
 *
 * Copyright (c) 2009-2014 Digital Bazaar, Inc.
 */ var forge = require('./forge');
require('./aes');
require('./sha256');
require('./prng');
require('./util');
(function() {
    // forge.random already defined
    if (forge.random && forge.random.getBytes) {
        module.exports = forge.random;
        return;
    }
    (function(jQuery) {
        // the default prng plugin, uses AES-128
        var prng_aes = {
        };
        var _prng_aes_output = new Array(4);
        var _prng_aes_buffer = forge.util.createBuffer();
        prng_aes.formatKey = function(key) {
            // convert the key into 32-bit integers
            var tmp = forge.util.createBuffer(key);
            key = new Array(4);
            key[0] = tmp.getInt32();
            key[1] = tmp.getInt32();
            key[2] = tmp.getInt32();
            key[3] = tmp.getInt32();
            // return the expanded key
            return forge.aes._expandKey(key, false);
        };
        prng_aes.formatSeed = function(seed) {
            // convert seed into 32-bit integers
            var tmp = forge.util.createBuffer(seed);
            seed = new Array(4);
            seed[0] = tmp.getInt32();
            seed[1] = tmp.getInt32();
            seed[2] = tmp.getInt32();
            seed[3] = tmp.getInt32();
            return seed;
        };
        prng_aes.cipher = function(key, seed) {
            forge.aes._updateBlock(key, seed, _prng_aes_output, false);
            _prng_aes_buffer.putInt32(_prng_aes_output[0]);
            _prng_aes_buffer.putInt32(_prng_aes_output[1]);
            _prng_aes_buffer.putInt32(_prng_aes_output[2]);
            _prng_aes_buffer.putInt32(_prng_aes_output[3]);
            return _prng_aes_buffer.getBytes();
        };
        prng_aes.increment = function(seed) {
            // FIXME: do we care about carry or signed issues?
            ++seed[3];
            return seed;
        };
        prng_aes.md = forge.md.sha256;
        /**
 * Creates a new PRNG.
 */ function spawnPrng() {
            var ctx = forge.prng.create(prng_aes);
            /**
   * Gets random bytes. If a native secure crypto API is unavailable, this
   * method tries to make the bytes more unpredictable by drawing from data that
   * can be collected from the user of the browser, eg: mouse movement.
   *
   * If a callback is given, this method will be called asynchronously.
   *
   * @param count the number of random bytes to get.
   * @param [callback(err, bytes)] called once the operation completes.
   *
   * @return the random bytes in a string.
   */ ctx.getBytes = function(count, callback) {
                return ctx.generate(count, callback);
            };
            /**
   * Gets random bytes asynchronously. If a native secure crypto API is
   * unavailable, this method tries to make the bytes more unpredictable by
   * drawing from data that can be collected from the user of the browser,
   * eg: mouse movement.
   *
   * @param count the number of random bytes to get.
   *
   * @return the random bytes in a string.
   */ ctx.getBytesSync = function(count) {
                return ctx.generate(count);
            };
            return ctx;
        }
        // create default prng context
        var _ctx = spawnPrng();
        // add other sources of entropy only if window.crypto.getRandomValues is not
        // available -- otherwise this source will be automatically used by the prng
        var getRandomValues = null;
        var globalScope = forge.util.globalScope;
        var _crypto = globalScope.crypto || globalScope.msCrypto;
        if (_crypto && _crypto.getRandomValues) getRandomValues = function(arr) {
            return _crypto.getRandomValues(arr);
        };
        if (forge.options.usePureJavaScript || !forge.util.isNodejs && !getRandomValues) {
            typeof window === 'undefined' || window.document;
            // get load time entropy
            _ctx.collectInt(+new Date(), 32);
            // add some entropy from navigator object
            if (typeof navigator !== 'undefined') {
                var _navBytes = '';
                for(var key1 in navigator)try {
                    if (typeof navigator[key1] == 'string') _navBytes += navigator[key1];
                } catch (e) {
                /* Some navigator keys might not be accessible, e.g. the geolocation
          attribute throws an exception if touched in Mozilla chrome://
          context.

          Silently ignore this and just don't use this as a source of
          entropy. */ }
                _ctx.collect(_navBytes);
                _navBytes = null;
            }
            // add mouse and keyboard collectors if jquery is available
            if (jQuery) {
                // set up mouse entropy capture
                jQuery().mousemove(function(e) {
                    // add mouse coords
                    _ctx.collectInt(e.clientX, 16);
                    _ctx.collectInt(e.clientY, 16);
                });
                // set up keyboard entropy capture
                jQuery().keypress(function(e) {
                    _ctx.collectInt(e.charCode, 8);
                });
            }
        }
        /* Random API */ if (!forge.random) forge.random = _ctx;
        else // extend forge.random with _ctx
        for(var key1 in _ctx)forge.random[key1] = _ctx[key1];
        // expose spawn PRNG
        forge.random.createInstance = spawnPrng;
        module.exports = forge.random;
    })(typeof jQuery !== 'undefined' ? jQuery : null);
})();

},{"./forge":"7AnVp","./aes":"jgIby","./sha256":"fHkaX","./prng":"6wCDp","./util":"cHj6b"}],"fHkaX":[function(require,module,exports) {
/**
 * Secure Hash Algorithm with 256-bit digest (SHA-256) implementation.
 *
 * See FIPS 180-2 for details.
 *
 * @author Dave Longley
 *
 * Copyright (c) 2010-2015 Digital Bazaar, Inc.
 */ var forge = require('./forge');
require('./md');
require('./util');
var sha256 = module.exports = forge.sha256 = forge.sha256 || {
};
forge.md.sha256 = forge.md.algorithms.sha256 = sha256;
/**
 * Creates a SHA-256 message digest object.
 *
 * @return a message digest object.
 */ sha256.create = function() {
    // do initialization as necessary
    if (!_initialized) _init();
    // SHA-256 state contains eight 32-bit integers
    var _state = null;
    // input buffer
    var _input = forge.util.createBuffer();
    // used for word storage
    var _w = new Array(64);
    // message digest object
    var md = {
        algorithm: 'sha256',
        blockLength: 64,
        digestLength: 32,
        // 56-bit length of message so far (does not including padding)
        messageLength: 0,
        // true message length
        fullMessageLength: null,
        // size of message length in bytes
        messageLengthSize: 8
    };
    /**
   * Starts the digest.
   *
   * @return this digest object.
   */ md.start = function() {
        // up to 56-bit message length for convenience
        md.messageLength = 0;
        // full message length (set md.messageLength64 for backwards-compatibility)
        md.fullMessageLength = md.messageLength64 = [];
        var int32s = md.messageLengthSize / 4;
        for(var i = 0; i < int32s; ++i)md.fullMessageLength.push(0);
        _input = forge.util.createBuffer();
        _state = {
            h0: 1779033703,
            h1: 3144134277,
            h2: 1013904242,
            h3: 2773480762,
            h4: 1359893119,
            h5: 2600822924,
            h6: 528734635,
            h7: 1541459225
        };
        return md;
    };
    // start digest automatically for first time
    md.start();
    /**
   * Updates the digest with the given message input. The given input can
   * treated as raw input (no encoding will be applied) or an encoding of
   * 'utf8' maybe given to encode the input using UTF-8.
   *
   * @param msg the message input to update with.
   * @param encoding the encoding to use (default: 'raw', other: 'utf8').
   *
   * @return this digest object.
   */ md.update = function(msg, encoding) {
        if (encoding === 'utf8') msg = forge.util.encodeUtf8(msg);
        // update message length
        var len = msg.length;
        md.messageLength += len;
        len = [
            len / 4294967296 >>> 0,
            len >>> 0
        ];
        for(var i = md.fullMessageLength.length - 1; i >= 0; --i){
            md.fullMessageLength[i] += len[1];
            len[1] = len[0] + (md.fullMessageLength[i] / 4294967296 >>> 0);
            md.fullMessageLength[i] = md.fullMessageLength[i] >>> 0;
            len[0] = len[1] / 4294967296 >>> 0;
        }
        // add bytes to input buffer
        _input.putBytes(msg);
        // process bytes
        _update(_state, _w, _input);
        // compact input buffer every 2K or if empty
        if (_input.read > 2048 || _input.length() === 0) _input.compact();
        return md;
    };
    /**
   * Produces the digest.
   *
   * @return a byte buffer containing the digest value.
   */ md.digest = function() {
        /* Note: Here we copy the remaining bytes in the input buffer and
    add the appropriate SHA-256 padding. Then we do the final update
    on a copy of the state so that if the user wants to get
    intermediate digests they can do so. */ /* Determine the number of bytes that must be added to the message
    to ensure its length is congruent to 448 mod 512. In other words,
    the data to be digested must be a multiple of 512 bits (or 128 bytes).
    This data includes the message, some padding, and the length of the
    message. Since the length of the message will be encoded as 8 bytes (64
    bits), that means that the last segment of the data must have 56 bytes
    (448 bits) of message and padding. Therefore, the length of the message
    plus the padding must be congruent to 448 mod 512 because
    512 - 128 = 448.

    In order to fill up the message length it must be filled with
    padding that begins with 1 bit followed by all 0 bits. Padding
    must *always* be present, so if the message length is already
    congruent to 448 mod 512, then 512 padding bits must be added. */ var finalBlock = forge.util.createBuffer();
        finalBlock.putBytes(_input.bytes());
        // compute remaining size to be digested (include message length size)
        var remaining = md.fullMessageLength[md.fullMessageLength.length - 1] + md.messageLengthSize;
        // add padding for overflow blockSize - overflow
        // _padding starts with 1 byte with first bit is set (byte value 128), then
        // there may be up to (blockSize - 1) other pad bytes
        var overflow = remaining & md.blockLength - 1;
        finalBlock.putBytes(_padding.substr(0, md.blockLength - overflow));
        // serialize message length in bits in big-endian order; since length
        // is stored in bytes we multiply by 8 and add carry from next int
        var next, carry;
        var bits = md.fullMessageLength[0] * 8;
        for(var i = 0; i < md.fullMessageLength.length - 1; ++i){
            next = md.fullMessageLength[i + 1] * 8;
            carry = next / 4294967296 >>> 0;
            bits += carry;
            finalBlock.putInt32(bits >>> 0);
            bits = next >>> 0;
        }
        finalBlock.putInt32(bits);
        var s2 = {
            h0: _state.h0,
            h1: _state.h1,
            h2: _state.h2,
            h3: _state.h3,
            h4: _state.h4,
            h5: _state.h5,
            h6: _state.h6,
            h7: _state.h7
        };
        _update(s2, _w, finalBlock);
        var rval = forge.util.createBuffer();
        rval.putInt32(s2.h0);
        rval.putInt32(s2.h1);
        rval.putInt32(s2.h2);
        rval.putInt32(s2.h3);
        rval.putInt32(s2.h4);
        rval.putInt32(s2.h5);
        rval.putInt32(s2.h6);
        rval.putInt32(s2.h7);
        return rval;
    };
    return md;
};
// sha-256 padding bytes not initialized yet
var _padding = null;
var _initialized = false;
// table of constants
var _k = null;
/**
 * Initializes the constant tables.
 */ function _init() {
    // create padding
    _padding = String.fromCharCode(128);
    _padding += forge.util.fillString(String.fromCharCode(0), 64);
    // create K table for SHA-256
    _k = [
        1116352408,
        1899447441,
        3049323471,
        3921009573,
        961987163,
        1508970993,
        2453635748,
        2870763221,
        3624381080,
        310598401,
        607225278,
        1426881987,
        1925078388,
        2162078206,
        2614888103,
        3248222580,
        3835390401,
        4022224774,
        264347078,
        604807628,
        770255983,
        1249150122,
        1555081692,
        1996064986,
        2554220882,
        2821834349,
        2952996808,
        3210313671,
        3336571891,
        3584528711,
        113926993,
        338241895,
        666307205,
        773529912,
        1294757372,
        1396182291,
        1695183700,
        1986661051,
        2177026350,
        2456956037,
        2730485921,
        2820302411,
        3259730800,
        3345764771,
        3516065817,
        3600352804,
        4094571909,
        275423344,
        430227734,
        506948616,
        659060556,
        883997877,
        958139571,
        1322822218,
        1537002063,
        1747873779,
        1955562222,
        2024104815,
        2227730452,
        2361852424,
        2428436474,
        2756734187,
        3204031479,
        3329325298
    ];
    // now initialized
    _initialized = true;
}
/**
 * Updates a SHA-256 state with the given byte buffer.
 *
 * @param s the SHA-256 state to update.
 * @param w the array to use to store words.
 * @param bytes the byte buffer to update with.
 */ function _update(s, w, bytes) {
    // consume 512 bit (64 byte) chunks
    var t1, t2, s0, s1, ch, maj, i, a, b, c, d, e, f, g, h;
    var len = bytes.length();
    while(len >= 64){
        // the w array will be populated with sixteen 32-bit big-endian words
        // and then extended into 64 32-bit words according to SHA-256
        for(i = 0; i < 16; ++i)w[i] = bytes.getInt32();
        for(; i < 64; ++i){
            // XOR word 2 words ago rot right 17, rot right 19, shft right 10
            t1 = w[i - 2];
            t1 = (t1 >>> 17 | t1 << 15) ^ (t1 >>> 19 | t1 << 13) ^ t1 >>> 10;
            // XOR word 15 words ago rot right 7, rot right 18, shft right 3
            t2 = w[i - 15];
            t2 = (t2 >>> 7 | t2 << 25) ^ (t2 >>> 18 | t2 << 14) ^ t2 >>> 3;
            // sum(t1, word 7 ago, t2, word 16 ago) modulo 2^32
            w[i] = t1 + w[i - 7] + t2 + w[i - 16] | 0;
        }
        // initialize hash value for this chunk
        a = s.h0;
        b = s.h1;
        c = s.h2;
        d = s.h3;
        e = s.h4;
        f = s.h5;
        g = s.h6;
        h = s.h7;
        // round function
        for(i = 0; i < 64; ++i){
            // Sum1(e)
            s1 = (e >>> 6 | e << 26) ^ (e >>> 11 | e << 21) ^ (e >>> 25 | e << 7);
            // Ch(e, f, g) (optimized the same way as SHA-1)
            ch = g ^ e & (f ^ g);
            // Sum0(a)
            s0 = (a >>> 2 | a << 30) ^ (a >>> 13 | a << 19) ^ (a >>> 22 | a << 10);
            // Maj(a, b, c) (optimized the same way as SHA-1)
            maj = a & b | c & (a ^ b);
            // main algorithm
            t1 = h + s1 + ch + _k[i] + w[i];
            t2 = s0 + maj;
            h = g;
            g = f;
            f = e;
            // `>>> 0` necessary to avoid iOS/Safari 10 optimization bug
            // can't truncate with `| 0`
            e = d + t1 >>> 0;
            d = c;
            c = b;
            b = a;
            // `>>> 0` necessary to avoid iOS/Safari 10 optimization bug
            // can't truncate with `| 0`
            a = t1 + t2 >>> 0;
        }
        // update hash state
        s.h0 = s.h0 + a | 0;
        s.h1 = s.h1 + b | 0;
        s.h2 = s.h2 + c | 0;
        s.h3 = s.h3 + d | 0;
        s.h4 = s.h4 + e | 0;
        s.h5 = s.h5 + f | 0;
        s.h6 = s.h6 + g | 0;
        s.h7 = s.h7 + h | 0;
        len -= 64;
    }
}

},{"./forge":"7AnVp","./md":"9dnCj","./util":"cHj6b"}],"6wCDp":[function(require,module,exports) {
var process = require("process");
/**
 * A javascript implementation of a cryptographically-secure
 * Pseudo Random Number Generator (PRNG). The Fortuna algorithm is followed
 * here though the use of SHA-256 is not enforced; when generating an
 * a PRNG context, the hashing algorithm and block cipher used for
 * the generator are specified via a plugin.
 *
 * @author Dave Longley
 *
 * Copyright (c) 2010-2014 Digital Bazaar, Inc.
 */ var forge = require('./forge');
require('./util');
var _crypto1 = null;
if (forge.util.isNodejs && !forge.options.usePureJavaScript && !process.versions['node-webkit']) _crypto1 = require('crypto');
/* PRNG API */ var prng = module.exports = forge.prng = forge.prng || {
};
/**
 * Creates a new PRNG context.
 *
 * A PRNG plugin must be passed in that will provide:
 *
 * 1. A function that initializes the key and seed of a PRNG context. It
 *   will be given a 16 byte key and a 16 byte seed. Any key expansion
 *   or transformation of the seed from a byte string into an array of
 *   integers (or similar) should be performed.
 * 2. The cryptographic function used by the generator. It takes a key and
 *   a seed.
 * 3. A seed increment function. It takes the seed and returns seed + 1.
 * 4. An api to create a message digest.
 *
 * For an example, see random.js.
 *
 * @param plugin the PRNG plugin to use.
 */ prng.create = function(plugin) {
    var ctx = {
        plugin: plugin,
        key: null,
        seed: null,
        time: null,
        // number of reseeds so far
        reseeds: 0,
        // amount of data generated so far
        generated: 0,
        // no initial key bytes
        keyBytes: ''
    };
    // create 32 entropy pools (each is a message digest)
    var md1 = plugin.md;
    var pools = new Array(32);
    for(var i1 = 0; i1 < 32; ++i1)pools[i1] = md1.create();
    ctx.pools = pools;
    // entropy pools are written to cyclically, starting at index 0
    ctx.pool = 0;
    /**
   * Generates random bytes. The bytes may be generated synchronously or
   * asynchronously. Web workers must use the asynchronous interface or
   * else the behavior is undefined.
   *
   * @param count the number of random bytes to generate.
   * @param [callback(err, bytes)] called once the operation completes.
   *
   * @return count random bytes as a string.
   */ ctx.generate = function(count, callback) {
        // do synchronously
        if (!callback) return ctx.generateSync(count);
        // simple generator using counter-based CBC
        var cipher = ctx.plugin.cipher;
        var increment = ctx.plugin.increment;
        var formatKey = ctx.plugin.formatKey;
        var formatSeed = ctx.plugin.formatSeed;
        var b = forge.util.createBuffer();
        // paranoid deviation from Fortuna:
        // reset key for every request to protect previously
        // generated random bytes should the key be discovered;
        // there is no 100ms based reseeding because of this
        // forced reseed for every `generate` call
        ctx.key = null;
        generate();
        function generate(err) {
            if (err) return callback(err);
            // sufficient bytes generated
            if (b.length() >= count) return callback(null, b.getBytes(count));
            // if amount of data generated is greater than 1 MiB, trigger reseed
            if (ctx.generated > 1048575) ctx.key = null;
            if (ctx.key === null) // prevent stack overflow
            return forge.util.nextTick(function() {
                _reseed(generate);
            });
            // generate the random bytes
            var bytes = cipher(ctx.key, ctx.seed);
            ctx.generated += bytes.length;
            b.putBytes(bytes);
            // generate bytes for a new key and seed
            ctx.key = formatKey(cipher(ctx.key, increment(ctx.seed)));
            ctx.seed = formatSeed(cipher(ctx.key, ctx.seed));
            forge.util.setImmediate(generate);
        }
    };
    /**
   * Generates random bytes synchronously.
   *
   * @param count the number of random bytes to generate.
   *
   * @return count random bytes as a string.
   */ ctx.generateSync = function(count) {
        // simple generator using counter-based CBC
        var cipher = ctx.plugin.cipher;
        var increment = ctx.plugin.increment;
        var formatKey = ctx.plugin.formatKey;
        var formatSeed = ctx.plugin.formatSeed;
        // paranoid deviation from Fortuna:
        // reset key for every request to protect previously
        // generated random bytes should the key be discovered;
        // there is no 100ms based reseeding because of this
        // forced reseed for every `generateSync` call
        ctx.key = null;
        var b = forge.util.createBuffer();
        while(b.length() < count){
            // if amount of data generated is greater than 1 MiB, trigger reseed
            if (ctx.generated > 1048575) ctx.key = null;
            if (ctx.key === null) _reseedSync();
            // generate the random bytes
            var bytes = cipher(ctx.key, ctx.seed);
            ctx.generated += bytes.length;
            b.putBytes(bytes);
            // generate bytes for a new key and seed
            ctx.key = formatKey(cipher(ctx.key, increment(ctx.seed)));
            ctx.seed = formatSeed(cipher(ctx.key, ctx.seed));
        }
        return b.getBytes(count);
    };
    /**
   * Private function that asynchronously reseeds a generator.
   *
   * @param callback(err) called once the operation completes.
   */ function _reseed(callback) {
        if (ctx.pools[0].messageLength >= 32) {
            _seed();
            return callback();
        }
        // not enough seed data...
        var needed = 32 - ctx.pools[0].messageLength << 5;
        ctx.seedFile(needed, function(err, bytes) {
            if (err) return callback(err);
            ctx.collect(bytes);
            _seed();
            callback();
        });
    }
    /**
   * Private function that synchronously reseeds a generator.
   */ function _reseedSync() {
        if (ctx.pools[0].messageLength >= 32) return _seed();
        // not enough seed data...
        var needed = 32 - ctx.pools[0].messageLength << 5;
        ctx.collect(ctx.seedFileSync(needed));
        _seed();
    }
    /**
   * Private function that seeds a generator once enough bytes are available.
   */ function _seed() {
        // update reseed count
        ctx.reseeds = ctx.reseeds === 4294967295 ? 0 : ctx.reseeds + 1;
        // goal is to update `key` via:
        // key = hash(key + s)
        //   where 's' is all collected entropy from selected pools, then...
        // create a plugin-based message digest
        var md = ctx.plugin.md.create();
        // consume current key bytes
        md.update(ctx.keyBytes);
        // digest the entropy of pools whose index k meet the
        // condition 'n mod 2^k == 0' where n is the number of reseeds
        var _2powK = 1;
        for(var k = 0; k < 32; ++k){
            if (ctx.reseeds % _2powK === 0) {
                md.update(ctx.pools[k].digest().getBytes());
                ctx.pools[k].start();
            }
            _2powK = _2powK << 1;
        }
        // get digest for key bytes
        ctx.keyBytes = md.digest().getBytes();
        // paranoid deviation from Fortuna:
        // update `seed` via `seed = hash(key)`
        // instead of initializing to zero once and only
        // ever incrementing it
        md.start();
        md.update(ctx.keyBytes);
        var seedBytes = md.digest().getBytes();
        // update state
        ctx.key = ctx.plugin.formatKey(ctx.keyBytes);
        ctx.seed = ctx.plugin.formatSeed(seedBytes);
        ctx.generated = 0;
    }
    /**
   * The built-in default seedFile. This seedFile is used when entropy
   * is needed immediately.
   *
   * @param needed the number of bytes that are needed.
   *
   * @return the random bytes.
   */ function defaultSeedFile(needed) {
        // use window.crypto.getRandomValues strong source of entropy if available
        var getRandomValues = null;
        var globalScope = forge.util.globalScope;
        var _crypto = globalScope.crypto || globalScope.msCrypto;
        if (_crypto && _crypto.getRandomValues) getRandomValues = function(arr) {
            return _crypto.getRandomValues(arr);
        };
        var b = forge.util.createBuffer();
        if (getRandomValues) while(b.length() < needed){
            // max byte length is 65536 before QuotaExceededError is thrown
            // http://www.w3.org/TR/WebCryptoAPI/#RandomSource-method-getRandomValues
            var count = Math.max(1, Math.min(needed - b.length(), 65536) / 4);
            var entropy = new Uint32Array(Math.floor(count));
            try {
                getRandomValues(entropy);
                for(var i = 0; i < entropy.length; ++i)b.putInt32(entropy[i]);
            } catch (e) {
                /* only ignore QuotaExceededError */ if (!(typeof QuotaExceededError !== 'undefined' && e instanceof QuotaExceededError)) throw e;
            }
        }
        // be sad and add some weak random data
        if (b.length() < needed) {
            /* Draws from Park-Miller "minimal standard" 31 bit PRNG,
      implemented with David G. Carta's optimization: with 32 bit math
      and without division (Public Domain). */ var hi, lo, next;
            var seed = Math.floor(Math.random() * 65536);
            while(b.length() < needed){
                lo = 16807 * (seed & 65535);
                hi = 16807 * (seed >> 16);
                lo += (hi & 32767) << 16;
                lo += hi >> 15;
                lo = (lo & 2147483647) + (lo >> 31);
                seed = lo & 4294967295;
                // consume lower 3 bytes of seed
                for(var i = 0; i < 3; ++i){
                    // throw in more pseudo random
                    next = seed >>> (i << 3);
                    next ^= Math.floor(Math.random() * 256);
                    b.putByte(String.fromCharCode(next & 255));
                }
            }
        }
        return b.getBytes(needed);
    }
    // initialize seed file APIs
    if (_crypto1) {
        // use nodejs async API
        ctx.seedFile = function(needed, callback) {
            _crypto1.randomBytes(needed, function(err, bytes) {
                if (err) return callback(err);
                callback(null, bytes.toString());
            });
        };
        // use nodejs sync API
        ctx.seedFileSync = function(needed) {
            return _crypto1.randomBytes(needed).toString();
        };
    } else {
        ctx.seedFile = function(needed, callback) {
            try {
                callback(null, defaultSeedFile(needed));
            } catch (e) {
                callback(e);
            }
        };
        ctx.seedFileSync = defaultSeedFile;
    }
    /**
   * Adds entropy to a prng ctx's accumulator.
   *
   * @param bytes the bytes of entropy as a string.
   */ ctx.collect = function(bytes) {
        // iterate over pools distributing entropy cyclically
        var count = bytes.length;
        for(var i = 0; i < count; ++i){
            ctx.pools[ctx.pool].update(bytes.substr(i, 1));
            ctx.pool = ctx.pool === 31 ? 0 : ctx.pool + 1;
        }
    };
    /**
   * Collects an integer of n bits.
   *
   * @param i the integer entropy.
   * @param n the number of bits in the integer.
   */ ctx.collectInt = function(i, n) {
        var bytes = '';
        for(var x = 0; x < n; x += 8)bytes += String.fromCharCode(i >> x & 255);
        ctx.collect(bytes);
    };
    /**
   * Registers a Web Worker to receive immediate entropy from the main thread.
   * This method is required until Web Workers can access the native crypto
   * API. This method should be called twice for each created worker, once in
   * the main thread, and once in the worker itself.
   *
   * @param worker the worker to register.
   */ ctx.registerWorker = function(worker) {
        // worker receives random bytes
        if (worker === self) ctx.seedFile = function(needed, callback) {
            function listener(e) {
                var data = e.data;
                if (data.forge && data.forge.prng) {
                    self.removeEventListener('message', listener);
                    callback(data.forge.prng.err, data.forge.prng.bytes);
                }
            }
            self.addEventListener('message', listener);
            self.postMessage({
                forge: {
                    prng: {
                        needed: needed
                    }
                }
            });
        };
        else {
            // main thread sends random bytes upon request
            var listener1 = function(e) {
                var data = e.data;
                if (data.forge && data.forge.prng) ctx.seedFile(data.forge.prng.needed, function(err, bytes) {
                    worker.postMessage({
                        forge: {
                            prng: {
                                err: err,
                                bytes: bytes
                            }
                        }
                    });
                });
            };
            // TODO: do we need to remove the event listener when the worker dies?
            worker.addEventListener('message', listener1);
        }
    };
    return ctx;
};

},{"process":"joWnX","./forge":"7AnVp","./util":"cHj6b","crypto":"joWnX"}],"2vA0U":[function(require,module,exports) {
/**
 * RC2 implementation.
 *
 * @author Stefan Siegl
 *
 * Copyright (c) 2012 Stefan Siegl <stesie@brokenpipe.de>
 *
 * Information on the RC2 cipher is available from RFC #2268,
 * http://www.ietf.org/rfc/rfc2268.txt
 */ var forge = require('./forge');
require('./util');
var piTable = [
    217,
    120,
    249,
    196,
    25,
    221,
    181,
    237,
    40,
    233,
    253,
    121,
    74,
    160,
    216,
    157,
    198,
    126,
    55,
    131,
    43,
    118,
    83,
    142,
    98,
    76,
    100,
    136,
    68,
    139,
    251,
    162,
    23,
    154,
    89,
    245,
    135,
    179,
    79,
    19,
    97,
    69,
    109,
    141,
    9,
    129,
    125,
    50,
    189,
    143,
    64,
    235,
    134,
    183,
    123,
    11,
    240,
    149,
    33,
    34,
    92,
    107,
    78,
    130,
    84,
    214,
    101,
    147,
    206,
    96,
    178,
    28,
    115,
    86,
    192,
    20,
    167,
    140,
    241,
    220,
    18,
    117,
    202,
    31,
    59,
    190,
    228,
    209,
    66,
    61,
    212,
    48,
    163,
    60,
    182,
    38,
    111,
    191,
    14,
    218,
    70,
    105,
    7,
    87,
    39,
    242,
    29,
    155,
    188,
    148,
    67,
    3,
    248,
    17,
    199,
    246,
    144,
    239,
    62,
    231,
    6,
    195,
    213,
    47,
    200,
    102,
    30,
    215,
    8,
    232,
    234,
    222,
    128,
    82,
    238,
    247,
    132,
    170,
    114,
    172,
    53,
    77,
    106,
    42,
    150,
    26,
    210,
    113,
    90,
    21,
    73,
    116,
    75,
    159,
    208,
    94,
    4,
    24,
    164,
    236,
    194,
    224,
    65,
    110,
    15,
    81,
    203,
    204,
    36,
    145,
    175,
    80,
    161,
    244,
    112,
    57,
    153,
    124,
    58,
    133,
    35,
    184,
    180,
    122,
    252,
    2,
    54,
    91,
    37,
    85,
    151,
    49,
    45,
    93,
    250,
    152,
    227,
    138,
    146,
    174,
    5,
    223,
    41,
    16,
    103,
    108,
    186,
    201,
    211,
    0,
    230,
    207,
    225,
    158,
    168,
    44,
    99,
    22,
    1,
    63,
    88,
    226,
    137,
    169,
    13,
    56,
    52,
    27,
    171,
    51,
    255,
    176,
    187,
    72,
    12,
    95,
    185,
    177,
    205,
    46,
    197,
    243,
    219,
    71,
    229,
    165,
    156,
    119,
    10,
    166,
    32,
    104,
    254,
    127,
    193,
    173
];
var s = [
    1,
    2,
    3,
    5
];
/**
 * Rotate a word left by given number of bits.
 *
 * Bits that are shifted out on the left are put back in on the right
 * hand side.
 *
 * @param word The word to shift left.
 * @param bits The number of bits to shift by.
 * @return The rotated word.
 */ var rol = function(word, bits) {
    return word << bits & 65535 | (word & 65535) >> 16 - bits;
};
/**
 * Rotate a word right by given number of bits.
 *
 * Bits that are shifted out on the right are put back in on the left
 * hand side.
 *
 * @param word The word to shift right.
 * @param bits The number of bits to shift by.
 * @return The rotated word.
 */ var ror = function(word, bits) {
    return (word & 65535) >> bits | word << 16 - bits & 65535;
};
/* RC2 API */ module.exports = forge.rc2 = forge.rc2 || {
};
/**
 * Perform RC2 key expansion as per RFC #2268, section 2.
 *
 * @param key variable-length user key (between 1 and 128 bytes)
 * @param effKeyBits number of effective key bits (default: 128)
 * @return the expanded RC2 key (ByteBuffer of 128 bytes)
 */ forge.rc2.expandKey = function(key, effKeyBits) {
    if (typeof key === 'string') key = forge.util.createBuffer(key);
    effKeyBits = effKeyBits || 128;
    /* introduce variables that match the names used in RFC #2268 */ var L = key;
    var T = key.length();
    var T1 = effKeyBits;
    var T8 = Math.ceil(T1 / 8);
    var TM = 255 >> (T1 & 7);
    var i;
    for(i = T; i < 128; i++)L.putByte(piTable[L.at(i - 1) + L.at(i - T) & 255]);
    L.setAt(128 - T8, piTable[L.at(128 - T8) & TM]);
    for(i = 127 - T8; i >= 0; i--)L.setAt(i, piTable[L.at(i + 1) ^ L.at(i + T8)]);
    return L;
};
/**
 * Creates a RC2 cipher object.
 *
 * @param key the symmetric key to use (as base for key generation).
 * @param bits the number of effective key bits.
 * @param encrypt false for decryption, true for encryption.
 *
 * @return the cipher.
 */ var createCipher = function(key, bits, encrypt) {
    var _finish = false, _input = null, _output = null, _iv = null;
    var mixRound, mashRound;
    var i, j, K = [];
    /* Expand key and fill into K[] Array */ key = forge.rc2.expandKey(key, bits);
    for(i = 0; i < 64; i++)K.push(key.getInt16Le());
    if (encrypt) {
        /**
     * Perform one mixing round "in place".
     *
     * @param R Array of four words to perform mixing on.
     */ mixRound = function(R) {
            for(i = 0; i < 4; i++){
                R[i] += K[j] + (R[(i + 3) % 4] & R[(i + 2) % 4]) + (~R[(i + 3) % 4] & R[(i + 1) % 4]);
                R[i] = rol(R[i], s[i]);
                j++;
            }
        };
        /**
     * Perform one mashing round "in place".
     *
     * @param R Array of four words to perform mashing on.
     */ mashRound = function(R) {
            for(i = 0; i < 4; i++)R[i] += K[R[(i + 3) % 4] & 63];
        };
    } else {
        /**
     * Perform one r-mixing round "in place".
     *
     * @param R Array of four words to perform mixing on.
     */ mixRound = function(R) {
            for(i = 3; i >= 0; i--){
                R[i] = ror(R[i], s[i]);
                R[i] -= K[j] + (R[(i + 3) % 4] & R[(i + 2) % 4]) + (~R[(i + 3) % 4] & R[(i + 1) % 4]);
                j--;
            }
        };
        /**
     * Perform one r-mashing round "in place".
     *
     * @param R Array of four words to perform mashing on.
     */ mashRound = function(R) {
            for(i = 3; i >= 0; i--)R[i] -= K[R[(i + 3) % 4] & 63];
        };
    }
    /**
   * Run the specified cipher execution plan.
   *
   * This function takes four words from the input buffer, applies the IV on
   * it (if requested) and runs the provided execution plan.
   *
   * The plan must be put together in form of a array of arrays.  Where the
   * outer one is simply a list of steps to perform and the inner one needs
   * to have two elements: the first one telling how many rounds to perform,
   * the second one telling what to do (i.e. the function to call).
   *
   * @param {Array} plan The plan to execute.
   */ var runPlan = function(plan) {
        var R = [];
        /* Get data from input buffer and fill the four words into R */ for(i = 0; i < 4; i++){
            var val = _input.getInt16Le();
            if (_iv !== null) {
                if (encrypt) /* We're encrypting, apply the IV first. */ val ^= _iv.getInt16Le();
                else /* We're decryption, keep cipher text for next block. */ _iv.putInt16Le(val);
            }
            R.push(val & 65535);
        }
        /* Reset global "j" variable as per spec. */ j = encrypt ? 0 : 63;
        /* Run execution plan. */ for(var ptr = 0; ptr < plan.length; ptr++)for(var ctr = 0; ctr < plan[ptr][0]; ctr++)plan[ptr][1](R);
        /* Write back result to output buffer. */ for(i = 0; i < 4; i++){
            if (_iv !== null) {
                if (encrypt) /* We're encrypting in CBC-mode, feed back encrypted bytes into
             IV buffer to carry it forward to next block. */ _iv.putInt16Le(R[i]);
                else R[i] ^= _iv.getInt16Le();
            }
            _output.putInt16Le(R[i]);
        }
    };
    /* Create cipher object */ var cipher = null;
    cipher = {
        /**
     * Starts or restarts the encryption or decryption process, whichever
     * was previously configured.
     *
     * To use the cipher in CBC mode, iv may be given either as a string
     * of bytes, or as a byte buffer.  For ECB mode, give null as iv.
     *
     * @param iv the initialization vector to use, null for ECB mode.
     * @param output the output the buffer to write to, null to create one.
     */ start: function(iv, output) {
            if (iv) /* CBC mode */ {
                if (typeof iv === 'string') iv = forge.util.createBuffer(iv);
            }
            _finish = false;
            _input = forge.util.createBuffer();
            _output = output || new forge.util.createBuffer();
            _iv = iv;
            cipher.output = _output;
        },
        /**
     * Updates the next block.
     *
     * @param input the buffer to read from.
     */ update: function(input) {
            if (!_finish) // not finishing, so fill the input buffer with more input
            _input.putBuffer(input);
            while(_input.length() >= 8)runPlan([
                [
                    5,
                    mixRound
                ],
                [
                    1,
                    mashRound
                ],
                [
                    6,
                    mixRound
                ],
                [
                    1,
                    mashRound
                ],
                [
                    5,
                    mixRound
                ]
            ]);
        },
        /**
     * Finishes encrypting or decrypting.
     *
     * @param pad a padding function to use, null for PKCS#7 padding,
     *           signature(blockSize, buffer, decrypt).
     *
     * @return true if successful, false on error.
     */ finish: function(pad) {
            var rval = true;
            if (encrypt) {
                if (pad) rval = pad(8, _input, !encrypt);
                else {
                    // add PKCS#7 padding to block (each pad byte is the
                    // value of the number of pad bytes)
                    var padding = _input.length() === 8 ? 8 : 8 - _input.length();
                    _input.fillWithByte(padding, padding);
                }
            }
            if (rval) {
                // do final update
                _finish = true;
                cipher.update();
            }
            if (!encrypt) {
                // check for error: input data not a multiple of block size
                rval = _input.length() === 0;
                if (rval) {
                    if (pad) rval = pad(8, _output, !encrypt);
                    else {
                        // ensure padding byte count is valid
                        var len = _output.length();
                        var count = _output.at(len - 1);
                        if (count > len) rval = false;
                        else // trim off padding bytes
                        _output.truncate(count);
                    }
                }
            }
            return rval;
        }
    };
    return cipher;
};
/**
 * Creates an RC2 cipher object to encrypt data in ECB or CBC mode using the
 * given symmetric key. The output will be stored in the 'output' member
 * of the returned cipher.
 *
 * The key and iv may be given as a string of bytes or a byte buffer.
 * The cipher is initialized to use 128 effective key bits.
 *
 * @param key the symmetric key to use.
 * @param iv the initialization vector to use.
 * @param output the buffer to write to, null to create one.
 *
 * @return the cipher.
 */ forge.rc2.startEncrypting = function(key, iv, output) {
    var cipher = forge.rc2.createEncryptionCipher(key, 128);
    cipher.start(iv, output);
    return cipher;
};
/**
 * Creates an RC2 cipher object to encrypt data in ECB or CBC mode using the
 * given symmetric key.
 *
 * The key may be given as a string of bytes or a byte buffer.
 *
 * To start encrypting call start() on the cipher with an iv and optional
 * output buffer.
 *
 * @param key the symmetric key to use.
 *
 * @return the cipher.
 */ forge.rc2.createEncryptionCipher = function(key, bits) {
    return createCipher(key, bits, true);
};
/**
 * Creates an RC2 cipher object to decrypt data in ECB or CBC mode using the
 * given symmetric key. The output will be stored in the 'output' member
 * of the returned cipher.
 *
 * The key and iv may be given as a string of bytes or a byte buffer.
 * The cipher is initialized to use 128 effective key bits.
 *
 * @param key the symmetric key to use.
 * @param iv the initialization vector to use.
 * @param output the buffer to write to, null to create one.
 *
 * @return the cipher.
 */ forge.rc2.startDecrypting = function(key, iv, output) {
    var cipher = forge.rc2.createDecryptionCipher(key, 128);
    cipher.start(iv, output);
    return cipher;
};
/**
 * Creates an RC2 cipher object to decrypt data in ECB or CBC mode using the
 * given symmetric key.
 *
 * The key may be given as a string of bytes or a byte buffer.
 *
 * To start decrypting call start() on the cipher with an iv and optional
 * output buffer.
 *
 * @param key the symmetric key to use.
 *
 * @return the cipher.
 */ forge.rc2.createDecryptionCipher = function(key, bits) {
    return createCipher(key, bits, false);
};

},{"./forge":"7AnVp","./util":"cHj6b"}],"2GXRz":[function(require,module,exports) {
/**
 * Javascript implementation of basic RSA algorithms.
 *
 * @author Dave Longley
 *
 * Copyright (c) 2010-2014 Digital Bazaar, Inc.
 *
 * The only algorithm currently supported for PKI is RSA.
 *
 * An RSA key is often stored in ASN.1 DER format. The SubjectPublicKeyInfo
 * ASN.1 structure is composed of an algorithm of type AlgorithmIdentifier
 * and a subjectPublicKey of type bit string.
 *
 * The AlgorithmIdentifier contains an Object Identifier (OID) and parameters
 * for the algorithm, if any. In the case of RSA, there aren't any.
 *
 * SubjectPublicKeyInfo ::= SEQUENCE {
 *   algorithm AlgorithmIdentifier,
 *   subjectPublicKey BIT STRING
 * }
 *
 * AlgorithmIdentifer ::= SEQUENCE {
 *   algorithm OBJECT IDENTIFIER,
 *   parameters ANY DEFINED BY algorithm OPTIONAL
 * }
 *
 * For an RSA public key, the subjectPublicKey is:
 *
 * RSAPublicKey ::= SEQUENCE {
 *   modulus            INTEGER,    -- n
 *   publicExponent     INTEGER     -- e
 * }
 *
 * PrivateKeyInfo ::= SEQUENCE {
 *   version                   Version,
 *   privateKeyAlgorithm       PrivateKeyAlgorithmIdentifier,
 *   privateKey                PrivateKey,
 *   attributes           [0]  IMPLICIT Attributes OPTIONAL
 * }
 *
 * Version ::= INTEGER
 * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
 * PrivateKey ::= OCTET STRING
 * Attributes ::= SET OF Attribute
 *
 * An RSA private key as the following structure:
 *
 * RSAPrivateKey ::= SEQUENCE {
 *   version Version,
 *   modulus INTEGER, -- n
 *   publicExponent INTEGER, -- e
 *   privateExponent INTEGER, -- d
 *   prime1 INTEGER, -- p
 *   prime2 INTEGER, -- q
 *   exponent1 INTEGER, -- d mod (p-1)
 *   exponent2 INTEGER, -- d mod (q-1)
 *   coefficient INTEGER -- (inverse of q) mod p
 * }
 *
 * Version ::= INTEGER
 *
 * The OID for the RSA key algorithm is: 1.2.840.113549.1.1.1
 */ var forge = require('./forge');
require('./asn1');
require('./jsbn');
require('./oids');
require('./pkcs1');
require('./prime');
require('./random');
require('./util');
if (typeof BigInteger === 'undefined') var BigInteger = forge.jsbn.BigInteger;
var _crypto = forge.util.isNodejs ? require('crypto') : null;
// shortcut for asn.1 API
var asn1 = forge.asn1;
// shortcut for util API
var util = forge.util;
/*
 * RSA encryption and decryption, see RFC 2313.
 */ forge.pki = forge.pki || {
};
module.exports = forge.pki.rsa = forge.rsa = forge.rsa || {
};
var pki = forge.pki;
// for finding primes, which are 30k+i for i = 1, 7, 11, 13, 17, 19, 23, 29
var GCD_30_DELTA = [
    6,
    4,
    2,
    4,
    2,
    4,
    6,
    2
];
// validator for a PrivateKeyInfo structure
var privateKeyValidator = {
    // PrivateKeyInfo
    name: 'PrivateKeyInfo',
    tagClass: asn1.Class.UNIVERSAL,
    type: asn1.Type.SEQUENCE,
    constructed: true,
    value: [
        {
            // Version (INTEGER)
            name: 'PrivateKeyInfo.version',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.INTEGER,
            constructed: false,
            capture: 'privateKeyVersion'
        },
        {
            // privateKeyAlgorithm
            name: 'PrivateKeyInfo.privateKeyAlgorithm',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.SEQUENCE,
            constructed: true,
            value: [
                {
                    name: 'AlgorithmIdentifier.algorithm',
                    tagClass: asn1.Class.UNIVERSAL,
                    type: asn1.Type.OID,
                    constructed: false,
                    capture: 'privateKeyOid'
                }
            ]
        },
        {
            // PrivateKey
            name: 'PrivateKeyInfo',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.OCTETSTRING,
            constructed: false,
            capture: 'privateKey'
        }
    ]
};
// validator for an RSA private key
var rsaPrivateKeyValidator = {
    // RSAPrivateKey
    name: 'RSAPrivateKey',
    tagClass: asn1.Class.UNIVERSAL,
    type: asn1.Type.SEQUENCE,
    constructed: true,
    value: [
        {
            // Version (INTEGER)
            name: 'RSAPrivateKey.version',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.INTEGER,
            constructed: false,
            capture: 'privateKeyVersion'
        },
        {
            // modulus (n)
            name: 'RSAPrivateKey.modulus',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.INTEGER,
            constructed: false,
            capture: 'privateKeyModulus'
        },
        {
            // publicExponent (e)
            name: 'RSAPrivateKey.publicExponent',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.INTEGER,
            constructed: false,
            capture: 'privateKeyPublicExponent'
        },
        {
            // privateExponent (d)
            name: 'RSAPrivateKey.privateExponent',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.INTEGER,
            constructed: false,
            capture: 'privateKeyPrivateExponent'
        },
        {
            // prime1 (p)
            name: 'RSAPrivateKey.prime1',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.INTEGER,
            constructed: false,
            capture: 'privateKeyPrime1'
        },
        {
            // prime2 (q)
            name: 'RSAPrivateKey.prime2',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.INTEGER,
            constructed: false,
            capture: 'privateKeyPrime2'
        },
        {
            // exponent1 (d mod (p-1))
            name: 'RSAPrivateKey.exponent1',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.INTEGER,
            constructed: false,
            capture: 'privateKeyExponent1'
        },
        {
            // exponent2 (d mod (q-1))
            name: 'RSAPrivateKey.exponent2',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.INTEGER,
            constructed: false,
            capture: 'privateKeyExponent2'
        },
        {
            // coefficient ((inverse of q) mod p)
            name: 'RSAPrivateKey.coefficient',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.INTEGER,
            constructed: false,
            capture: 'privateKeyCoefficient'
        }
    ]
};
// validator for an RSA public key
var rsaPublicKeyValidator = {
    // RSAPublicKey
    name: 'RSAPublicKey',
    tagClass: asn1.Class.UNIVERSAL,
    type: asn1.Type.SEQUENCE,
    constructed: true,
    value: [
        {
            // modulus (n)
            name: 'RSAPublicKey.modulus',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.INTEGER,
            constructed: false,
            capture: 'publicKeyModulus'
        },
        {
            // publicExponent (e)
            name: 'RSAPublicKey.exponent',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.INTEGER,
            constructed: false,
            capture: 'publicKeyExponent'
        }
    ]
};
// validator for an SubjectPublicKeyInfo structure
// Note: Currently only works with an RSA public key
var publicKeyValidator = forge.pki.rsa.publicKeyValidator = {
    name: 'SubjectPublicKeyInfo',
    tagClass: asn1.Class.UNIVERSAL,
    type: asn1.Type.SEQUENCE,
    constructed: true,
    captureAsn1: 'subjectPublicKeyInfo',
    value: [
        {
            name: 'SubjectPublicKeyInfo.AlgorithmIdentifier',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.SEQUENCE,
            constructed: true,
            value: [
                {
                    name: 'AlgorithmIdentifier.algorithm',
                    tagClass: asn1.Class.UNIVERSAL,
                    type: asn1.Type.OID,
                    constructed: false,
                    capture: 'publicKeyOid'
                }
            ]
        },
        {
            // subjectPublicKey
            name: 'SubjectPublicKeyInfo.subjectPublicKey',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.BITSTRING,
            constructed: false,
            value: [
                {
                    // RSAPublicKey
                    name: 'SubjectPublicKeyInfo.subjectPublicKey.RSAPublicKey',
                    tagClass: asn1.Class.UNIVERSAL,
                    type: asn1.Type.SEQUENCE,
                    constructed: true,
                    optional: true,
                    captureAsn1: 'rsaPublicKey'
                }
            ]
        }
    ]
};
/**
 * Wrap digest in DigestInfo object.
 *
 * This function implements EMSA-PKCS1-v1_5-ENCODE as per RFC 3447.
 *
 * DigestInfo ::= SEQUENCE {
 *   digestAlgorithm DigestAlgorithmIdentifier,
 *   digest Digest
 * }
 *
 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
 * Digest ::= OCTET STRING
 *
 * @param md the message digest object with the hash to sign.
 *
 * @return the encoded message (ready for RSA encrytion)
 */ var emsaPkcs1v15encode = function(md) {
    // get the oid for the algorithm
    var oid;
    if (md.algorithm in pki.oids) oid = pki.oids[md.algorithm];
    else {
        var error = new Error('Unknown message digest algorithm.');
        error.algorithm = md.algorithm;
        throw error;
    }
    var oidBytes = asn1.oidToDer(oid).getBytes();
    // create the digest info
    var digestInfo = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []);
    var digestAlgorithm = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []);
    digestAlgorithm.value.push(asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, oidBytes));
    digestAlgorithm.value.push(asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, ''));
    var digest = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, md.digest().getBytes());
    digestInfo.value.push(digestAlgorithm);
    digestInfo.value.push(digest);
    // encode digest info
    return asn1.toDer(digestInfo).getBytes();
};
/**
 * Performs x^c mod n (RSA encryption or decryption operation).
 *
 * @param x the number to raise and mod.
 * @param key the key to use.
 * @param pub true if the key is public, false if private.
 *
 * @return the result of x^c mod n.
 */ var _modPow = function(x, key, pub) {
    if (pub) return x.modPow(key.e, key.n);
    if (!key.p || !key.q) // allow calculation without CRT params (slow)
    return x.modPow(key.d, key.n);
    // pre-compute dP, dQ, and qInv if necessary
    if (!key.dP) key.dP = key.d.mod(key.p.subtract(BigInteger.ONE));
    if (!key.dQ) key.dQ = key.d.mod(key.q.subtract(BigInteger.ONE));
    if (!key.qInv) key.qInv = key.q.modInverse(key.p);
    /* Chinese remainder theorem (CRT) states:

    Suppose n1, n2, ..., nk are positive integers which are pairwise
    coprime (n1 and n2 have no common factors other than 1). For any
    integers x1, x2, ..., xk there exists an integer x solving the
    system of simultaneous congruences (where ~= means modularly
    congruent so a ~= b mod n means a mod n = b mod n):

    x ~= x1 mod n1
    x ~= x2 mod n2
    ...
    x ~= xk mod nk

    This system of congruences has a single simultaneous solution x
    between 0 and n - 1. Furthermore, each xk solution and x itself
    is congruent modulo the product n = n1*n2*...*nk.
    So x1 mod n = x2 mod n = xk mod n = x mod n.

    The single simultaneous solution x can be solved with the following
    equation:

    x = sum(xi*ri*si) mod n where ri = n/ni and si = ri^-1 mod ni.

    Where x is less than n, xi = x mod ni.

    For RSA we are only concerned with k = 2. The modulus n = pq, where
    p and q are coprime. The RSA decryption algorithm is:

    y = x^d mod n

    Given the above:

    x1 = x^d mod p
    r1 = n/p = q
    s1 = q^-1 mod p
    x2 = x^d mod q
    r2 = n/q = p
    s2 = p^-1 mod q

    So y = (x1r1s1 + x2r2s2) mod n
         = ((x^d mod p)q(q^-1 mod p) + (x^d mod q)p(p^-1 mod q)) mod n

    According to Fermat's Little Theorem, if the modulus P is prime,
    for any integer A not evenly divisible by P, A^(P-1) ~= 1 mod P.
    Since A is not divisible by P it follows that if:
    N ~= M mod (P - 1), then A^N mod P = A^M mod P. Therefore:

    A^N mod P = A^(M mod (P - 1)) mod P. (The latter takes less effort
    to calculate). In order to calculate x^d mod p more quickly the
    exponent d mod (p - 1) is stored in the RSA private key (the same
    is done for x^d mod q). These values are referred to as dP and dQ
    respectively. Therefore we now have:

    y = ((x^dP mod p)q(q^-1 mod p) + (x^dQ mod q)p(p^-1 mod q)) mod n

    Since we'll be reducing x^dP by modulo p (same for q) we can also
    reduce x by p (and q respectively) before hand. Therefore, let

    xp = ((x mod p)^dP mod p), and
    xq = ((x mod q)^dQ mod q), yielding:

    y = (xp*q*(q^-1 mod p) + xq*p*(p^-1 mod q)) mod n

    This can be further reduced to a simple algorithm that only
    requires 1 inverse (the q inverse is used) to be used and stored.
    The algorithm is called Garner's algorithm. If qInv is the
    inverse of q, we simply calculate:

    y = (qInv*(xp - xq) mod p) * q + xq

    However, there are two further complications. First, we need to
    ensure that xp > xq to prevent signed BigIntegers from being used
    so we add p until this is true (since we will be mod'ing with
    p anyway). Then, there is a known timing attack on algorithms
    using the CRT. To mitigate this risk, "cryptographic blinding"
    should be used. This requires simply generating a random number r
    between 0 and n-1 and its inverse and multiplying x by r^e before
    calculating y and then multiplying y by r^-1 afterwards. Note that
    r must be coprime with n (gcd(r, n) === 1) in order to have an
    inverse.
  */ // cryptographic blinding
    var r;
    do r = new BigInteger(forge.util.bytesToHex(forge.random.getBytes(key.n.bitLength() / 8)), 16);
    while (r.compareTo(key.n) >= 0 || !r.gcd(key.n).equals(BigInteger.ONE))
    x = x.multiply(r.modPow(key.e, key.n)).mod(key.n);
    // calculate xp and xq
    var xp = x.mod(key.p).modPow(key.dP, key.p);
    var xq = x.mod(key.q).modPow(key.dQ, key.q);
    // xp must be larger than xq to avoid signed bit usage
    while(xp.compareTo(xq) < 0)xp = xp.add(key.p);
    // do last step
    var y = xp.subtract(xq).multiply(key.qInv).mod(key.p).multiply(key.q).add(xq);
    // remove effect of random for cryptographic blinding
    y = y.multiply(r.modInverse(key.n)).mod(key.n);
    return y;
};
/**
 * NOTE: THIS METHOD IS DEPRECATED, use 'sign' on a private key object or
 * 'encrypt' on a public key object instead.
 *
 * Performs RSA encryption.
 *
 * The parameter bt controls whether to put padding bytes before the
 * message passed in. Set bt to either true or false to disable padding
 * completely (in order to handle e.g. EMSA-PSS encoding seperately before),
 * signaling whether the encryption operation is a public key operation
 * (i.e. encrypting data) or not, i.e. private key operation (data signing).
 *
 * For PKCS#1 v1.5 padding pass in the block type to use, i.e. either 0x01
 * (for signing) or 0x02 (for encryption). The key operation mode (private
 * or public) is derived from this flag in that case).
 *
 * @param m the message to encrypt as a byte string.
 * @param key the RSA key to use.
 * @param bt for PKCS#1 v1.5 padding, the block type to use
 *   (0x01 for private key, 0x02 for public),
 *   to disable padding: true = public key, false = private key.
 *
 * @return the encrypted bytes as a string.
 */ pki.rsa.encrypt = function(m, key, bt) {
    var pub = bt;
    var eb;
    // get the length of the modulus in bytes
    var k = Math.ceil(key.n.bitLength() / 8);
    if (bt !== false && bt !== true) {
        // legacy, default to PKCS#1 v1.5 padding
        pub = bt === 2;
        eb = _encodePkcs1_v1_5(m, key, bt);
    } else {
        eb = forge.util.createBuffer();
        eb.putBytes(m);
    }
    // load encryption block as big integer 'x'
    // FIXME: hex conversion inefficient, get BigInteger w/byte strings
    var x = new BigInteger(eb.toHex(), 16);
    // do RSA encryption
    var y = _modPow(x, key, pub);
    // convert y into the encrypted data byte string, if y is shorter in
    // bytes than k, then prepend zero bytes to fill up ed
    // FIXME: hex conversion inefficient, get BigInteger w/byte strings
    var yhex = y.toString(16);
    var ed = forge.util.createBuffer();
    var zeros = k - Math.ceil(yhex.length / 2);
    while(zeros > 0){
        ed.putByte(0);
        --zeros;
    }
    ed.putBytes(forge.util.hexToBytes(yhex));
    return ed.getBytes();
};
/**
 * NOTE: THIS METHOD IS DEPRECATED, use 'decrypt' on a private key object or
 * 'verify' on a public key object instead.
 *
 * Performs RSA decryption.
 *
 * The parameter ml controls whether to apply PKCS#1 v1.5 padding
 * or not.  Set ml = false to disable padding removal completely
 * (in order to handle e.g. EMSA-PSS later on) and simply pass back
 * the RSA encryption block.
 *
 * @param ed the encrypted data to decrypt in as a byte string.
 * @param key the RSA key to use.
 * @param pub true for a public key operation, false for private.
 * @param ml the message length, if known, false to disable padding.
 *
 * @return the decrypted message as a byte string.
 */ pki.rsa.decrypt = function(ed, key, pub, ml) {
    // get the length of the modulus in bytes
    var k = Math.ceil(key.n.bitLength() / 8);
    // error if the length of the encrypted data ED is not k
    if (ed.length !== k) {
        var error = new Error('Encrypted message length is invalid.');
        error.length = ed.length;
        error.expected = k;
        throw error;
    }
    // convert encrypted data into a big integer
    // FIXME: hex conversion inefficient, get BigInteger w/byte strings
    var y = new BigInteger(forge.util.createBuffer(ed).toHex(), 16);
    // y must be less than the modulus or it wasn't the result of
    // a previous mod operation (encryption) using that modulus
    if (y.compareTo(key.n) >= 0) throw new Error('Encrypted message is invalid.');
    // do RSA decryption
    var x = _modPow(y, key, pub);
    // create the encryption block, if x is shorter in bytes than k, then
    // prepend zero bytes to fill up eb
    // FIXME: hex conversion inefficient, get BigInteger w/byte strings
    var xhex = x.toString(16);
    var eb = forge.util.createBuffer();
    var zeros = k - Math.ceil(xhex.length / 2);
    while(zeros > 0){
        eb.putByte(0);
        --zeros;
    }
    eb.putBytes(forge.util.hexToBytes(xhex));
    if (ml !== false) // legacy, default to PKCS#1 v1.5 padding
    return _decodePkcs1_v1_5(eb.getBytes(), key, pub);
    // return message
    return eb.getBytes();
};
/**
 * Creates an RSA key-pair generation state object. It is used to allow
 * key-generation to be performed in steps. It also allows for a UI to
 * display progress updates.
 *
 * @param bits the size for the private key in bits, defaults to 2048.
 * @param e the public exponent to use, defaults to 65537 (0x10001).
 * @param [options] the options to use.
 *          prng a custom crypto-secure pseudo-random number generator to use,
 *            that must define "getBytesSync".
 *          algorithm the algorithm to use (default: 'PRIMEINC').
 *
 * @return the state object to use to generate the key-pair.
 */ pki.rsa.createKeyPairGenerationState = function(bits, e, options) {
    // TODO: migrate step-based prime generation code to forge.prime
    // set default bits
    if (typeof bits === 'string') bits = parseInt(bits, 10);
    bits = bits || 2048;
    // create prng with api that matches BigInteger secure random
    options = options || {
    };
    var prng = options.prng || forge.random;
    var rng = {
        // x is an array to fill with bytes
        nextBytes: function(x) {
            var b = prng.getBytesSync(x.length);
            for(var i = 0; i < x.length; ++i)x[i] = b.charCodeAt(i);
        }
    };
    var algorithm = options.algorithm || 'PRIMEINC';
    // create PRIMEINC algorithm state
    var rval;
    if (algorithm === 'PRIMEINC') {
        rval = {
            algorithm: algorithm,
            state: 0,
            bits: bits,
            rng: rng,
            eInt: e || 65537,
            e: new BigInteger(null),
            p: null,
            q: null,
            qBits: bits >> 1,
            pBits: bits - (bits >> 1),
            pqState: 0,
            num: null,
            keys: null
        };
        rval.e.fromInt(rval.eInt);
    } else throw new Error('Invalid key generation algorithm: ' + algorithm);
    return rval;
};
/**
 * Attempts to runs the key-generation algorithm for at most n seconds
 * (approximately) using the given state. When key-generation has completed,
 * the keys will be stored in state.keys.
 *
 * To use this function to update a UI while generating a key or to prevent
 * causing browser lockups/warnings, set "n" to a value other than 0. A
 * simple pattern for generating a key and showing a progress indicator is:
 *
 * var state = pki.rsa.createKeyPairGenerationState(2048);
 * var step = function() {
 *   // step key-generation, run algorithm for 100 ms, repeat
 *   if(!forge.pki.rsa.stepKeyPairGenerationState(state, 100)) {
 *     setTimeout(step, 1);
 *   } else {
 *     // key-generation complete
 *     // TODO: turn off progress indicator here
 *     // TODO: use the generated key-pair in "state.keys"
 *   }
 * };
 * // TODO: turn on progress indicator here
 * setTimeout(step, 0);
 *
 * @param state the state to use.
 * @param n the maximum number of milliseconds to run the algorithm for, 0
 *          to run the algorithm to completion.
 *
 * @return true if the key-generation completed, false if not.
 */ pki.rsa.stepKeyPairGenerationState = function(state, n) {
    // set default algorithm if not set
    if (!('algorithm' in state)) state.algorithm = 'PRIMEINC';
    // TODO: migrate step-based prime generation code to forge.prime
    // TODO: abstract as PRIMEINC algorithm
    // do key generation (based on Tom Wu's rsa.js, see jsbn.js license)
    // with some minor optimizations and designed to run in steps
    // local state vars
    var THIRTY = new BigInteger(null);
    THIRTY.fromInt(30);
    var deltaIdx = 0;
    var op_or = function(x, y) {
        return x | y;
    };
    // keep stepping until time limit is reached or done
    var t1 = +new Date();
    var t2;
    var total = 0;
    while(state.keys === null && (n <= 0 || total < n)){
        // generate p or q
        if (state.state === 0) {
            /* Note: All primes are of the form:

        30k+i, for i < 30 and gcd(30, i)=1, where there are 8 values for i

        When we generate a random number, we always align it at 30k + 1. Each
        time the number is determined not to be prime we add to get to the
        next 'i', eg: if the number was at 30k + 1 we add 6. */ var bits = state.p === null ? state.pBits : state.qBits;
            var bits1 = bits - 1;
            // get a random number
            if (state.pqState === 0) {
                state.num = new BigInteger(bits, state.rng);
                // force MSB set
                if (!state.num.testBit(bits1)) state.num.bitwiseTo(BigInteger.ONE.shiftLeft(bits1), op_or, state.num);
                // align number on 30k+1 boundary
                state.num.dAddOffset(31 - state.num.mod(THIRTY).byteValue(), 0);
                deltaIdx = 0;
                ++state.pqState;
            } else if (state.pqState === 1) {
                // try to make the number a prime
                if (state.num.bitLength() > bits) // overflow, try again
                state.pqState = 0;
                else if (state.num.isProbablePrime(_getMillerRabinTests(state.num.bitLength()))) ++state.pqState;
                else // get next potential prime
                state.num.dAddOffset(GCD_30_DELTA[(deltaIdx++) % 8], 0);
            } else if (state.pqState === 2) // ensure number is coprime with e
            state.pqState = state.num.subtract(BigInteger.ONE).gcd(state.e).compareTo(BigInteger.ONE) === 0 ? 3 : 0;
            else if (state.pqState === 3) {
                // store p or q
                state.pqState = 0;
                if (state.p === null) state.p = state.num;
                else state.q = state.num;
                // advance state if both p and q are ready
                if (state.p !== null && state.q !== null) ++state.state;
                state.num = null;
            }
        } else if (state.state === 1) {
            // ensure p is larger than q (swap them if not)
            if (state.p.compareTo(state.q) < 0) {
                state.num = state.p;
                state.p = state.q;
                state.q = state.num;
            }
            ++state.state;
        } else if (state.state === 2) {
            // compute phi: (p - 1)(q - 1) (Euler's totient function)
            state.p1 = state.p.subtract(BigInteger.ONE);
            state.q1 = state.q.subtract(BigInteger.ONE);
            state.phi = state.p1.multiply(state.q1);
            ++state.state;
        } else if (state.state === 3) {
            // ensure e and phi are coprime
            if (state.phi.gcd(state.e).compareTo(BigInteger.ONE) === 0) // phi and e are coprime, advance
            ++state.state;
            else {
                // phi and e aren't coprime, so generate a new p and q
                state.p = null;
                state.q = null;
                state.state = 0;
            }
        } else if (state.state === 4) {
            // create n, ensure n is has the right number of bits
            state.n = state.p.multiply(state.q);
            // ensure n is right number of bits
            if (state.n.bitLength() === state.bits) // success, advance
            ++state.state;
            else {
                // failed, get new q
                state.q = null;
                state.state = 0;
            }
        } else if (state.state === 5) {
            // set keys
            var d = state.e.modInverse(state.phi);
            state.keys = {
                privateKey: pki.rsa.setPrivateKey(state.n, state.e, d, state.p, state.q, d.mod(state.p1), d.mod(state.q1), state.q.modInverse(state.p)),
                publicKey: pki.rsa.setPublicKey(state.n, state.e)
            };
        }
        // update timing
        t2 = +new Date();
        total += t2 - t1;
        t1 = t2;
    }
    return state.keys !== null;
};
/**
 * Generates an RSA public-private key pair in a single call.
 *
 * To generate a key-pair in steps (to allow for progress updates and to
 * prevent blocking or warnings in slow browsers) then use the key-pair
 * generation state functions.
 *
 * To generate a key-pair asynchronously (either through web-workers, if
 * available, or by breaking up the work on the main thread), pass a
 * callback function.
 *
 * @param [bits] the size for the private key in bits, defaults to 2048.
 * @param [e] the public exponent to use, defaults to 65537.
 * @param [options] options for key-pair generation, if given then 'bits'
 *            and 'e' must *not* be given:
 *          bits the size for the private key in bits, (default: 2048).
 *          e the public exponent to use, (default: 65537 (0x10001)).
 *          workerScript the worker script URL.
 *          workers the number of web workers (if supported) to use,
 *            (default: 2).
 *          workLoad the size of the work load, ie: number of possible prime
 *            numbers for each web worker to check per work assignment,
 *            (default: 100).
 *          prng a custom crypto-secure pseudo-random number generator to use,
 *            that must define "getBytesSync". Disables use of native APIs.
 *          algorithm the algorithm to use (default: 'PRIMEINC').
 * @param [callback(err, keypair)] called once the operation completes.
 *
 * @return an object with privateKey and publicKey properties.
 */ pki.rsa.generateKeyPair = function(bits, e1, options, callback) {
    // (bits), (options), (callback)
    if (arguments.length === 1) {
        if (typeof bits === 'object') {
            options = bits;
            bits = undefined;
        } else if (typeof bits === 'function') {
            callback = bits;
            bits = undefined;
        }
    } else if (arguments.length === 2) {
        // (bits, e), (bits, options), (bits, callback), (options, callback)
        if (typeof bits === 'number') {
            if (typeof e1 === 'function') {
                callback = e1;
                e1 = undefined;
            } else if (typeof e1 !== 'number') {
                options = e1;
                e1 = undefined;
            }
        } else {
            options = bits;
            callback = e1;
            bits = undefined;
            e1 = undefined;
        }
    } else if (arguments.length === 3) {
        // (bits, e, options), (bits, e, callback), (bits, options, callback)
        if (typeof e1 === 'number') {
            if (typeof options === 'function') {
                callback = options;
                options = undefined;
            }
        } else {
            callback = options;
            options = e1;
            e1 = undefined;
        }
    }
    options = options || {
    };
    if (bits === undefined) bits = options.bits || 2048;
    if (e1 === undefined) e1 = options.e || 65537;
    // use native code if permitted, available, and parameters are acceptable
    if (!forge.options.usePureJavaScript && !options.prng && bits >= 256 && bits <= 16384 && (e1 === 65537 || e1 === 3)) {
        if (callback) {
            // try native async
            if (_detectNodeCrypto('generateKeyPair')) return _crypto.generateKeyPair('rsa', {
                modulusLength: bits,
                publicExponent: e1,
                publicKeyEncoding: {
                    type: 'spki',
                    format: 'pem'
                },
                privateKeyEncoding: {
                    type: 'pkcs8',
                    format: 'pem'
                }
            }, function(err, pub, priv) {
                if (err) return callback(err);
                callback(null, {
                    privateKey: pki.privateKeyFromPem(priv),
                    publicKey: pki.publicKeyFromPem(pub)
                });
            });
            if (_detectSubtleCrypto('generateKey') && _detectSubtleCrypto('exportKey')) // use standard native generateKey
            return util.globalScope.crypto.subtle.generateKey({
                name: 'RSASSA-PKCS1-v1_5',
                modulusLength: bits,
                publicExponent: _intToUint8Array(e1),
                hash: {
                    name: 'SHA-256'
                }
            }, true, [
                'sign',
                'verify'
            ]).then(function(pair) {
                return util.globalScope.crypto.subtle.exportKey('pkcs8', pair.privateKey);
            // avoiding catch(function(err) {...}) to support IE <= 8
            }).then(undefined, function(err) {
                callback(err);
            }).then(function(pkcs8) {
                if (pkcs8) {
                    var privateKey = pki.privateKeyFromAsn1(asn1.fromDer(forge.util.createBuffer(pkcs8)));
                    callback(null, {
                        privateKey: privateKey,
                        publicKey: pki.setRsaPublicKey(privateKey.n, privateKey.e)
                    });
                }
            });
            if (_detectSubtleMsCrypto('generateKey') && _detectSubtleMsCrypto('exportKey')) {
                var genOp = util.globalScope.msCrypto.subtle.generateKey({
                    name: 'RSASSA-PKCS1-v1_5',
                    modulusLength: bits,
                    publicExponent: _intToUint8Array(e1),
                    hash: {
                        name: 'SHA-256'
                    }
                }, true, [
                    'sign',
                    'verify'
                ]);
                genOp.oncomplete = function(e2) {
                    var pair = e2.target.result;
                    var exportOp = util.globalScope.msCrypto.subtle.exportKey('pkcs8', pair.privateKey);
                    exportOp.oncomplete = function(e) {
                        var pkcs8 = e.target.result;
                        var privateKey = pki.privateKeyFromAsn1(asn1.fromDer(forge.util.createBuffer(pkcs8)));
                        callback(null, {
                            privateKey: privateKey,
                            publicKey: pki.setRsaPublicKey(privateKey.n, privateKey.e)
                        });
                    };
                    exportOp.onerror = function(err) {
                        callback(err);
                    };
                };
                genOp.onerror = function(err) {
                    callback(err);
                };
                return;
            }
        } else // try native sync
        if (_detectNodeCrypto('generateKeyPairSync')) {
            var keypair = _crypto.generateKeyPairSync('rsa', {
                modulusLength: bits,
                publicExponent: e1,
                publicKeyEncoding: {
                    type: 'spki',
                    format: 'pem'
                },
                privateKeyEncoding: {
                    type: 'pkcs8',
                    format: 'pem'
                }
            });
            return {
                privateKey: pki.privateKeyFromPem(keypair.privateKey),
                publicKey: pki.publicKeyFromPem(keypair.publicKey)
            };
        }
    }
    // use JavaScript implementation
    var state = pki.rsa.createKeyPairGenerationState(bits, e1, options);
    if (!callback) {
        pki.rsa.stepKeyPairGenerationState(state, 0);
        return state.keys;
    }
    _generateKeyPair(state, options, callback);
};
/**
 * Sets an RSA public key from BigIntegers modulus and exponent.
 *
 * @param n the modulus.
 * @param e the exponent.
 *
 * @return the public key.
 */ pki.setRsaPublicKey = pki.rsa.setPublicKey = function(n, e3) {
    var key1 = {
        n: n,
        e: e3
    };
    /**
   * Encrypts the given data with this public key. Newer applications
   * should use the 'RSA-OAEP' decryption scheme, 'RSAES-PKCS1-V1_5' is for
   * legacy applications.
   *
   * @param data the byte string to encrypt.
   * @param scheme the encryption scheme to use:
   *          'RSAES-PKCS1-V1_5' (default),
   *          'RSA-OAEP',
   *          'RAW', 'NONE', or null to perform raw RSA encryption,
   *          an object with an 'encode' property set to a function
   *          with the signature 'function(data, key)' that returns
   *          a binary-encoded string representing the encoded data.
   * @param schemeOptions any scheme-specific options.
   *
   * @return the encrypted byte string.
   */ key1.encrypt = function(data, scheme, schemeOptions) {
        if (typeof scheme === 'string') scheme = scheme.toUpperCase();
        else if (scheme === undefined) scheme = 'RSAES-PKCS1-V1_5';
        if (scheme === 'RSAES-PKCS1-V1_5') scheme = {
            encode: function(m, key, pub) {
                return _encodePkcs1_v1_5(m, key, 2).getBytes();
            }
        };
        else if (scheme === 'RSA-OAEP' || scheme === 'RSAES-OAEP') scheme = {
            encode: function(m, key) {
                return forge.pkcs1.encode_rsa_oaep(key, m, schemeOptions);
            }
        };
        else if ([
            'RAW',
            'NONE',
            'NULL',
            null
        ].indexOf(scheme) !== -1) scheme = {
            encode: function(e) {
                return e;
            }
        };
        else if (typeof scheme === 'string') throw new Error('Unsupported encryption scheme: "' + scheme + '".');
        // do scheme-based encoding then rsa encryption
        var e4 = scheme.encode(data, key1, true);
        return pki.rsa.encrypt(e4, key1, true);
    };
    /**
   * Verifies the given signature against the given digest.
   *
   * PKCS#1 supports multiple (currently two) signature schemes:
   * RSASSA-PKCS1-V1_5 and RSASSA-PSS.
   *
   * By default this implementation uses the "old scheme", i.e.
   * RSASSA-PKCS1-V1_5, in which case once RSA-decrypted, the
   * signature is an OCTET STRING that holds a DigestInfo.
   *
   * DigestInfo ::= SEQUENCE {
   *   digestAlgorithm DigestAlgorithmIdentifier,
   *   digest Digest
   * }
   * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
   * Digest ::= OCTET STRING
   *
   * To perform PSS signature verification, provide an instance
   * of Forge PSS object as the scheme parameter.
   *
   * @param digest the message digest hash to compare against the signature,
   *          as a binary-encoded string.
   * @param signature the signature to verify, as a binary-encoded string.
   * @param scheme signature verification scheme to use:
   *          'RSASSA-PKCS1-V1_5' or undefined for RSASSA PKCS#1 v1.5,
   *          a Forge PSS object for RSASSA-PSS,
   *          'NONE' or null for none, DigestInfo will not be expected, but
   *            PKCS#1 v1.5 padding will still be used.
   *
   * @return true if the signature was verified, false if not.
   */ key1.verify = function(digest1, signature, scheme) {
        if (typeof scheme === 'string') scheme = scheme.toUpperCase();
        else if (scheme === undefined) scheme = 'RSASSA-PKCS1-V1_5';
        if (scheme === 'RSASSA-PKCS1-V1_5') scheme = {
            verify: function(digest, d) {
                // remove padding
                d = _decodePkcs1_v1_5(d, key1, true);
                // d is ASN.1 BER-encoded DigestInfo
                var obj = asn1.fromDer(d);
                // compare the given digest to the decrypted one
                return digest === obj.value[1].value;
            }
        };
        else if (scheme === 'NONE' || scheme === 'NULL' || scheme === null) scheme = {
            verify: function(digest, d) {
                // remove padding
                d = _decodePkcs1_v1_5(d, key1, true);
                return digest === d;
            }
        };
        // do rsa decryption w/o any decoding, then verify -- which does decoding
        var d1 = pki.rsa.decrypt(signature, key1, true, false);
        return scheme.verify(digest1, d1, key1.n.bitLength());
    };
    return key1;
};
/**
 * Sets an RSA private key from BigIntegers modulus, exponent, primes,
 * prime exponents, and modular multiplicative inverse.
 *
 * @param n the modulus.
 * @param e the public exponent.
 * @param d the private exponent ((inverse of e) mod n).
 * @param p the first prime.
 * @param q the second prime.
 * @param dP exponent1 (d mod (p-1)).
 * @param dQ exponent2 (d mod (q-1)).
 * @param qInv ((inverse of q) mod p)
 *
 * @return the private key.
 */ pki.setRsaPrivateKey = pki.rsa.setPrivateKey = function(n, e, d2, p, q, dP, dQ, qInv) {
    var key2 = {
        n: n,
        e: e,
        d: d2,
        p: p,
        q: q,
        dP: dP,
        dQ: dQ,
        qInv: qInv
    };
    /**
   * Decrypts the given data with this private key. The decryption scheme
   * must match the one used to encrypt the data.
   *
   * @param data the byte string to decrypt.
   * @param scheme the decryption scheme to use:
   *          'RSAES-PKCS1-V1_5' (default),
   *          'RSA-OAEP',
   *          'RAW', 'NONE', or null to perform raw RSA decryption.
   * @param schemeOptions any scheme-specific options.
   *
   * @return the decrypted byte string.
   */ key2.decrypt = function(data, scheme, schemeOptions) {
        if (typeof scheme === 'string') scheme = scheme.toUpperCase();
        else if (scheme === undefined) scheme = 'RSAES-PKCS1-V1_5';
        // do rsa decryption w/o any decoding
        var d3 = pki.rsa.decrypt(data, key2, false, false);
        if (scheme === 'RSAES-PKCS1-V1_5') scheme = {
            decode: _decodePkcs1_v1_5
        };
        else if (scheme === 'RSA-OAEP' || scheme === 'RSAES-OAEP') scheme = {
            decode: function(d, key) {
                return forge.pkcs1.decode_rsa_oaep(key, d, schemeOptions);
            }
        };
        else if ([
            'RAW',
            'NONE',
            'NULL',
            null
        ].indexOf(scheme) !== -1) scheme = {
            decode: function(d) {
                return d;
            }
        };
        else throw new Error('Unsupported encryption scheme: "' + scheme + '".');
        // decode according to scheme
        return scheme.decode(d3, key2, false);
    };
    /**
   * Signs the given digest, producing a signature.
   *
   * PKCS#1 supports multiple (currently two) signature schemes:
   * RSASSA-PKCS1-V1_5 and RSASSA-PSS.
   *
   * By default this implementation uses the "old scheme", i.e.
   * RSASSA-PKCS1-V1_5. In order to generate a PSS signature, provide
   * an instance of Forge PSS object as the scheme parameter.
   *
   * @param md the message digest object with the hash to sign.
   * @param scheme the signature scheme to use:
   *          'RSASSA-PKCS1-V1_5' or undefined for RSASSA PKCS#1 v1.5,
   *          a Forge PSS object for RSASSA-PSS,
   *          'NONE' or null for none, DigestInfo will not be used but
   *            PKCS#1 v1.5 padding will still be used.
   *
   * @return the signature as a byte string.
   */ key2.sign = function(md, scheme) {
        /* Note: The internal implementation of RSA operations is being
      transitioned away from a PKCS#1 v1.5 hard-coded scheme. Some legacy
      code like the use of an encoding block identifier 'bt' will eventually
      be removed. */ // private key operation
        var bt = false;
        if (typeof scheme === 'string') scheme = scheme.toUpperCase();
        if (scheme === undefined || scheme === 'RSASSA-PKCS1-V1_5') {
            scheme = {
                encode: emsaPkcs1v15encode
            };
            bt = 1;
        } else if (scheme === 'NONE' || scheme === 'NULL' || scheme === null) {
            scheme = {
                encode: function() {
                    return md;
                }
            };
            bt = 1;
        }
        // encode and then encrypt
        var d = scheme.encode(md, key2.n.bitLength());
        return pki.rsa.encrypt(d, key2, bt);
    };
    return key2;
};
/**
 * Wraps an RSAPrivateKey ASN.1 object in an ASN.1 PrivateKeyInfo object.
 *
 * @param rsaKey the ASN.1 RSAPrivateKey.
 *
 * @return the ASN.1 PrivateKeyInfo.
 */ pki.wrapRsaPrivateKey = function(rsaKey) {
    // PrivateKeyInfo
    return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
        // version (0)
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, asn1.integerToDer(0).getBytes()),
        // privateKeyAlgorithm
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
            asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(pki.oids.rsaEncryption).getBytes()),
            asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '')
        ]),
        // PrivateKey
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, asn1.toDer(rsaKey).getBytes())
    ]);
};
/**
 * Converts a private key from an ASN.1 object.
 *
 * @param obj the ASN.1 representation of a PrivateKeyInfo containing an
 *          RSAPrivateKey or an RSAPrivateKey.
 *
 * @return the private key.
 */ pki.privateKeyFromAsn1 = function(obj) {
    // get PrivateKeyInfo
    var capture = {
    };
    var errors = [];
    if (asn1.validate(obj, privateKeyValidator, capture, errors)) obj = asn1.fromDer(forge.util.createBuffer(capture.privateKey));
    // get RSAPrivateKey
    capture = {
    };
    errors = [];
    if (!asn1.validate(obj, rsaPrivateKeyValidator, capture, errors)) {
        var error = new Error("Cannot read private key. ASN.1 object does not contain an RSAPrivateKey.");
        error.errors = errors;
        throw error;
    }
    // Note: Version is currently ignored.
    // capture.privateKeyVersion
    // FIXME: inefficient, get a BigInteger that uses byte strings
    var n, e, d, p, q, dP, dQ, qInv;
    n = forge.util.createBuffer(capture.privateKeyModulus).toHex();
    e = forge.util.createBuffer(capture.privateKeyPublicExponent).toHex();
    d = forge.util.createBuffer(capture.privateKeyPrivateExponent).toHex();
    p = forge.util.createBuffer(capture.privateKeyPrime1).toHex();
    q = forge.util.createBuffer(capture.privateKeyPrime2).toHex();
    dP = forge.util.createBuffer(capture.privateKeyExponent1).toHex();
    dQ = forge.util.createBuffer(capture.privateKeyExponent2).toHex();
    qInv = forge.util.createBuffer(capture.privateKeyCoefficient).toHex();
    // set private key
    return pki.setRsaPrivateKey(new BigInteger(n, 16), new BigInteger(e, 16), new BigInteger(d, 16), new BigInteger(p, 16), new BigInteger(q, 16), new BigInteger(dP, 16), new BigInteger(dQ, 16), new BigInteger(qInv, 16));
};
/**
 * Converts a private key to an ASN.1 RSAPrivateKey.
 *
 * @param key the private key.
 *
 * @return the ASN.1 representation of an RSAPrivateKey.
 */ pki.privateKeyToAsn1 = pki.privateKeyToRSAPrivateKey = function(key) {
    // RSAPrivateKey
    return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
        // version (0 = only 2 primes, 1 multiple primes)
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, asn1.integerToDer(0).getBytes()),
        // modulus (n)
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, _bnToBytes(key.n)),
        // publicExponent (e)
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, _bnToBytes(key.e)),
        // privateExponent (d)
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, _bnToBytes(key.d)),
        // privateKeyPrime1 (p)
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, _bnToBytes(key.p)),
        // privateKeyPrime2 (q)
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, _bnToBytes(key.q)),
        // privateKeyExponent1 (dP)
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, _bnToBytes(key.dP)),
        // privateKeyExponent2 (dQ)
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, _bnToBytes(key.dQ)),
        // coefficient (qInv)
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, _bnToBytes(key.qInv))
    ]);
};
/**
 * Converts a public key from an ASN.1 SubjectPublicKeyInfo or RSAPublicKey.
 *
 * @param obj the asn1 representation of a SubjectPublicKeyInfo or RSAPublicKey.
 *
 * @return the public key.
 */ pki.publicKeyFromAsn1 = function(obj) {
    // get SubjectPublicKeyInfo
    var capture = {
    };
    var errors = [];
    if (asn1.validate(obj, publicKeyValidator, capture, errors)) {
        // get oid
        var oid = asn1.derToOid(capture.publicKeyOid);
        if (oid !== pki.oids.rsaEncryption) {
            var error = new Error('Cannot read public key. Unknown OID.');
            error.oid = oid;
            throw error;
        }
        obj = capture.rsaPublicKey;
    }
    // get RSA params
    errors = [];
    if (!asn1.validate(obj, rsaPublicKeyValidator, capture, errors)) {
        var error = new Error("Cannot read public key. ASN.1 object does not contain an RSAPublicKey.");
        error.errors = errors;
        throw error;
    }
    // FIXME: inefficient, get a BigInteger that uses byte strings
    var n = forge.util.createBuffer(capture.publicKeyModulus).toHex();
    var e = forge.util.createBuffer(capture.publicKeyExponent).toHex();
    // set public key
    return pki.setRsaPublicKey(new BigInteger(n, 16), new BigInteger(e, 16));
};
/**
 * Converts a public key to an ASN.1 SubjectPublicKeyInfo.
 *
 * @param key the public key.
 *
 * @return the asn1 representation of a SubjectPublicKeyInfo.
 */ pki.publicKeyToAsn1 = pki.publicKeyToSubjectPublicKeyInfo = function(key) {
    // SubjectPublicKeyInfo
    return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
        // AlgorithmIdentifier
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
            // algorithm
            asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(pki.oids.rsaEncryption).getBytes()),
            // parameters (null)
            asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '')
        ]),
        // subjectPublicKey
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.BITSTRING, false, [
            pki.publicKeyToRSAPublicKey(key)
        ])
    ]);
};
/**
 * Converts a public key to an ASN.1 RSAPublicKey.
 *
 * @param key the public key.
 *
 * @return the asn1 representation of a RSAPublicKey.
 */ pki.publicKeyToRSAPublicKey = function(key) {
    // RSAPublicKey
    return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
        // modulus (n)
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, _bnToBytes(key.n)),
        // publicExponent (e)
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, _bnToBytes(key.e))
    ]);
};
/**
 * Encodes a message using PKCS#1 v1.5 padding.
 *
 * @param m the message to encode.
 * @param key the RSA key to use.
 * @param bt the block type to use, i.e. either 0x01 (for signing) or 0x02
 *          (for encryption).
 *
 * @return the padded byte buffer.
 */ function _encodePkcs1_v1_5(m, key, bt) {
    var eb = forge.util.createBuffer();
    // get the length of the modulus in bytes
    var k = Math.ceil(key.n.bitLength() / 8);
    /* use PKCS#1 v1.5 padding */ if (m.length > k - 11) {
        var error = new Error('Message is too long for PKCS#1 v1.5 padding.');
        error.length = m.length;
        error.max = k - 11;
        throw error;
    }
    /* A block type BT, a padding string PS, and the data D shall be
    formatted into an octet string EB, the encryption block:

    EB = 00 || BT || PS || 00 || D

    The block type BT shall be a single octet indicating the structure of
    the encryption block. For this version of the document it shall have
    value 00, 01, or 02. For a private-key operation, the block type
    shall be 00 or 01. For a public-key operation, it shall be 02.

    The padding string PS shall consist of k-3-||D|| octets. For block
    type 00, the octets shall have value 00; for block type 01, they
    shall have value FF; and for block type 02, they shall be
    pseudorandomly generated and nonzero. This makes the length of the
    encryption block EB equal to k. */ // build the encryption block
    eb.putByte(0);
    eb.putByte(bt);
    // create the padding
    var padNum = k - 3 - m.length;
    var padByte;
    // private key op
    if (bt === 0 || bt === 1) {
        padByte = bt === 0 ? 0 : 255;
        for(var i = 0; i < padNum; ++i)eb.putByte(padByte);
    } else // public key op
    // pad with random non-zero values
    while(padNum > 0){
        var numZeros = 0;
        var padBytes = forge.random.getBytes(padNum);
        for(var i = 0; i < padNum; ++i){
            padByte = padBytes.charCodeAt(i);
            if (padByte === 0) ++numZeros;
            else eb.putByte(padByte);
        }
        padNum = numZeros;
    }
    // zero followed by message
    eb.putByte(0);
    eb.putBytes(m);
    return eb;
}
/**
 * Decodes a message using PKCS#1 v1.5 padding.
 *
 * @param em the message to decode.
 * @param key the RSA key to use.
 * @param pub true if the key is a public key, false if it is private.
 * @param ml the message length, if specified.
 *
 * @return the decoded bytes.
 */ function _decodePkcs1_v1_5(em, key, pub, ml) {
    // get the length of the modulus in bytes
    var k = Math.ceil(key.n.bitLength() / 8);
    /* It is an error if any of the following conditions occurs:

    1. The encryption block EB cannot be parsed unambiguously.
    2. The padding string PS consists of fewer than eight octets
      or is inconsisent with the block type BT.
    3. The decryption process is a public-key operation and the block
      type BT is not 00 or 01, or the decryption process is a
      private-key operation and the block type is not 02.
   */ // parse the encryption block
    var eb = forge.util.createBuffer(em);
    var first = eb.getByte();
    var bt = eb.getByte();
    if (first !== 0 || pub && bt !== 0 && bt !== 1 || !pub && bt != 2 || pub && bt === 0 && typeof ml === 'undefined') throw new Error('Encryption block is invalid.');
    var padNum = 0;
    if (bt === 0) {
        // check all padding bytes for 0x00
        padNum = k - 3 - ml;
        for(var i = 0; i < padNum; ++i){
            if (eb.getByte() !== 0) throw new Error('Encryption block is invalid.');
        }
    } else if (bt === 1) {
        // find the first byte that isn't 0xFF, should be after all padding
        padNum = 0;
        while(eb.length() > 1){
            if (eb.getByte() !== 255) {
                --eb.read;
                break;
            }
            ++padNum;
        }
    } else if (bt === 2) {
        // look for 0x00 byte
        padNum = 0;
        while(eb.length() > 1){
            if (eb.getByte() === 0) {
                --eb.read;
                break;
            }
            ++padNum;
        }
    }
    // zero must be 0x00 and padNum must be (k - 3 - message length)
    var zero = eb.getByte();
    if (zero !== 0 || padNum !== k - 3 - eb.length()) throw new Error('Encryption block is invalid.');
    return eb.getBytes();
}
/**
 * Runs the key-generation algorithm asynchronously, either in the background
 * via Web Workers, or using the main thread and setImmediate.
 *
 * @param state the key-pair generation state.
 * @param [options] options for key-pair generation:
 *          workerScript the worker script URL.
 *          workers the number of web workers (if supported) to use,
 *            (default: 2, -1 to use estimated cores minus one).
 *          workLoad the size of the work load, ie: number of possible prime
 *            numbers for each web worker to check per work assignment,
 *            (default: 100).
 * @param callback(err, keypair) called once the operation completes.
 */ function _generateKeyPair(state, options, callback1) {
    if (typeof options === 'function') {
        callback1 = options;
        options = {
        };
    }
    options = options || {
    };
    var opts = {
        algorithm: {
            name: options.algorithm || 'PRIMEINC',
            options: {
                workers: options.workers || 2,
                workLoad: options.workLoad || 100,
                workerScript: options.workerScript
            }
        }
    };
    if ('prng' in options) opts.prng = options.prng;
    generate();
    function generate() {
        // find p and then q (done in series to simplify)
        getPrime(state.pBits, function(err, num) {
            if (err) return callback1(err);
            state.p = num;
            if (state.q !== null) return finish(err, state.q);
            getPrime(state.qBits, finish);
        });
    }
    function getPrime(bits, callback) {
        forge.prime.generateProbablePrime(bits, opts, callback);
    }
    function finish(err, num) {
        if (err) return callback1(err);
        // set q
        state.q = num;
        // ensure p is larger than q (swap them if not)
        if (state.p.compareTo(state.q) < 0) {
            var tmp = state.p;
            state.p = state.q;
            state.q = tmp;
        }
        // ensure p is coprime with e
        if (state.p.subtract(BigInteger.ONE).gcd(state.e).compareTo(BigInteger.ONE) !== 0) {
            state.p = null;
            generate();
            return;
        }
        // ensure q is coprime with e
        if (state.q.subtract(BigInteger.ONE).gcd(state.e).compareTo(BigInteger.ONE) !== 0) {
            state.q = null;
            getPrime(state.qBits, finish);
            return;
        }
        // compute phi: (p - 1)(q - 1) (Euler's totient function)
        state.p1 = state.p.subtract(BigInteger.ONE);
        state.q1 = state.q.subtract(BigInteger.ONE);
        state.phi = state.p1.multiply(state.q1);
        // ensure e and phi are coprime
        if (state.phi.gcd(state.e).compareTo(BigInteger.ONE) !== 0) {
            // phi and e aren't coprime, so generate a new p and q
            state.p = state.q = null;
            generate();
            return;
        }
        // create n, ensure n is has the right number of bits
        state.n = state.p.multiply(state.q);
        if (state.n.bitLength() !== state.bits) {
            // failed, get new q
            state.q = null;
            getPrime(state.qBits, finish);
            return;
        }
        // set keys
        var d = state.e.modInverse(state.phi);
        state.keys = {
            privateKey: pki.rsa.setPrivateKey(state.n, state.e, d, state.p, state.q, d.mod(state.p1), d.mod(state.q1), state.q.modInverse(state.p)),
            publicKey: pki.rsa.setPublicKey(state.n, state.e)
        };
        callback1(null, state.keys);
    }
}
/**
 * Converts a positive BigInteger into 2's-complement big-endian bytes.
 *
 * @param b the big integer to convert.
 *
 * @return the bytes.
 */ function _bnToBytes(b) {
    // prepend 0x00 if first byte >= 0x80
    var hex = b.toString(16);
    if (hex[0] >= '8') hex = '00' + hex;
    var bytes = forge.util.hexToBytes(hex);
    // ensure integer is minimally-encoded
    if (bytes.length > 1 && (bytes.charCodeAt(0) === 0 && (bytes.charCodeAt(1) & 128) === 0 || bytes.charCodeAt(0) === 255 && (bytes.charCodeAt(1) & 128) === 128)) return bytes.substr(1);
    return bytes;
}
/**
 * Returns the required number of Miller-Rabin tests to generate a
 * prime with an error probability of (1/2)^80.
 *
 * See Handbook of Applied Cryptography Chapter 4, Table 4.4.
 *
 * @param bits the bit size.
 *
 * @return the required number of iterations.
 */ function _getMillerRabinTests(bits) {
    if (bits <= 100) return 27;
    if (bits <= 150) return 18;
    if (bits <= 200) return 15;
    if (bits <= 250) return 12;
    if (bits <= 300) return 9;
    if (bits <= 350) return 8;
    if (bits <= 400) return 7;
    if (bits <= 500) return 6;
    if (bits <= 600) return 5;
    if (bits <= 800) return 4;
    if (bits <= 1250) return 3;
    return 2;
}
/**
 * Performs feature detection on the Node crypto interface.
 *
 * @param fn the feature (function) to detect.
 *
 * @return true if detected, false if not.
 */ function _detectNodeCrypto(fn) {
    return forge.util.isNodejs && typeof _crypto[fn] === 'function';
}
/**
 * Performs feature detection on the SubtleCrypto interface.
 *
 * @param fn the feature (function) to detect.
 *
 * @return true if detected, false if not.
 */ function _detectSubtleCrypto(fn) {
    return typeof util.globalScope !== 'undefined' && typeof util.globalScope.crypto === 'object' && typeof util.globalScope.crypto.subtle === 'object' && typeof util.globalScope.crypto.subtle[fn] === 'function';
}
/**
 * Performs feature detection on the deprecated Microsoft Internet Explorer
 * outdated SubtleCrypto interface. This function should only be used after
 * checking for the modern, standard SubtleCrypto interface.
 *
 * @param fn the feature (function) to detect.
 *
 * @return true if detected, false if not.
 */ function _detectSubtleMsCrypto(fn) {
    return typeof util.globalScope !== 'undefined' && typeof util.globalScope.msCrypto === 'object' && typeof util.globalScope.msCrypto.subtle === 'object' && typeof util.globalScope.msCrypto.subtle[fn] === 'function';
}
function _intToUint8Array(x) {
    var bytes = forge.util.hexToBytes(x.toString(16));
    var buffer = new Uint8Array(bytes.length);
    for(var i = 0; i < bytes.length; ++i)buffer[i] = bytes.charCodeAt(i);
    return buffer;
}
function _privateKeyFromJwk(jwk) {
    if (jwk.kty !== 'RSA') throw new Error('Unsupported key algorithm "' + jwk.kty + '"; algorithm must be "RSA".');
    return pki.setRsaPrivateKey(_base64ToBigInt(jwk.n), _base64ToBigInt(jwk.e), _base64ToBigInt(jwk.d), _base64ToBigInt(jwk.p), _base64ToBigInt(jwk.q), _base64ToBigInt(jwk.dp), _base64ToBigInt(jwk.dq), _base64ToBigInt(jwk.qi));
}
function _publicKeyFromJwk(jwk) {
    if (jwk.kty !== 'RSA') throw new Error('Key algorithm must be "RSA".');
    return pki.setRsaPublicKey(_base64ToBigInt(jwk.n), _base64ToBigInt(jwk.e));
}
function _base64ToBigInt(b64) {
    return new BigInteger(forge.util.bytesToHex(forge.util.decode64(b64)), 16);
}

},{"./forge":"7AnVp","./asn1":"fLyrX","./jsbn":"6OVnc","./oids":"iymJu","./pkcs1":"ggouh","./prime":"2gGbG","./random":"7GrCn","./util":"cHj6b","crypto":"joWnX"}],"6OVnc":[function(require,module,exports) {
// Copyright (c) 2005  Tom Wu
// All Rights Reserved.
// See "LICENSE" for details.
// Basic JavaScript BN library - subset useful for RSA encryption.
/*
Licensing (LICENSE)
-------------------

This software is covered under the following copyright:
*/ /*
 * Copyright (c) 2003-2005  Tom Wu
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
 *
 * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
 * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
 * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 * In addition, the following condition applies:
 *
 * All redistributions must retain an intact copy of this copyright notice
 * and disclaimer.
 */ /*
Address all questions regarding this license to:

  Tom Wu
  tjw@cs.Stanford.EDU
*/ var forge = require('./forge');
module.exports = forge.jsbn = forge.jsbn || {
};
// Bits per digit
var dbits;
// JavaScript engine analysis
var canary = 244837814094590;
var j_lm = (canary & 16777215) == 15715070;
// (public) Constructor
function BigInteger(a, b, c) {
    this.data = [];
    if (a != null) {
        if ("number" == typeof a) this.fromNumber(a, b, c);
        else if (b == null && "string" != typeof a) this.fromString(a, 256);
        else this.fromString(a, b);
    }
}
forge.jsbn.BigInteger = BigInteger;
// return new, unset BigInteger
function nbi() {
    return new BigInteger(null);
}
// am: Compute w_j += (x*this_i), propagate carries,
// c is initial carry, returns final carry.
// c < 3*dvalue, x < 2*dvalue, this_i < dvalue
// We need to select the fastest one that works in this environment.
// am1: use a single mult and divide to get the high bits,
// max digit bits should be 26 because
// max internal value = 2*dvalue^2-2*dvalue (< 2^53)
function am1(i, x, w, j, c, n) {
    while(--n >= 0){
        var v = x * this.data[i++] + w.data[j] + c;
        c = Math.floor(v / 67108864);
        w.data[j++] = v & 67108863;
    }
    return c;
}
// am2 avoids a big mult-and-extract completely.
// Max digit bits should be <= 30 because we do bitwise ops
// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31)
function am2(i, x, w, j, c, n) {
    var xl = x & 32767, xh = x >> 15;
    while(--n >= 0){
        var l = this.data[i] & 32767;
        var h = this.data[i++] >> 15;
        var m = xh * l + h * xl;
        l = xl * l + ((m & 32767) << 15) + w.data[j] + (c & 1073741823);
        c = (l >>> 30) + (m >>> 15) + xh * h + (c >>> 30);
        w.data[j++] = l & 1073741823;
    }
    return c;
}
// Alternately, set max digit bits to 28 since some
// browsers slow down when dealing with 32-bit numbers.
function am3(i, x, w, j, c, n) {
    var xl = x & 16383, xh = x >> 14;
    while(--n >= 0){
        var l = this.data[i] & 16383;
        var h = this.data[i++] >> 14;
        var m = xh * l + h * xl;
        l = xl * l + ((m & 16383) << 14) + w.data[j] + c;
        c = (l >> 28) + (m >> 14) + xh * h;
        w.data[j++] = l & 268435455;
    }
    return c;
}
// node.js (no browser)
if (typeof navigator === 'undefined') {
    BigInteger.prototype.am = am3;
    dbits = 28;
} else if (j_lm && navigator.appName == "Microsoft Internet Explorer") {
    BigInteger.prototype.am = am2;
    dbits = 30;
} else if (j_lm && navigator.appName != "Netscape") {
    BigInteger.prototype.am = am1;
    dbits = 26;
} else {
    BigInteger.prototype.am = am3;
    dbits = 28;
}
BigInteger.prototype.DB = dbits;
BigInteger.prototype.DM = (1 << dbits) - 1;
BigInteger.prototype.DV = 1 << dbits;
var BI_FP = 52;
BigInteger.prototype.FV = Math.pow(2, BI_FP);
BigInteger.prototype.F1 = BI_FP - dbits;
BigInteger.prototype.F2 = 2 * dbits - BI_FP;
// Digit conversions
var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";
var BI_RC = new Array();
var rr, vv;
rr = "0".charCodeAt(0);
for(vv = 0; vv <= 9; ++vv)BI_RC[rr++] = vv;
rr = "a".charCodeAt(0);
for(vv = 10; vv < 36; ++vv)BI_RC[rr++] = vv;
rr = "A".charCodeAt(0);
for(vv = 10; vv < 36; ++vv)BI_RC[rr++] = vv;
function int2char(n) {
    return BI_RM.charAt(n);
}
function intAt(s, i) {
    var c = BI_RC[s.charCodeAt(i)];
    return c == null ? -1 : c;
}
// (protected) copy this to r
function bnpCopyTo(r) {
    for(var i = this.t - 1; i >= 0; --i)r.data[i] = this.data[i];
    r.t = this.t;
    r.s = this.s;
}
// (protected) set from integer value x, -DV <= x < DV
function bnpFromInt(x) {
    this.t = 1;
    this.s = x < 0 ? -1 : 0;
    if (x > 0) this.data[0] = x;
    else if (x < -1) this.data[0] = x + this.DV;
    else this.t = 0;
}
// return bigint initialized to value
function nbv(i) {
    var r = nbi();
    r.fromInt(i);
    return r;
}
// (protected) set from string and radix
function bnpFromString(s, b) {
    var k;
    if (b == 16) k = 4;
    else if (b == 8) k = 3;
    else if (b == 256) k = 8; // byte array
    else if (b == 2) k = 1;
    else if (b == 32) k = 5;
    else if (b == 4) k = 2;
    else {
        this.fromRadix(s, b);
        return;
    }
    this.t = 0;
    this.s = 0;
    var i = s.length, mi = false, sh = 0;
    while(--i >= 0){
        var x = k == 8 ? s[i] & 255 : intAt(s, i);
        if (x < 0) {
            if (s.charAt(i) == "-") mi = true;
            continue;
        }
        mi = false;
        if (sh == 0) this.data[this.t++] = x;
        else if (sh + k > this.DB) {
            this.data[this.t - 1] |= (x & (1 << this.DB - sh) - 1) << sh;
            this.data[this.t++] = x >> this.DB - sh;
        } else this.data[this.t - 1] |= x << sh;
        sh += k;
        if (sh >= this.DB) sh -= this.DB;
    }
    if (k == 8 && (s[0] & 128) != 0) {
        this.s = -1;
        if (sh > 0) this.data[this.t - 1] |= (1 << this.DB - sh) - 1 << sh;
    }
    this.clamp();
    if (mi) BigInteger.ZERO.subTo(this, this);
}
// (protected) clamp off excess high words
function bnpClamp() {
    var c = this.s & this.DM;
    while(this.t > 0 && this.data[this.t - 1] == c)--this.t;
}
// (public) return string representation in given radix
function bnToString(b) {
    if (this.s < 0) return "-" + this.negate().toString(b);
    var k;
    if (b == 16) k = 4;
    else if (b == 8) k = 3;
    else if (b == 2) k = 1;
    else if (b == 32) k = 5;
    else if (b == 4) k = 2;
    else return this.toRadix(b);
    var km = (1 << k) - 1, d, m = false, r = "", i = this.t;
    var p = this.DB - i * this.DB % k;
    if (i-- > 0) {
        if (p < this.DB && (d = this.data[i] >> p) > 0) {
            m = true;
            r = int2char(d);
        }
        while(i >= 0){
            if (p < k) {
                d = (this.data[i] & (1 << p) - 1) << k - p;
                d |= this.data[--i] >> (p += this.DB - k);
            } else {
                d = this.data[i] >> (p -= k) & km;
                if (p <= 0) {
                    p += this.DB;
                    --i;
                }
            }
            if (d > 0) m = true;
            if (m) r += int2char(d);
        }
    }
    return m ? r : "0";
}
// (public) -this
function bnNegate() {
    var r = nbi();
    BigInteger.ZERO.subTo(this, r);
    return r;
}
// (public) |this|
function bnAbs() {
    return this.s < 0 ? this.negate() : this;
}
// (public) return + if this > a, - if this < a, 0 if equal
function bnCompareTo(a) {
    var r = this.s - a.s;
    if (r != 0) return r;
    var i = this.t;
    r = i - a.t;
    if (r != 0) return this.s < 0 ? -r : r;
    while(--i >= 0)if ((r = this.data[i] - a.data[i]) != 0) return r;
    return 0;
}
// returns bit length of the integer x
function nbits(x) {
    var r = 1, t;
    if ((t = x >>> 16) != 0) {
        x = t;
        r += 16;
    }
    if ((t = x >> 8) != 0) {
        x = t;
        r += 8;
    }
    if ((t = x >> 4) != 0) {
        x = t;
        r += 4;
    }
    if ((t = x >> 2) != 0) {
        x = t;
        r += 2;
    }
    if ((t = x >> 1) != 0) {
        x = t;
        r += 1;
    }
    return r;
}
// (public) return the number of bits in "this"
function bnBitLength() {
    if (this.t <= 0) return 0;
    return this.DB * (this.t - 1) + nbits(this.data[this.t - 1] ^ this.s & this.DM);
}
// (protected) r = this << n*DB
function bnpDLShiftTo(n, r) {
    var i;
    for(i = this.t - 1; i >= 0; --i)r.data[i + n] = this.data[i];
    for(i = n - 1; i >= 0; --i)r.data[i] = 0;
    r.t = this.t + n;
    r.s = this.s;
}
// (protected) r = this >> n*DB
function bnpDRShiftTo(n, r) {
    for(var i = n; i < this.t; ++i)r.data[i - n] = this.data[i];
    r.t = Math.max(this.t - n, 0);
    r.s = this.s;
}
// (protected) r = this << n
function bnpLShiftTo(n, r) {
    var bs = n % this.DB;
    var cbs = this.DB - bs;
    var bm = (1 << cbs) - 1;
    var ds = Math.floor(n / this.DB), c = this.s << bs & this.DM, i;
    for(i = this.t - 1; i >= 0; --i){
        r.data[i + ds + 1] = this.data[i] >> cbs | c;
        c = (this.data[i] & bm) << bs;
    }
    for(i = ds - 1; i >= 0; --i)r.data[i] = 0;
    r.data[ds] = c;
    r.t = this.t + ds + 1;
    r.s = this.s;
    r.clamp();
}
// (protected) r = this >> n
function bnpRShiftTo(n, r) {
    r.s = this.s;
    var ds = Math.floor(n / this.DB);
    if (ds >= this.t) {
        r.t = 0;
        return;
    }
    var bs = n % this.DB;
    var cbs = this.DB - bs;
    var bm = (1 << bs) - 1;
    r.data[0] = this.data[ds] >> bs;
    for(var i = ds + 1; i < this.t; ++i){
        r.data[i - ds - 1] |= (this.data[i] & bm) << cbs;
        r.data[i - ds] = this.data[i] >> bs;
    }
    if (bs > 0) r.data[this.t - ds - 1] |= (this.s & bm) << cbs;
    r.t = this.t - ds;
    r.clamp();
}
// (protected) r = this - a
function bnpSubTo(a, r) {
    var i = 0, c = 0, m = Math.min(a.t, this.t);
    while(i < m){
        c += this.data[i] - a.data[i];
        r.data[i++] = c & this.DM;
        c >>= this.DB;
    }
    if (a.t < this.t) {
        c -= a.s;
        while(i < this.t){
            c += this.data[i];
            r.data[i++] = c & this.DM;
            c >>= this.DB;
        }
        c += this.s;
    } else {
        c += this.s;
        while(i < a.t){
            c -= a.data[i];
            r.data[i++] = c & this.DM;
            c >>= this.DB;
        }
        c -= a.s;
    }
    r.s = c < 0 ? -1 : 0;
    if (c < -1) r.data[i++] = this.DV + c;
    else if (c > 0) r.data[i++] = c;
    r.t = i;
    r.clamp();
}
// (protected) r = this * a, r != this,a (HAC 14.12)
// "this" should be the larger one if appropriate.
function bnpMultiplyTo(a, r) {
    var x = this.abs(), y = a.abs();
    var i = x.t;
    r.t = i + y.t;
    while(--i >= 0)r.data[i] = 0;
    for(i = 0; i < y.t; ++i)r.data[i + x.t] = x.am(0, y.data[i], r, i, 0, x.t);
    r.s = 0;
    r.clamp();
    if (this.s != a.s) BigInteger.ZERO.subTo(r, r);
}
// (protected) r = this^2, r != this (HAC 14.16)
function bnpSquareTo(r) {
    var x = this.abs();
    var i = r.t = 2 * x.t;
    while(--i >= 0)r.data[i] = 0;
    for(i = 0; i < x.t - 1; ++i){
        var c = x.am(i, x.data[i], r, 2 * i, 0, 1);
        if ((r.data[i + x.t] += x.am(i + 1, 2 * x.data[i], r, 2 * i + 1, c, x.t - i - 1)) >= x.DV) {
            r.data[i + x.t] -= x.DV;
            r.data[i + x.t + 1] = 1;
        }
    }
    if (r.t > 0) r.data[r.t - 1] += x.am(i, x.data[i], r, 2 * i, 0, 1);
    r.s = 0;
    r.clamp();
}
// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
// r != q, this != m.  q or r may be null.
function bnpDivRemTo(m, q, r) {
    var pm = m.abs();
    if (pm.t <= 0) return;
    var pt = this.abs();
    if (pt.t < pm.t) {
        if (q != null) q.fromInt(0);
        if (r != null) this.copyTo(r);
        return;
    }
    if (r == null) r = nbi();
    var y = nbi(), ts = this.s, ms = m.s;
    var nsh = this.DB - nbits(pm.data[pm.t - 1]); // normalize modulus
    if (nsh > 0) {
        pm.lShiftTo(nsh, y);
        pt.lShiftTo(nsh, r);
    } else {
        pm.copyTo(y);
        pt.copyTo(r);
    }
    var ys = y.t;
    var y0 = y.data[ys - 1];
    if (y0 == 0) return;
    var yt = y0 * (1 << this.F1) + (ys > 1 ? y.data[ys - 2] >> this.F2 : 0);
    var d1 = this.FV / yt, d2 = (1 << this.F1) / yt, e = 1 << this.F2;
    var i = r.t, j = i - ys, t = q == null ? nbi() : q;
    y.dlShiftTo(j, t);
    if (r.compareTo(t) >= 0) {
        r.data[r.t++] = 1;
        r.subTo(t, r);
    }
    BigInteger.ONE.dlShiftTo(ys, t);
    t.subTo(y, y); // "negative" y so we can replace sub with am later
    while(y.t < ys)y.data[y.t++] = 0;
    while(--j >= 0){
        // Estimate quotient digit
        var qd = r.data[--i] == y0 ? this.DM : Math.floor(r.data[i] * d1 + (r.data[i - 1] + e) * d2);
        if ((r.data[i] += y.am(0, qd, r, j, 0, ys)) < qd) {
            y.dlShiftTo(j, t);
            r.subTo(t, r);
            while(r.data[i] < --qd)r.subTo(t, r);
        }
    }
    if (q != null) {
        r.drShiftTo(ys, q);
        if (ts != ms) BigInteger.ZERO.subTo(q, q);
    }
    r.t = ys;
    r.clamp();
    if (nsh > 0) r.rShiftTo(nsh, r); // Denormalize remainder
    if (ts < 0) BigInteger.ZERO.subTo(r, r);
}
// (public) this mod a
function bnMod(a) {
    var r = nbi();
    this.abs().divRemTo(a, null, r);
    if (this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r, r);
    return r;
}
// Modular reduction using "classic" algorithm
function Classic(m) {
    this.m = m;
}
function cConvert(x) {
    if (x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m);
    else return x;
}
function cRevert(x) {
    return x;
}
function cReduce(x) {
    x.divRemTo(this.m, null, x);
}
function cMulTo(x, y, r) {
    x.multiplyTo(y, r);
    this.reduce(r);
}
function cSqrTo(x, r) {
    x.squareTo(r);
    this.reduce(r);
}
Classic.prototype.convert = cConvert;
Classic.prototype.revert = cRevert;
Classic.prototype.reduce = cReduce;
Classic.prototype.mulTo = cMulTo;
Classic.prototype.sqrTo = cSqrTo;
// (protected) return "-1/this % 2^DB"; useful for Mont. reduction
// justification:
//         xy == 1 (mod m)
//         xy =  1+km
//   xy(2-xy) = (1+km)(1-km)
// x[y(2-xy)] = 1-k^2m^2
// x[y(2-xy)] == 1 (mod m^2)
// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
// should reduce x and y(2-xy) by m^2 at each step to keep size bounded.
// JS multiply "overflows" differently from C/C++, so care is needed here.
function bnpInvDigit() {
    if (this.t < 1) return 0;
    var x = this.data[0];
    if ((x & 1) == 0) return 0;
    var y = x & 3; // y == 1/x mod 2^2
    y = y * (2 - (x & 15) * y) & 15; // y == 1/x mod 2^4
    y = y * (2 - (x & 255) * y) & 255; // y == 1/x mod 2^8
    y = y * (2 - ((x & 65535) * y & 65535)) & 65535; // y == 1/x mod 2^16
    // last step - calculate inverse mod DV directly;
    // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
    y = y * (2 - x * y % this.DV) % this.DV; // y == 1/x mod 2^dbits
    // we really want the negative inverse, and -DV < y < DV
    return y > 0 ? this.DV - y : -y;
}
// Montgomery reduction
function Montgomery(m) {
    this.m = m;
    this.mp = m.invDigit();
    this.mpl = this.mp & 32767;
    this.mph = this.mp >> 15;
    this.um = (1 << m.DB - 15) - 1;
    this.mt2 = 2 * m.t;
}
// xR mod m
function montConvert(x) {
    var r = nbi();
    x.abs().dlShiftTo(this.m.t, r);
    r.divRemTo(this.m, null, r);
    if (x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r, r);
    return r;
}
// x/R mod m
function montRevert(x) {
    var r = nbi();
    x.copyTo(r);
    this.reduce(r);
    return r;
}
// x = x/R mod m (HAC 14.32)
function montReduce(x) {
    while(x.t <= this.mt2)x.data[x.t++] = 0;
    for(var i = 0; i < this.m.t; ++i){
        // faster way of calculating u0 = x.data[i]*mp mod DV
        var j = x.data[i] & 32767;
        var u0 = j * this.mpl + ((j * this.mph + (x.data[i] >> 15) * this.mpl & this.um) << 15) & x.DM;
        // use am to combine the multiply-shift-add into one call
        j = i + this.m.t;
        x.data[j] += this.m.am(0, u0, x, i, 0, this.m.t);
        // propagate carry
        while(x.data[j] >= x.DV){
            x.data[j] -= x.DV;
            x.data[++j]++;
        }
    }
    x.clamp();
    x.drShiftTo(this.m.t, x);
    if (x.compareTo(this.m) >= 0) x.subTo(this.m, x);
}
// r = "x^2/R mod m"; x != r
function montSqrTo(x, r) {
    x.squareTo(r);
    this.reduce(r);
}
// r = "xy/R mod m"; x,y != r
function montMulTo(x, y, r) {
    x.multiplyTo(y, r);
    this.reduce(r);
}
Montgomery.prototype.convert = montConvert;
Montgomery.prototype.revert = montRevert;
Montgomery.prototype.reduce = montReduce;
Montgomery.prototype.mulTo = montMulTo;
Montgomery.prototype.sqrTo = montSqrTo;
// (protected) true iff this is even
function bnpIsEven() {
    return (this.t > 0 ? this.data[0] & 1 : this.s) == 0;
}
// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
function bnpExp(e, z) {
    if (e > 4294967295 || e < 1) return BigInteger.ONE;
    var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e) - 1;
    g.copyTo(r);
    while(--i >= 0){
        z.sqrTo(r, r2);
        if ((e & 1 << i) > 0) z.mulTo(r2, g, r);
        else {
            var t = r;
            r = r2;
            r2 = t;
        }
    }
    return z.revert(r);
}
// (public) this^e % m, 0 <= e < 2^32
function bnModPowInt(e, m) {
    var z;
    if (e < 256 || m.isEven()) z = new Classic(m);
    else z = new Montgomery(m);
    return this.exp(e, z);
}
// protected
BigInteger.prototype.copyTo = bnpCopyTo;
BigInteger.prototype.fromInt = bnpFromInt;
BigInteger.prototype.fromString = bnpFromString;
BigInteger.prototype.clamp = bnpClamp;
BigInteger.prototype.dlShiftTo = bnpDLShiftTo;
BigInteger.prototype.drShiftTo = bnpDRShiftTo;
BigInteger.prototype.lShiftTo = bnpLShiftTo;
BigInteger.prototype.rShiftTo = bnpRShiftTo;
BigInteger.prototype.subTo = bnpSubTo;
BigInteger.prototype.multiplyTo = bnpMultiplyTo;
BigInteger.prototype.squareTo = bnpSquareTo;
BigInteger.prototype.divRemTo = bnpDivRemTo;
BigInteger.prototype.invDigit = bnpInvDigit;
BigInteger.prototype.isEven = bnpIsEven;
BigInteger.prototype.exp = bnpExp;
// public
BigInteger.prototype.toString = bnToString;
BigInteger.prototype.negate = bnNegate;
BigInteger.prototype.abs = bnAbs;
BigInteger.prototype.compareTo = bnCompareTo;
BigInteger.prototype.bitLength = bnBitLength;
BigInteger.prototype.mod = bnMod;
BigInteger.prototype.modPowInt = bnModPowInt;
// "constants"
BigInteger.ZERO = nbv(0);
BigInteger.ONE = nbv(1);
// jsbn2 lib
//Copyright (c) 2005-2009  Tom Wu
//All Rights Reserved.
//See "LICENSE" for details (See jsbn.js for LICENSE).
//Extended JavaScript BN functions, required for RSA private ops.
//Version 1.1: new BigInteger("0", 10) returns "proper" zero
//(public)
function bnClone() {
    var r = nbi();
    this.copyTo(r);
    return r;
}
//(public) return value as integer
function bnIntValue() {
    if (this.s < 0) {
        if (this.t == 1) return this.data[0] - this.DV;
        else if (this.t == 0) return -1;
    } else if (this.t == 1) return this.data[0];
    else if (this.t == 0) return 0;
    // assumes 16 < DB < 32
    return (this.data[1] & (1 << 32 - this.DB) - 1) << this.DB | this.data[0];
}
//(public) return value as byte
function bnByteValue() {
    return this.t == 0 ? this.s : this.data[0] << 24 >> 24;
}
//(public) return value as short (assumes DB>=16)
function bnShortValue() {
    return this.t == 0 ? this.s : this.data[0] << 16 >> 16;
}
//(protected) return x s.t. r^x < DV
function bnpChunkSize(r) {
    return Math.floor(Math.LN2 * this.DB / Math.log(r));
}
//(public) 0 if this == 0, 1 if this > 0
function bnSigNum() {
    if (this.s < 0) return -1;
    else if (this.t <= 0 || this.t == 1 && this.data[0] <= 0) return 0;
    else return 1;
}
//(protected) convert to radix string
function bnpToRadix(b) {
    if (b == null) b = 10;
    if (this.signum() == 0 || b < 2 || b > 36) return "0";
    var cs = this.chunkSize(b);
    var a = Math.pow(b, cs);
    var d = nbv(a), y = nbi(), z = nbi(), r = "";
    this.divRemTo(d, y, z);
    while(y.signum() > 0){
        r = (a + z.intValue()).toString(b).substr(1) + r;
        y.divRemTo(d, y, z);
    }
    return z.intValue().toString(b) + r;
}
//(protected) convert from radix string
function bnpFromRadix(s, b) {
    this.fromInt(0);
    if (b == null) b = 10;
    var cs = this.chunkSize(b);
    var d = Math.pow(b, cs), mi = false, j = 0, w = 0;
    for(var i = 0; i < s.length; ++i){
        var x = intAt(s, i);
        if (x < 0) {
            if (s.charAt(i) == "-" && this.signum() == 0) mi = true;
            continue;
        }
        w = b * w + x;
        if (++j >= cs) {
            this.dMultiply(d);
            this.dAddOffset(w, 0);
            j = 0;
            w = 0;
        }
    }
    if (j > 0) {
        this.dMultiply(Math.pow(b, j));
        this.dAddOffset(w, 0);
    }
    if (mi) BigInteger.ZERO.subTo(this, this);
}
//(protected) alternate constructor
function bnpFromNumber(a, b, c) {
    if ("number" == typeof b) {
        // new BigInteger(int,int,RNG)
        if (a < 2) this.fromInt(1);
        else {
            this.fromNumber(a, c);
            if (!this.testBit(a - 1)) this.bitwiseTo(BigInteger.ONE.shiftLeft(a - 1), op_or, this);
            if (this.isEven()) this.dAddOffset(1, 0); // force odd
            while(!this.isProbablePrime(b)){
                this.dAddOffset(2, 0);
                if (this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a - 1), this);
            }
        }
    } else {
        // new BigInteger(int,RNG)
        var x = new Array(), t = a & 7;
        x.length = (a >> 3) + 1;
        b.nextBytes(x);
        if (t > 0) x[0] &= (1 << t) - 1;
        else x[0] = 0;
        this.fromString(x, 256);
    }
}
//(public) convert to bigendian byte array
function bnToByteArray() {
    var i = this.t, r = new Array();
    r[0] = this.s;
    var p = this.DB - i * this.DB % 8, d, k = 0;
    if (i-- > 0) {
        if (p < this.DB && (d = this.data[i] >> p) != (this.s & this.DM) >> p) r[k++] = d | this.s << this.DB - p;
        while(i >= 0){
            if (p < 8) {
                d = (this.data[i] & (1 << p) - 1) << 8 - p;
                d |= this.data[--i] >> (p += this.DB - 8);
            } else {
                d = this.data[i] >> (p -= 8) & 255;
                if (p <= 0) {
                    p += this.DB;
                    --i;
                }
            }
            if ((d & 128) != 0) d |= -256;
            if (k == 0 && (this.s & 128) != (d & 128)) ++k;
            if (k > 0 || d != this.s) r[k++] = d;
        }
    }
    return r;
}
function bnEquals(a) {
    return this.compareTo(a) == 0;
}
function bnMin(a) {
    return this.compareTo(a) < 0 ? this : a;
}
function bnMax(a) {
    return this.compareTo(a) > 0 ? this : a;
}
//(protected) r = this op a (bitwise)
function bnpBitwiseTo(a, op, r) {
    var i, f, m = Math.min(a.t, this.t);
    for(i = 0; i < m; ++i)r.data[i] = op(this.data[i], a.data[i]);
    if (a.t < this.t) {
        f = a.s & this.DM;
        for(i = m; i < this.t; ++i)r.data[i] = op(this.data[i], f);
        r.t = this.t;
    } else {
        f = this.s & this.DM;
        for(i = m; i < a.t; ++i)r.data[i] = op(f, a.data[i]);
        r.t = a.t;
    }
    r.s = op(this.s, a.s);
    r.clamp();
}
//(public) this & a
function op_and(x, y) {
    return x & y;
}
function bnAnd(a) {
    var r = nbi();
    this.bitwiseTo(a, op_and, r);
    return r;
}
//(public) this | a
function op_or(x, y) {
    return x | y;
}
function bnOr(a) {
    var r = nbi();
    this.bitwiseTo(a, op_or, r);
    return r;
}
//(public) this ^ a
function op_xor(x, y) {
    return x ^ y;
}
function bnXor(a) {
    var r = nbi();
    this.bitwiseTo(a, op_xor, r);
    return r;
}
//(public) this & ~a
function op_andnot(x, y) {
    return x & ~y;
}
function bnAndNot(a) {
    var r = nbi();
    this.bitwiseTo(a, op_andnot, r);
    return r;
}
//(public) ~this
function bnNot() {
    var r = nbi();
    for(var i = 0; i < this.t; ++i)r.data[i] = this.DM & ~this.data[i];
    r.t = this.t;
    r.s = ~this.s;
    return r;
}
//(public) this << n
function bnShiftLeft(n) {
    var r = nbi();
    if (n < 0) this.rShiftTo(-n, r);
    else this.lShiftTo(n, r);
    return r;
}
//(public) this >> n
function bnShiftRight(n) {
    var r = nbi();
    if (n < 0) this.lShiftTo(-n, r);
    else this.rShiftTo(n, r);
    return r;
}
//return index of lowest 1-bit in x, x < 2^31
function lbit(x) {
    if (x == 0) return -1;
    var r = 0;
    if ((x & 65535) == 0) {
        x >>= 16;
        r += 16;
    }
    if ((x & 255) == 0) {
        x >>= 8;
        r += 8;
    }
    if ((x & 15) == 0) {
        x >>= 4;
        r += 4;
    }
    if ((x & 3) == 0) {
        x >>= 2;
        r += 2;
    }
    if ((x & 1) == 0) ++r;
    return r;
}
//(public) returns index of lowest 1-bit (or -1 if none)
function bnGetLowestSetBit() {
    for(var i = 0; i < this.t; ++i)if (this.data[i] != 0) return i * this.DB + lbit(this.data[i]);
    if (this.s < 0) return this.t * this.DB;
    return -1;
}
//return number of 1 bits in x
function cbit(x) {
    var r = 0;
    while(x != 0){
        x &= x - 1;
        ++r;
    }
    return r;
}
//(public) return number of set bits
function bnBitCount() {
    var r = 0, x = this.s & this.DM;
    for(var i = 0; i < this.t; ++i)r += cbit(this.data[i] ^ x);
    return r;
}
//(public) true iff nth bit is set
function bnTestBit(n) {
    var j = Math.floor(n / this.DB);
    if (j >= this.t) return this.s != 0;
    return (this.data[j] & 1 << n % this.DB) != 0;
}
//(protected) this op (1<<n)
function bnpChangeBit(n, op) {
    var r = BigInteger.ONE.shiftLeft(n);
    this.bitwiseTo(r, op, r);
    return r;
}
//(public) this | (1<<n)
function bnSetBit(n) {
    return this.changeBit(n, op_or);
}
//(public) this & ~(1<<n)
function bnClearBit(n) {
    return this.changeBit(n, op_andnot);
}
//(public) this ^ (1<<n)
function bnFlipBit(n) {
    return this.changeBit(n, op_xor);
}
//(protected) r = this + a
function bnpAddTo(a, r) {
    var i = 0, c = 0, m = Math.min(a.t, this.t);
    while(i < m){
        c += this.data[i] + a.data[i];
        r.data[i++] = c & this.DM;
        c >>= this.DB;
    }
    if (a.t < this.t) {
        c += a.s;
        while(i < this.t){
            c += this.data[i];
            r.data[i++] = c & this.DM;
            c >>= this.DB;
        }
        c += this.s;
    } else {
        c += this.s;
        while(i < a.t){
            c += a.data[i];
            r.data[i++] = c & this.DM;
            c >>= this.DB;
        }
        c += a.s;
    }
    r.s = c < 0 ? -1 : 0;
    if (c > 0) r.data[i++] = c;
    else if (c < -1) r.data[i++] = this.DV + c;
    r.t = i;
    r.clamp();
}
//(public) this + a
function bnAdd(a) {
    var r = nbi();
    this.addTo(a, r);
    return r;
}
//(public) this - a
function bnSubtract(a) {
    var r = nbi();
    this.subTo(a, r);
    return r;
}
//(public) this * a
function bnMultiply(a) {
    var r = nbi();
    this.multiplyTo(a, r);
    return r;
}
//(public) this / a
function bnDivide(a) {
    var r = nbi();
    this.divRemTo(a, r, null);
    return r;
}
//(public) this % a
function bnRemainder(a) {
    var r = nbi();
    this.divRemTo(a, null, r);
    return r;
}
//(public) [this/a,this%a]
function bnDivideAndRemainder(a) {
    var q = nbi(), r = nbi();
    this.divRemTo(a, q, r);
    return new Array(q, r);
}
//(protected) this *= n, this >= 0, 1 < n < DV
function bnpDMultiply(n) {
    this.data[this.t] = this.am(0, n - 1, this, 0, 0, this.t);
    ++this.t;
    this.clamp();
}
//(protected) this += n << w words, this >= 0
function bnpDAddOffset(n, w) {
    if (n == 0) return;
    while(this.t <= w)this.data[this.t++] = 0;
    this.data[w] += n;
    while(this.data[w] >= this.DV){
        this.data[w] -= this.DV;
        if (++w >= this.t) this.data[this.t++] = 0;
        ++this.data[w];
    }
}
//A "null" reducer
function NullExp() {
}
function nNop(x) {
    return x;
}
function nMulTo(x, y, r) {
    x.multiplyTo(y, r);
}
function nSqrTo(x, r) {
    x.squareTo(r);
}
NullExp.prototype.convert = nNop;
NullExp.prototype.revert = nNop;
NullExp.prototype.mulTo = nMulTo;
NullExp.prototype.sqrTo = nSqrTo;
//(public) this^e
function bnPow(e) {
    return this.exp(e, new NullExp());
}
//(protected) r = lower n words of "this * a", a.t <= n
//"this" should be the larger one if appropriate.
function bnpMultiplyLowerTo(a, n, r) {
    var i = Math.min(this.t + a.t, n);
    r.s = 0; // assumes a,this >= 0
    r.t = i;
    while(i > 0)r.data[--i] = 0;
    var j;
    for(j = r.t - this.t; i < j; ++i)r.data[i + this.t] = this.am(0, a.data[i], r, i, 0, this.t);
    for(j = Math.min(a.t, n); i < j; ++i)this.am(0, a.data[i], r, i, 0, n - i);
    r.clamp();
}
//(protected) r = "this * a" without lower n words, n > 0
//"this" should be the larger one if appropriate.
function bnpMultiplyUpperTo(a, n, r) {
    --n;
    var i = r.t = this.t + a.t - n;
    r.s = 0; // assumes a,this >= 0
    while(--i >= 0)r.data[i] = 0;
    for(i = Math.max(n - this.t, 0); i < a.t; ++i)r.data[this.t + i - n] = this.am(n - i, a.data[i], r, 0, 0, this.t + i - n);
    r.clamp();
    r.drShiftTo(1, r);
}
//Barrett modular reduction
function Barrett(m) {
    // setup Barrett
    this.r2 = nbi();
    this.q3 = nbi();
    BigInteger.ONE.dlShiftTo(2 * m.t, this.r2);
    this.mu = this.r2.divide(m);
    this.m = m;
}
function barrettConvert(x) {
    if (x.s < 0 || x.t > 2 * this.m.t) return x.mod(this.m);
    else if (x.compareTo(this.m) < 0) return x;
    else {
        var r = nbi();
        x.copyTo(r);
        this.reduce(r);
        return r;
    }
}
function barrettRevert(x) {
    return x;
}
//x = x mod m (HAC 14.42)
function barrettReduce(x) {
    x.drShiftTo(this.m.t - 1, this.r2);
    if (x.t > this.m.t + 1) {
        x.t = this.m.t + 1;
        x.clamp();
    }
    this.mu.multiplyUpperTo(this.r2, this.m.t + 1, this.q3);
    this.m.multiplyLowerTo(this.q3, this.m.t + 1, this.r2);
    while(x.compareTo(this.r2) < 0)x.dAddOffset(1, this.m.t + 1);
    x.subTo(this.r2, x);
    while(x.compareTo(this.m) >= 0)x.subTo(this.m, x);
}
//r = x^2 mod m; x != r
function barrettSqrTo(x, r) {
    x.squareTo(r);
    this.reduce(r);
}
//r = x*y mod m; x,y != r
function barrettMulTo(x, y, r) {
    x.multiplyTo(y, r);
    this.reduce(r);
}
Barrett.prototype.convert = barrettConvert;
Barrett.prototype.revert = barrettRevert;
Barrett.prototype.reduce = barrettReduce;
Barrett.prototype.mulTo = barrettMulTo;
Barrett.prototype.sqrTo = barrettSqrTo;
//(public) this^e % m (HAC 14.85)
function bnModPow(e, m) {
    var i = e.bitLength(), k, r = nbv(1), z;
    if (i <= 0) return r;
    else if (i < 18) k = 1;
    else if (i < 48) k = 3;
    else if (i < 144) k = 4;
    else if (i < 768) k = 5;
    else k = 6;
    if (i < 8) z = new Classic(m);
    else if (m.isEven()) z = new Barrett(m);
    else z = new Montgomery(m);
    // precomputation
    var g = new Array(), n = 3, k1 = k - 1, km = (1 << k) - 1;
    g[1] = z.convert(this);
    if (k > 1) {
        var g2 = nbi();
        z.sqrTo(g[1], g2);
        while(n <= km){
            g[n] = nbi();
            z.mulTo(g2, g[n - 2], g[n]);
            n += 2;
        }
    }
    var j = e.t - 1, w, is1 = true, r2 = nbi(), t;
    i = nbits(e.data[j]) - 1;
    while(j >= 0){
        if (i >= k1) w = e.data[j] >> i - k1 & km;
        else {
            w = (e.data[j] & (1 << i + 1) - 1) << k1 - i;
            if (j > 0) w |= e.data[j - 1] >> this.DB + i - k1;
        }
        n = k;
        while((w & 1) == 0){
            w >>= 1;
            --n;
        }
        if ((i -= n) < 0) {
            i += this.DB;
            --j;
        }
        if (is1) {
            g[w].copyTo(r);
            is1 = false;
        } else {
            while(n > 1){
                z.sqrTo(r, r2);
                z.sqrTo(r2, r);
                n -= 2;
            }
            if (n > 0) z.sqrTo(r, r2);
            else {
                t = r;
                r = r2;
                r2 = t;
            }
            z.mulTo(r2, g[w], r);
        }
        while(j >= 0 && (e.data[j] & 1 << i) == 0){
            z.sqrTo(r, r2);
            t = r;
            r = r2;
            r2 = t;
            if (--i < 0) {
                i = this.DB - 1;
                --j;
            }
        }
    }
    return z.revert(r);
}
//(public) gcd(this,a) (HAC 14.54)
function bnGCD(a) {
    var x = this.s < 0 ? this.negate() : this.clone();
    var y = a.s < 0 ? a.negate() : a.clone();
    if (x.compareTo(y) < 0) {
        var t = x;
        x = y;
        y = t;
    }
    var i = x.getLowestSetBit(), g = y.getLowestSetBit();
    if (g < 0) return x;
    if (i < g) g = i;
    if (g > 0) {
        x.rShiftTo(g, x);
        y.rShiftTo(g, y);
    }
    while(x.signum() > 0){
        if ((i = x.getLowestSetBit()) > 0) x.rShiftTo(i, x);
        if ((i = y.getLowestSetBit()) > 0) y.rShiftTo(i, y);
        if (x.compareTo(y) >= 0) {
            x.subTo(y, x);
            x.rShiftTo(1, x);
        } else {
            y.subTo(x, y);
            y.rShiftTo(1, y);
        }
    }
    if (g > 0) y.lShiftTo(g, y);
    return y;
}
//(protected) this % n, n < 2^26
function bnpModInt(n) {
    if (n <= 0) return 0;
    var d = this.DV % n, r = this.s < 0 ? n - 1 : 0;
    if (this.t > 0) {
        if (d == 0) r = this.data[0] % n;
        else for(var i = this.t - 1; i >= 0; --i)r = (d * r + this.data[i]) % n;
    }
    return r;
}
//(public) 1/this % m (HAC 14.61)
function bnModInverse(m) {
    var ac = m.isEven();
    if (this.isEven() && ac || m.signum() == 0) return BigInteger.ZERO;
    var u = m.clone(), v = this.clone();
    var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1);
    while(u.signum() != 0){
        while(u.isEven()){
            u.rShiftTo(1, u);
            if (ac) {
                if (!a.isEven() || !b.isEven()) {
                    a.addTo(this, a);
                    b.subTo(m, b);
                }
                a.rShiftTo(1, a);
            } else if (!b.isEven()) b.subTo(m, b);
            b.rShiftTo(1, b);
        }
        while(v.isEven()){
            v.rShiftTo(1, v);
            if (ac) {
                if (!c.isEven() || !d.isEven()) {
                    c.addTo(this, c);
                    d.subTo(m, d);
                }
                c.rShiftTo(1, c);
            } else if (!d.isEven()) d.subTo(m, d);
            d.rShiftTo(1, d);
        }
        if (u.compareTo(v) >= 0) {
            u.subTo(v, u);
            if (ac) a.subTo(c, a);
            b.subTo(d, b);
        } else {
            v.subTo(u, v);
            if (ac) c.subTo(a, c);
            d.subTo(b, d);
        }
    }
    if (v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO;
    if (d.compareTo(m) >= 0) return d.subtract(m);
    if (d.signum() < 0) d.addTo(m, d);
    else return d;
    if (d.signum() < 0) return d.add(m);
    else return d;
}
var lowprimes = [
    2,
    3,
    5,
    7,
    11,
    13,
    17,
    19,
    23,
    29,
    31,
    37,
    41,
    43,
    47,
    53,
    59,
    61,
    67,
    71,
    73,
    79,
    83,
    89,
    97,
    101,
    103,
    107,
    109,
    113,
    127,
    131,
    137,
    139,
    149,
    151,
    157,
    163,
    167,
    173,
    179,
    181,
    191,
    193,
    197,
    199,
    211,
    223,
    227,
    229,
    233,
    239,
    241,
    251,
    257,
    263,
    269,
    271,
    277,
    281,
    283,
    293,
    307,
    311,
    313,
    317,
    331,
    337,
    347,
    349,
    353,
    359,
    367,
    373,
    379,
    383,
    389,
    397,
    401,
    409,
    419,
    421,
    431,
    433,
    439,
    443,
    449,
    457,
    461,
    463,
    467,
    479,
    487,
    491,
    499,
    503,
    509
];
var lplim = 67108864 / lowprimes[lowprimes.length - 1];
//(public) test primality with certainty >= 1-.5^t
function bnIsProbablePrime(t) {
    var i, x = this.abs();
    if (x.t == 1 && x.data[0] <= lowprimes[lowprimes.length - 1]) {
        for(i = 0; i < lowprimes.length; ++i)if (x.data[0] == lowprimes[i]) return true;
        return false;
    }
    if (x.isEven()) return false;
    i = 1;
    while(i < lowprimes.length){
        var m = lowprimes[i], j = i + 1;
        while(j < lowprimes.length && m < lplim)m *= lowprimes[j++];
        m = x.modInt(m);
        while(i < j)if (m % lowprimes[i++] == 0) return false;
    }
    return x.millerRabin(t);
}
//(protected) true if probably prime (HAC 4.24, Miller-Rabin)
function bnpMillerRabin(t) {
    var n1 = this.subtract(BigInteger.ONE);
    var k = n1.getLowestSetBit();
    if (k <= 0) return false;
    var r = n1.shiftRight(k);
    var prng = bnGetPrng();
    var a;
    for(var i = 0; i < t; ++i){
        // select witness 'a' at random from between 1 and n1
        do a = new BigInteger(this.bitLength(), prng);
        while (a.compareTo(BigInteger.ONE) <= 0 || a.compareTo(n1) >= 0)
        var y = a.modPow(r, this);
        if (y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) {
            var j = 1;
            while((j++) < k && y.compareTo(n1) != 0){
                y = y.modPowInt(2, this);
                if (y.compareTo(BigInteger.ONE) == 0) return false;
            }
            if (y.compareTo(n1) != 0) return false;
        }
    }
    return true;
}
// get pseudo random number generator
function bnGetPrng() {
    // create prng with api that matches BigInteger secure random
    return {
        // x is an array to fill with bytes
        nextBytes: function(x) {
            for(var i = 0; i < x.length; ++i)x[i] = Math.floor(Math.random() * 256);
        }
    };
}
//protected
BigInteger.prototype.chunkSize = bnpChunkSize;
BigInteger.prototype.toRadix = bnpToRadix;
BigInteger.prototype.fromRadix = bnpFromRadix;
BigInteger.prototype.fromNumber = bnpFromNumber;
BigInteger.prototype.bitwiseTo = bnpBitwiseTo;
BigInteger.prototype.changeBit = bnpChangeBit;
BigInteger.prototype.addTo = bnpAddTo;
BigInteger.prototype.dMultiply = bnpDMultiply;
BigInteger.prototype.dAddOffset = bnpDAddOffset;
BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo;
BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo;
BigInteger.prototype.modInt = bnpModInt;
BigInteger.prototype.millerRabin = bnpMillerRabin;
//public
BigInteger.prototype.clone = bnClone;
BigInteger.prototype.intValue = bnIntValue;
BigInteger.prototype.byteValue = bnByteValue;
BigInteger.prototype.shortValue = bnShortValue;
BigInteger.prototype.signum = bnSigNum;
BigInteger.prototype.toByteArray = bnToByteArray;
BigInteger.prototype.equals = bnEquals;
BigInteger.prototype.min = bnMin;
BigInteger.prototype.max = bnMax;
BigInteger.prototype.and = bnAnd;
BigInteger.prototype.or = bnOr;
BigInteger.prototype.xor = bnXor;
BigInteger.prototype.andNot = bnAndNot;
BigInteger.prototype.not = bnNot;
BigInteger.prototype.shiftLeft = bnShiftLeft;
BigInteger.prototype.shiftRight = bnShiftRight;
BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit;
BigInteger.prototype.bitCount = bnBitCount;
BigInteger.prototype.testBit = bnTestBit;
BigInteger.prototype.setBit = bnSetBit;
BigInteger.prototype.clearBit = bnClearBit;
BigInteger.prototype.flipBit = bnFlipBit;
BigInteger.prototype.add = bnAdd;
BigInteger.prototype.subtract = bnSubtract;
BigInteger.prototype.multiply = bnMultiply;
BigInteger.prototype.divide = bnDivide;
BigInteger.prototype.remainder = bnRemainder;
BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder;
BigInteger.prototype.modPow = bnModPow;
BigInteger.prototype.modInverse = bnModInverse;
BigInteger.prototype.pow = bnPow;
BigInteger.prototype.gcd = bnGCD;
BigInteger.prototype.isProbablePrime = bnIsProbablePrime; //BigInteger interfaces not implemented in jsbn:
 //BigInteger(int signum, byte[] magnitude)
 //double doubleValue()
 //float floatValue()
 //int hashCode()
 //long longValue()
 //static BigInteger valueOf(long val)

},{"./forge":"7AnVp"}],"ggouh":[function(require,module,exports) {
/**
 * Partial implementation of PKCS#1 v2.2: RSA-OEAP
 *
 * Modified but based on the following MIT and BSD licensed code:
 *
 * https://github.com/kjur/jsjws/blob/master/rsa.js:
 *
 * The 'jsjws'(JSON Web Signature JavaScript Library) License
 *
 * Copyright (c) 2012 Kenji Urushima
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 * http://webrsa.cvs.sourceforge.net/viewvc/webrsa/Client/RSAES-OAEP.js?content-type=text%2Fplain:
 *
 * RSAES-OAEP.js
 * $Id: RSAES-OAEP.js,v 1.1.1.1 2003/03/19 15:37:20 ellispritchard Exp $
 * JavaScript Implementation of PKCS #1 v2.1 RSA CRYPTOGRAPHY STANDARD (RSA Laboratories, June 14, 2002)
 * Copyright (C) Ellis Pritchard, Guardian Unlimited 2003.
 * Contact: ellis@nukinetics.com
 * Distributed under the BSD License.
 *
 * Official documentation: http://www.rsa.com/rsalabs/node.asp?id=2125
 *
 * @author Evan Jones (http://evanjones.ca/)
 * @author Dave Longley
 *
 * Copyright (c) 2013-2014 Digital Bazaar, Inc.
 */ var forge = require('./forge');
require('./util');
require('./random');
require('./sha1');
// shortcut for PKCS#1 API
var pkcs1 = module.exports = forge.pkcs1 = forge.pkcs1 || {
};
/**
 * Encode the given RSAES-OAEP message (M) using key, with optional label (L)
 * and seed.
 *
 * This method does not perform RSA encryption, it only encodes the message
 * using RSAES-OAEP.
 *
 * @param key the RSA key to use.
 * @param message the message to encode.
 * @param options the options to use:
 *          label an optional label to use.
 *          seed the seed to use.
 *          md the message digest object to use, undefined for SHA-1.
 *          mgf1 optional mgf1 parameters:
 *            md the message digest object to use for MGF1.
 *
 * @return the encoded message bytes.
 */ pkcs1.encode_rsa_oaep = function(key, message, options) {
    // parse arguments
    var label;
    var seed;
    var md;
    var mgf1Md;
    // legacy args (label, seed, md)
    if (typeof options === 'string') {
        label = options;
        seed = arguments[3] || undefined;
        md = arguments[4] || undefined;
    } else if (options) {
        label = options.label || undefined;
        seed = options.seed || undefined;
        md = options.md || undefined;
        if (options.mgf1 && options.mgf1.md) mgf1Md = options.mgf1.md;
    }
    // default OAEP to SHA-1 message digest
    if (!md) md = forge.md.sha1.create();
    else md.start();
    // default MGF-1 to same as OAEP
    if (!mgf1Md) mgf1Md = md;
    // compute length in bytes and check output
    var keyLength = Math.ceil(key.n.bitLength() / 8);
    var maxLength = keyLength - 2 * md.digestLength - 2;
    if (message.length > maxLength) {
        var error = new Error('RSAES-OAEP input message length is too long.');
        error.length = message.length;
        error.maxLength = maxLength;
        throw error;
    }
    if (!label) label = '';
    md.update(label, 'raw');
    var lHash = md.digest();
    var PS = '';
    var PS_length = maxLength - message.length;
    for(var i = 0; i < PS_length; i++)PS += '\x00';
    var DB = lHash.getBytes() + PS + '\x01' + message;
    if (!seed) seed = forge.random.getBytes(md.digestLength);
    else if (seed.length !== md.digestLength) {
        var error = new Error("Invalid RSAES-OAEP seed. The seed length must match the digest length.");
        error.seedLength = seed.length;
        error.digestLength = md.digestLength;
        throw error;
    }
    var dbMask = rsa_mgf1(seed, keyLength - md.digestLength - 1, mgf1Md);
    var maskedDB = forge.util.xorBytes(DB, dbMask, DB.length);
    var seedMask = rsa_mgf1(maskedDB, md.digestLength, mgf1Md);
    var maskedSeed = forge.util.xorBytes(seed, seedMask, seed.length);
    // return encoded message
    return '\x00' + maskedSeed + maskedDB;
};
/**
 * Decode the given RSAES-OAEP encoded message (EM) using key, with optional
 * label (L).
 *
 * This method does not perform RSA decryption, it only decodes the message
 * using RSAES-OAEP.
 *
 * @param key the RSA key to use.
 * @param em the encoded message to decode.
 * @param options the options to use:
 *          label an optional label to use.
 *          md the message digest object to use for OAEP, undefined for SHA-1.
 *          mgf1 optional mgf1 parameters:
 *            md the message digest object to use for MGF1.
 *
 * @return the decoded message bytes.
 */ pkcs1.decode_rsa_oaep = function(key, em, options) {
    // parse args
    var label;
    var md;
    var mgf1Md;
    // legacy args
    if (typeof options === 'string') {
        label = options;
        md = arguments[3] || undefined;
    } else if (options) {
        label = options.label || undefined;
        md = options.md || undefined;
        if (options.mgf1 && options.mgf1.md) mgf1Md = options.mgf1.md;
    }
    // compute length in bytes
    var keyLength = Math.ceil(key.n.bitLength() / 8);
    if (em.length !== keyLength) {
        var error = new Error('RSAES-OAEP encoded message length is invalid.');
        error.length = em.length;
        error.expectedLength = keyLength;
        throw error;
    }
    // default OAEP to SHA-1 message digest
    if (md === undefined) md = forge.md.sha1.create();
    else md.start();
    // default MGF-1 to same as OAEP
    if (!mgf1Md) mgf1Md = md;
    if (keyLength < 2 * md.digestLength + 2) throw new Error('RSAES-OAEP key is too short for the hash function.');
    if (!label) label = '';
    md.update(label, 'raw');
    var lHash = md.digest().getBytes();
    // split the message into its parts
    var y = em.charAt(0);
    var maskedSeed = em.substring(1, md.digestLength + 1);
    var maskedDB = em.substring(1 + md.digestLength);
    var seedMask = rsa_mgf1(maskedDB, md.digestLength, mgf1Md);
    var seed = forge.util.xorBytes(maskedSeed, seedMask, maskedSeed.length);
    var dbMask = rsa_mgf1(seed, keyLength - md.digestLength - 1, mgf1Md);
    var db = forge.util.xorBytes(maskedDB, dbMask, maskedDB.length);
    var lHashPrime = db.substring(0, md.digestLength);
    // constant time check that all values match what is expected
    var error = y !== '\x00';
    // constant time check lHash vs lHashPrime
    for(var i = 0; i < md.digestLength; ++i)error |= lHash.charAt(i) !== lHashPrime.charAt(i);
    // "constant time" find the 0x1 byte separating the padding (zeros) from the
    // message
    // TODO: It must be possible to do this in a better/smarter way?
    var in_ps = 1;
    var index = md.digestLength;
    for(var j = md.digestLength; j < db.length; j++){
        var code = db.charCodeAt(j);
        var is_0 = code & 1 ^ 1;
        // non-zero if not 0 or 1 in the ps section
        var error_mask = in_ps ? 65534 : 0;
        error |= code & error_mask;
        // latch in_ps to zero after we find 0x1
        in_ps = in_ps & is_0;
        index += in_ps;
    }
    if (error || db.charCodeAt(index) !== 1) throw new Error('Invalid RSAES-OAEP padding.');
    return db.substring(index + 1);
};
function rsa_mgf1(seed, maskLength, hash) {
    // default to SHA-1 message digest
    if (!hash) hash = forge.md.sha1.create();
    var t = '';
    var count = Math.ceil(maskLength / hash.digestLength);
    for(var i = 0; i < count; ++i){
        var c = String.fromCharCode(i >> 24 & 255, i >> 16 & 255, i >> 8 & 255, i & 255);
        hash.start();
        hash.update(seed + c);
        t += hash.digest().getBytes();
    }
    return t.substring(0, maskLength);
}

},{"./forge":"7AnVp","./util":"cHj6b","./random":"7GrCn","./sha1":"5Jqtv"}],"5Jqtv":[function(require,module,exports) {
/**
 * Secure Hash Algorithm with 160-bit digest (SHA-1) implementation.
 *
 * @author Dave Longley
 *
 * Copyright (c) 2010-2015 Digital Bazaar, Inc.
 */ var forge = require('./forge');
require('./md');
require('./util');
var sha1 = module.exports = forge.sha1 = forge.sha1 || {
};
forge.md.sha1 = forge.md.algorithms.sha1 = sha1;
/**
 * Creates a SHA-1 message digest object.
 *
 * @return a message digest object.
 */ sha1.create = function() {
    // do initialization as necessary
    if (!_initialized) _init();
    // SHA-1 state contains five 32-bit integers
    var _state = null;
    // input buffer
    var _input = forge.util.createBuffer();
    // used for word storage
    var _w = new Array(80);
    // message digest object
    var md = {
        algorithm: 'sha1',
        blockLength: 64,
        digestLength: 20,
        // 56-bit length of message so far (does not including padding)
        messageLength: 0,
        // true message length
        fullMessageLength: null,
        // size of message length in bytes
        messageLengthSize: 8
    };
    /**
   * Starts the digest.
   *
   * @return this digest object.
   */ md.start = function() {
        // up to 56-bit message length for convenience
        md.messageLength = 0;
        // full message length (set md.messageLength64 for backwards-compatibility)
        md.fullMessageLength = md.messageLength64 = [];
        var int32s = md.messageLengthSize / 4;
        for(var i = 0; i < int32s; ++i)md.fullMessageLength.push(0);
        _input = forge.util.createBuffer();
        _state = {
            h0: 1732584193,
            h1: 4023233417,
            h2: 2562383102,
            h3: 271733878,
            h4: 3285377520
        };
        return md;
    };
    // start digest automatically for first time
    md.start();
    /**
   * Updates the digest with the given message input. The given input can
   * treated as raw input (no encoding will be applied) or an encoding of
   * 'utf8' maybe given to encode the input using UTF-8.
   *
   * @param msg the message input to update with.
   * @param encoding the encoding to use (default: 'raw', other: 'utf8').
   *
   * @return this digest object.
   */ md.update = function(msg, encoding) {
        if (encoding === 'utf8') msg = forge.util.encodeUtf8(msg);
        // update message length
        var len = msg.length;
        md.messageLength += len;
        len = [
            len / 4294967296 >>> 0,
            len >>> 0
        ];
        for(var i = md.fullMessageLength.length - 1; i >= 0; --i){
            md.fullMessageLength[i] += len[1];
            len[1] = len[0] + (md.fullMessageLength[i] / 4294967296 >>> 0);
            md.fullMessageLength[i] = md.fullMessageLength[i] >>> 0;
            len[0] = len[1] / 4294967296 >>> 0;
        }
        // add bytes to input buffer
        _input.putBytes(msg);
        // process bytes
        _update(_state, _w, _input);
        // compact input buffer every 2K or if empty
        if (_input.read > 2048 || _input.length() === 0) _input.compact();
        return md;
    };
    /**
   * Produces the digest.
   *
   * @return a byte buffer containing the digest value.
   */ md.digest = function() {
        /* Note: Here we copy the remaining bytes in the input buffer and
    add the appropriate SHA-1 padding. Then we do the final update
    on a copy of the state so that if the user wants to get
    intermediate digests they can do so. */ /* Determine the number of bytes that must be added to the message
    to ensure its length is congruent to 448 mod 512. In other words,
    the data to be digested must be a multiple of 512 bits (or 128 bytes).
    This data includes the message, some padding, and the length of the
    message. Since the length of the message will be encoded as 8 bytes (64
    bits), that means that the last segment of the data must have 56 bytes
    (448 bits) of message and padding. Therefore, the length of the message
    plus the padding must be congruent to 448 mod 512 because
    512 - 128 = 448.

    In order to fill up the message length it must be filled with
    padding that begins with 1 bit followed by all 0 bits. Padding
    must *always* be present, so if the message length is already
    congruent to 448 mod 512, then 512 padding bits must be added. */ var finalBlock = forge.util.createBuffer();
        finalBlock.putBytes(_input.bytes());
        // compute remaining size to be digested (include message length size)
        var remaining = md.fullMessageLength[md.fullMessageLength.length - 1] + md.messageLengthSize;
        // add padding for overflow blockSize - overflow
        // _padding starts with 1 byte with first bit is set (byte value 128), then
        // there may be up to (blockSize - 1) other pad bytes
        var overflow = remaining & md.blockLength - 1;
        finalBlock.putBytes(_padding.substr(0, md.blockLength - overflow));
        // serialize message length in bits in big-endian order; since length
        // is stored in bytes we multiply by 8 and add carry from next int
        var next, carry;
        var bits = md.fullMessageLength[0] * 8;
        for(var i = 0; i < md.fullMessageLength.length - 1; ++i){
            next = md.fullMessageLength[i + 1] * 8;
            carry = next / 4294967296 >>> 0;
            bits += carry;
            finalBlock.putInt32(bits >>> 0);
            bits = next >>> 0;
        }
        finalBlock.putInt32(bits);
        var s2 = {
            h0: _state.h0,
            h1: _state.h1,
            h2: _state.h2,
            h3: _state.h3,
            h4: _state.h4
        };
        _update(s2, _w, finalBlock);
        var rval = forge.util.createBuffer();
        rval.putInt32(s2.h0);
        rval.putInt32(s2.h1);
        rval.putInt32(s2.h2);
        rval.putInt32(s2.h3);
        rval.putInt32(s2.h4);
        return rval;
    };
    return md;
};
// sha-1 padding bytes not initialized yet
var _padding = null;
var _initialized = false;
/**
 * Initializes the constant tables.
 */ function _init() {
    // create padding
    _padding = String.fromCharCode(128);
    _padding += forge.util.fillString(String.fromCharCode(0), 64);
    // now initialized
    _initialized = true;
}
/**
 * Updates a SHA-1 state with the given byte buffer.
 *
 * @param s the SHA-1 state to update.
 * @param w the array to use to store words.
 * @param bytes the byte buffer to update with.
 */ function _update(s, w, bytes) {
    // consume 512 bit (64 byte) chunks
    var t, a, b, c, d, e, f, i;
    var len = bytes.length();
    while(len >= 64){
        // the w array will be populated with sixteen 32-bit big-endian words
        // and then extended into 80 32-bit words according to SHA-1 algorithm
        // and for 32-79 using Max Locktyukhin's optimization
        // initialize hash value for this chunk
        a = s.h0;
        b = s.h1;
        c = s.h2;
        d = s.h3;
        e = s.h4;
        // round 1
        for(i = 0; i < 16; ++i){
            t = bytes.getInt32();
            w[i] = t;
            f = d ^ b & (c ^ d);
            t = (a << 5 | a >>> 27) + f + e + 1518500249 + t;
            e = d;
            d = c;
            // `>>> 0` necessary to avoid iOS/Safari 10 optimization bug
            c = (b << 30 | b >>> 2) >>> 0;
            b = a;
            a = t;
        }
        for(; i < 20; ++i){
            t = w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16];
            t = t << 1 | t >>> 31;
            w[i] = t;
            f = d ^ b & (c ^ d);
            t = (a << 5 | a >>> 27) + f + e + 1518500249 + t;
            e = d;
            d = c;
            // `>>> 0` necessary to avoid iOS/Safari 10 optimization bug
            c = (b << 30 | b >>> 2) >>> 0;
            b = a;
            a = t;
        }
        // round 2
        for(; i < 32; ++i){
            t = w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16];
            t = t << 1 | t >>> 31;
            w[i] = t;
            f = b ^ c ^ d;
            t = (a << 5 | a >>> 27) + f + e + 1859775393 + t;
            e = d;
            d = c;
            // `>>> 0` necessary to avoid iOS/Safari 10 optimization bug
            c = (b << 30 | b >>> 2) >>> 0;
            b = a;
            a = t;
        }
        for(; i < 40; ++i){
            t = w[i - 6] ^ w[i - 16] ^ w[i - 28] ^ w[i - 32];
            t = t << 2 | t >>> 30;
            w[i] = t;
            f = b ^ c ^ d;
            t = (a << 5 | a >>> 27) + f + e + 1859775393 + t;
            e = d;
            d = c;
            // `>>> 0` necessary to avoid iOS/Safari 10 optimization bug
            c = (b << 30 | b >>> 2) >>> 0;
            b = a;
            a = t;
        }
        // round 3
        for(; i < 60; ++i){
            t = w[i - 6] ^ w[i - 16] ^ w[i - 28] ^ w[i - 32];
            t = t << 2 | t >>> 30;
            w[i] = t;
            f = b & c | d & (b ^ c);
            t = (a << 5 | a >>> 27) + f + e + 2400959708 + t;
            e = d;
            d = c;
            // `>>> 0` necessary to avoid iOS/Safari 10 optimization bug
            c = (b << 30 | b >>> 2) >>> 0;
            b = a;
            a = t;
        }
        // round 4
        for(; i < 80; ++i){
            t = w[i - 6] ^ w[i - 16] ^ w[i - 28] ^ w[i - 32];
            t = t << 2 | t >>> 30;
            w[i] = t;
            f = b ^ c ^ d;
            t = (a << 5 | a >>> 27) + f + e + 3395469782 + t;
            e = d;
            d = c;
            // `>>> 0` necessary to avoid iOS/Safari 10 optimization bug
            c = (b << 30 | b >>> 2) >>> 0;
            b = a;
            a = t;
        }
        // update hash state
        s.h0 = s.h0 + a | 0;
        s.h1 = s.h1 + b | 0;
        s.h2 = s.h2 + c | 0;
        s.h3 = s.h3 + d | 0;
        s.h4 = s.h4 + e | 0;
        len -= 64;
    }
}

},{"./forge":"7AnVp","./md":"9dnCj","./util":"cHj6b"}],"2gGbG":[function(require,module,exports) {
/**
 * Prime number generation API.
 *
 * @author Dave Longley
 *
 * Copyright (c) 2014 Digital Bazaar, Inc.
 */ var forge = require('./forge');
require('./util');
require('./jsbn');
require('./random');
(function() {
    // forge.prime already defined
    if (forge.prime) {
        module.exports = forge.prime;
        return;
    }
    /* PRIME API */ var prime = module.exports = forge.prime = forge.prime || {
    };
    var BigInteger = forge.jsbn.BigInteger;
    // primes are 30k+i for i = 1, 7, 11, 13, 17, 19, 23, 29
    var GCD_30_DELTA = [
        6,
        4,
        2,
        4,
        2,
        4,
        6,
        2
    ];
    var THIRTY = new BigInteger(null);
    THIRTY.fromInt(30);
    var op_or = function(x, y) {
        return x | y;
    };
    /**
 * Generates a random probable prime with the given number of bits.
 *
 * Alternative algorithms can be specified by name as a string or as an
 * object with custom options like so:
 *
 * {
 *   name: 'PRIMEINC',
 *   options: {
 *     maxBlockTime: <the maximum amount of time to block the main
 *       thread before allowing I/O other JS to run>,
 *     millerRabinTests: <the number of miller-rabin tests to run>,
 *     workerScript: <the worker script URL>,
 *     workers: <the number of web workers (if supported) to use,
 *       -1 to use estimated cores minus one>.
 *     workLoad: the size of the work load, ie: number of possible prime
 *       numbers for each web worker to check per work assignment,
 *       (default: 100).
 *   }
 * }
 *
 * @param bits the number of bits for the prime number.
 * @param options the options to use.
 *          [algorithm] the algorithm to use (default: 'PRIMEINC').
 *          [prng] a custom crypto-secure pseudo-random number generator to use,
 *            that must define "getBytesSync".
 *
 * @return callback(err, num) called once the operation completes.
 */ prime.generateProbablePrime = function(bits, options, callback) {
        if (typeof options === 'function') {
            callback = options;
            options = {
            };
        }
        options = options || {
        };
        // default to PRIMEINC algorithm
        var algorithm = options.algorithm || 'PRIMEINC';
        if (typeof algorithm === 'string') algorithm = {
            name: algorithm
        };
        algorithm.options = algorithm.options || {
        };
        // create prng with api that matches BigInteger secure random
        var prng = options.prng || forge.random;
        var rng = {
            // x is an array to fill with bytes
            nextBytes: function(x) {
                var b = prng.getBytesSync(x.length);
                for(var i = 0; i < x.length; ++i)x[i] = b.charCodeAt(i);
            }
        };
        if (algorithm.name === 'PRIMEINC') return primeincFindPrime(bits, rng, algorithm.options, callback);
        throw new Error('Invalid prime generation algorithm: ' + algorithm.name);
    };
    function primeincFindPrime(bits, rng, options, callback) {
        if ('workers' in options) return primeincFindPrimeWithWorkers(bits, rng, options, callback);
        return primeincFindPrimeWithoutWorkers(bits, rng, options, callback);
    }
    function primeincFindPrimeWithoutWorkers(bits, rng, options, callback) {
        // initialize random number
        var num = generateRandom(bits, rng);
        /* Note: All primes are of the form 30k+i for i < 30 and gcd(30, i)=1. The
  number we are given is always aligned at 30k + 1. Each time the number is
  determined not to be prime we add to get to the next 'i', eg: if the number
  was at 30k + 1 we add 6. */ var deltaIdx = 0;
        // get required number of MR tests
        var mrTests = getMillerRabinTests(num.bitLength());
        if ('millerRabinTests' in options) mrTests = options.millerRabinTests;
        // find prime nearest to 'num' for maxBlockTime ms
        // 10 ms gives 5ms of leeway for other calculations before dropping
        // below 60fps (1000/60 == 16.67), but in reality, the number will
        // likely be higher due to an 'atomic' big int modPow
        var maxBlockTime = 10;
        if ('maxBlockTime' in options) maxBlockTime = options.maxBlockTime;
        _primeinc(num, bits, rng, deltaIdx, mrTests, maxBlockTime, callback);
    }
    function _primeinc(num, bits, rng, deltaIdx, mrTests, maxBlockTime, callback) {
        var start = +new Date();
        do {
            // overflow, regenerate random number
            if (num.bitLength() > bits) num = generateRandom(bits, rng);
            // do primality test
            if (num.isProbablePrime(mrTests)) return callback(null, num);
            // get next potential prime
            num.dAddOffset(GCD_30_DELTA[(deltaIdx++) % 8], 0);
        }while (maxBlockTime < 0 || +new Date() - start < maxBlockTime)
        // keep trying later
        forge.util.setImmediate(function() {
            _primeinc(num, bits, rng, deltaIdx, mrTests, maxBlockTime, callback);
        });
    }
    // NOTE: This algorithm is indeterminate in nature because workers
    // run in parallel looking at different segments of numbers. Even if this
    // algorithm is run twice with the same input from a predictable RNG, it
    // may produce different outputs.
    function primeincFindPrimeWithWorkers(bits, rng, options, callback) {
        // web workers unavailable
        if (typeof Worker === 'undefined') return primeincFindPrimeWithoutWorkers(bits, rng, options, callback);
        // initialize random number
        var num = generateRandom(bits, rng);
        // use web workers to generate keys
        var numWorkers = options.workers;
        var workLoad = options.workLoad || 100;
        var range = workLoad * 30 / 8;
        var workerScript = options.workerScript || 'forge/prime.worker.js';
        if (numWorkers === -1) return forge.util.estimateCores(function(err, cores) {
            if (err) // default to 2
            cores = 2;
            numWorkers = cores - 1;
            generate();
        });
        generate();
        function generate() {
            // require at least 1 worker
            numWorkers = Math.max(1, numWorkers);
            // TODO: consider optimizing by starting workers outside getPrime() ...
            // note that in order to clean up they will have to be made internally
            // asynchronous which may actually be slower
            // start workers immediately
            var workers = [];
            for(var i1 = 0; i1 < numWorkers; ++i1)// FIXME: fix path or use blob URLs
            workers[i1] = new Worker(workerScript);
            var running = numWorkers;
            // listen for requests from workers and assign ranges to find prime
            for(var i1 = 0; i1 < numWorkers; ++i1)workers[i1].addEventListener('message', workerMessage);
            /* Note: The distribution of random numbers is unknown. Therefore, each
    web worker is continuously allocated a range of numbers to check for a
    random number until one is found.

    Every 30 numbers will be checked just 8 times, because prime numbers
    have the form:

    30k+i, for i < 30 and gcd(30, i)=1 (there are 8 values of i for this)

    Therefore, if we want a web worker to run N checks before asking for
    a new range of numbers, each range must contain N*30/8 numbers.

    For 100 checks (workLoad), this is a range of 375. */ var found = false;
            function workerMessage(e) {
                // ignore message, prime already found
                if (found) return;
                --running;
                var data = e.data;
                if (data.found) {
                    // terminate all workers
                    for(var i = 0; i < workers.length; ++i)workers[i].terminate();
                    found = true;
                    return callback(null, new BigInteger(data.prime, 16));
                }
                // overflow, regenerate random number
                if (num.bitLength() > bits) num = generateRandom(bits, rng);
                // assign new range to check
                var hex = num.toString(16);
                // start prime search
                e.target.postMessage({
                    hex: hex,
                    workLoad: workLoad
                });
                num.dAddOffset(range, 0);
            }
        }
    }
    /**
 * Generates a random number using the given number of bits and RNG.
 *
 * @param bits the number of bits for the number.
 * @param rng the random number generator to use.
 *
 * @return the random number.
 */ function generateRandom(bits, rng) {
        var num = new BigInteger(bits, rng);
        // force MSB set
        var bits1 = bits - 1;
        if (!num.testBit(bits1)) num.bitwiseTo(BigInteger.ONE.shiftLeft(bits1), op_or, num);
        // align number on 30k+1 boundary
        num.dAddOffset(31 - num.mod(THIRTY).byteValue(), 0);
        return num;
    }
    /**
 * Returns the required number of Miller-Rabin tests to generate a
 * prime with an error probability of (1/2)^80.
 *
 * See Handbook of Applied Cryptography Chapter 4, Table 4.4.
 *
 * @param bits the bit size.
 *
 * @return the required number of iterations.
 */ function getMillerRabinTests(bits) {
        if (bits <= 100) return 27;
        if (bits <= 150) return 18;
        if (bits <= 200) return 15;
        if (bits <= 250) return 12;
        if (bits <= 300) return 9;
        if (bits <= 350) return 8;
        if (bits <= 400) return 7;
        if (bits <= 500) return 6;
        if (bits <= 600) return 5;
        if (bits <= 800) return 4;
        if (bits <= 1250) return 3;
        return 2;
    }
})();

},{"./forge":"7AnVp","./util":"cHj6b","./jsbn":"6OVnc","./random":"7GrCn"}],"8gaLA":[function(require,module,exports) {
'use strict';
const { base64  } = require('multiformats/bases/base64');
const ciphers = require('../ciphers/aes-gcm');
module.exports = {
    /**
   * Attempts to decrypt a base64 encoded PrivateKey string
   * with the given password. The privateKey must have been exported
   * using the same password and underlying cipher (aes-gcm)
   *
   * @param {string} privateKey - A base64 encoded encrypted key
   * @param {string} password
   * @returns {Promise<Uint8Array>} The private key protobuf
   */ import: async function(privateKey, password) {
        const encryptedKey = base64.decode(privateKey);
        const cipher = ciphers.create();
        return await cipher.decrypt(encryptedKey, password);
    }
};

},{"multiformats/bases/base64":"7Lo1j","../ciphers/aes-gcm":"cNDE6"}],"cNDE6":[function(require,module,exports) {
'use strict';
const { concat  } = require('uint8arrays/concat');
const { fromString  } = require('uint8arrays/from-string');
const webcrypto = require('../webcrypto');
// Based off of code from https://github.com/luke-park/SecureCompatibleEncryptionExamples
/**
 *
 * @param {object} [options]
 * @param {string} [options.algorithm=AES-GCM]
 * @param {number} [options.nonceLength=12]
 * @param {number} [options.keyLength=16]
 * @param {string} [options.digest=sha256]
 * @param {number} [options.saltLength=16]
 * @param {number} [options.iterations=32767]
 * @returns {*}
 */ function create({ algorithm ='AES-GCM' , nonceLength =12 , keyLength =16 , digest ='SHA-256' , saltLength =16 , iterations =32767  } = {
}) {
    const crypto = webcrypto.get();
    keyLength *= 8 // Browser crypto uses bits instead of bytes
    ;
    /**
   * Uses the provided password to derive a pbkdf2 key. The key
   * will then be used to encrypt the data.
   *
   * @param {Uint8Array} data - The data to decrypt
   * @param {string} password - A plain password
   * @returns {Promise<Uint8Array>}
   */ async function encrypt(data, password) {
        const salt = crypto.getRandomValues(new Uint8Array(saltLength));
        const nonce = crypto.getRandomValues(new Uint8Array(nonceLength));
        const aesGcm = {
            name: algorithm,
            iv: nonce
        };
        // Derive a key using PBKDF2.
        const deriveParams = {
            name: 'PBKDF2',
            salt,
            iterations,
            hash: {
                name: digest
            }
        };
        const rawKey = await crypto.subtle.importKey('raw', fromString(password), {
            name: 'PBKDF2'
        }, false, [
            'deriveKey',
            'deriveBits'
        ]);
        const cryptoKey = await crypto.subtle.deriveKey(deriveParams, rawKey, {
            name: algorithm,
            length: keyLength
        }, true, [
            'encrypt'
        ]);
        // Encrypt the string.
        const ciphertext = await crypto.subtle.encrypt(aesGcm, cryptoKey, data);
        return concat([
            salt,
            aesGcm.iv,
            new Uint8Array(ciphertext)
        ]);
    }
    /**
   * Uses the provided password to derive a pbkdf2 key. The key
   * will then be used to decrypt the data. The options used to create
   * this decryption cipher must be the same as those used to create
   * the encryption cipher.
   *
   * @param {Uint8Array} data - The data to decrypt
   * @param {string} password - A plain password
   * @returns {Promise<Uint8Array>}
   */ async function decrypt(data, password) {
        const salt = data.slice(0, saltLength);
        const nonce = data.slice(saltLength, saltLength + nonceLength);
        const ciphertext = data.slice(saltLength + nonceLength);
        const aesGcm = {
            name: algorithm,
            iv: nonce
        };
        // Derive the key using PBKDF2.
        const deriveParams = {
            name: 'PBKDF2',
            salt,
            iterations,
            hash: {
                name: digest
            }
        };
        const rawKey = await crypto.subtle.importKey('raw', fromString(password), {
            name: 'PBKDF2'
        }, false, [
            'deriveKey',
            'deriveBits'
        ]);
        const cryptoKey = await crypto.subtle.deriveKey(deriveParams, rawKey, {
            name: algorithm,
            length: keyLength
        }, true, [
            'decrypt'
        ]);
        // Decrypt the string.
        const plaintext = await crypto.subtle.decrypt(aesGcm, cryptoKey, ciphertext);
        return new Uint8Array(plaintext);
    }
    return {
        encrypt,
        decrypt
    };
}
module.exports = {
    create
};

},{"uint8arrays/concat":"fLIrL","uint8arrays/from-string":"lo45E","../webcrypto":"hKlQS"}],"hKlQS":[function(require,module,exports) {
/* eslint-env browser */ 'use strict';
// Check native crypto exists and is enabled (In insecure context `self.crypto`
// exists but `self.crypto.subtle` does not).
exports.get = (win = self)=>{
    const nativeCrypto = win.crypto || win.msCrypto;
    if (!nativeCrypto || !nativeCrypto.subtle) throw Object.assign(new Error("Missing Web Crypto API. The most likely cause of this error is that this page is being accessed from an insecure context (i.e. not HTTPS). For more information and possible resolutions see https://github.com/libp2p/js-libp2p-crypto/blob/master/README.md#web-crypto-api"), {
        code: 'ERR_MISSING_WEB_CRYPTO'
    });
    return nativeCrypto;
};

},{}],"F5NLK":[function(require,module,exports) {
'use strict';
const { sha256  } = require('multiformats/hashes/sha2');
const errcode = require('err-code');
const { equals: uint8ArrayEquals  } = require('uint8arrays/equals');
const { toString: uint8ArrayToString  } = require('uint8arrays/to-string');
require('node-forge/lib/sha512');
require('node-forge/lib/ed25519');
const forge = require('node-forge/lib/forge');
const crypto = require('./rsa');
const pbm = require('./keys');
const exporter = require('./exporter');
class RsaPublicKey {
    constructor(key){
        this._key = key;
    }
    async verify(data, sig) {
        return crypto.hashAndVerify(this._key, sig, data);
    }
    marshal() {
        return crypto.utils.jwkToPkix(this._key);
    }
    get bytes() {
        return pbm.PublicKey.encode({
            Type: pbm.KeyType.RSA,
            Data: this.marshal()
        }).finish();
    }
    encrypt(bytes2) {
        return crypto.encrypt(this._key, bytes2);
    }
    equals(key1) {
        return uint8ArrayEquals(this.bytes, key1.bytes);
    }
    async hash() {
        const { bytes  } = await sha256.digest(this.bytes);
        return bytes;
    }
}
class RsaPrivateKey {
    // key       - Object of the jwk format
    // publicKey - Uint8Array of the spki format
    constructor(key2, publicKey){
        this._key = key2;
        this._publicKey = publicKey;
    }
    genSecret() {
        return crypto.getRandomValues(16);
    }
    async sign(message) {
        return crypto.hashAndSign(this._key, message);
    }
    get public() {
        if (!this._publicKey) throw errcode(new Error('public key not provided'), 'ERR_PUBKEY_NOT_PROVIDED');
        return new RsaPublicKey(this._publicKey);
    }
    decrypt(bytes1) {
        return crypto.decrypt(this._key, bytes1);
    }
    marshal() {
        return crypto.utils.jwkToPkcs1(this._key);
    }
    get bytes() {
        return pbm.PrivateKey.encode({
            Type: pbm.KeyType.RSA,
            Data: this.marshal()
        }).finish();
    }
    equals(key3) {
        return uint8ArrayEquals(this.bytes, key3.bytes);
    }
    async hash() {
        const { bytes  } = await sha256.digest(this.bytes);
        return bytes;
    }
    /**
   * Gets the ID of the key.
   *
   * The key id is the base58 encoding of the SHA-256 multihash of its public key.
   * The public key is a protobuf encoding containing a type and the DER encoding
   * of the PKCS SubjectPublicKeyInfo.
   *
   * @returns {Promise<string>}
   */ async id() {
        const hash = await this.public.hash();
        return uint8ArrayToString(hash, 'base58btc');
    }
    /**
   * Exports the key into a password protected PEM format
   *
   * @param {string} password - The password to read the encrypted PEM
   * @param {string} [format=pkcs-8] - The format in which to export as
   */ async export(password, format = 'pkcs-8') {
        if (format === 'pkcs-8') {
            const buffer = new forge.util.ByteBuffer(this.marshal());
            const asn1 = forge.asn1.fromDer(buffer);
            const privateKey = forge.pki.privateKeyFromAsn1(asn1);
            const options = {
                algorithm: 'aes256',
                count: 10000,
                saltSize: 16,
                prfAlgorithm: 'sha512'
            };
            return forge.pki.encryptRsaPrivateKey(privateKey, password, options);
        } else if (format === 'libp2p-key') return exporter.export(this.bytes, password);
        else throw errcode(new Error(`export format '${format}' is not supported`), 'ERR_INVALID_EXPORT_FORMAT');
    }
}
async function unmarshalRsaPrivateKey(bytes) {
    const jwk = crypto.utils.pkcs1ToJwk(bytes);
    const keys = await crypto.unmarshalPrivateKey(jwk);
    return new RsaPrivateKey(keys.privateKey, keys.publicKey);
}
function unmarshalRsaPublicKey(bytes) {
    const jwk = crypto.utils.pkixToJwk(bytes);
    return new RsaPublicKey(jwk);
}
async function fromJwk(jwk) {
    const keys = await crypto.unmarshalPrivateKey(jwk);
    return new RsaPrivateKey(keys.privateKey, keys.publicKey);
}
async function generateKeyPair(bits) {
    const keys = await crypto.generateKey(bits);
    return new RsaPrivateKey(keys.privateKey, keys.publicKey);
}
module.exports = {
    RsaPublicKey,
    RsaPrivateKey,
    unmarshalRsaPublicKey,
    unmarshalRsaPrivateKey,
    generateKeyPair,
    fromJwk
};

},{"multiformats/hashes/sha2":"i8JnP","err-code":"eQvyh","uint8arrays/equals":"fjLeN","uint8arrays/to-string":"g3mCQ","node-forge/lib/sha512":"kidGB","node-forge/lib/ed25519":"3DfIA","node-forge/lib/forge":"7AnVp","./rsa":"gtCsO","./keys":"jQuh5","./exporter":"3mrEx"}],"kidGB":[function(require,module,exports) {
/**
 * Secure Hash Algorithm with a 1024-bit block size implementation.
 *
 * This includes: SHA-512, SHA-384, SHA-512/224, and SHA-512/256. For
 * SHA-256 (block size 512 bits), see sha256.js.
 *
 * See FIPS 180-4 for details.
 *
 * @author Dave Longley
 *
 * Copyright (c) 2014-2015 Digital Bazaar, Inc.
 */ var forge = require('./forge');
require('./md');
require('./util');
var sha512 = module.exports = forge.sha512 = forge.sha512 || {
};
// SHA-512
forge.md.sha512 = forge.md.algorithms.sha512 = sha512;
// SHA-384
var sha384 = forge.sha384 = forge.sha512.sha384 = forge.sha512.sha384 || {
};
sha384.create = function() {
    return sha512.create('SHA-384');
};
forge.md.sha384 = forge.md.algorithms.sha384 = sha384;
// SHA-512/256
forge.sha512.sha256 = forge.sha512.sha256 || {
    create: function() {
        return sha512.create('SHA-512/256');
    }
};
forge.md['sha512/256'] = forge.md.algorithms['sha512/256'] = forge.sha512.sha256;
// SHA-512/224
forge.sha512.sha224 = forge.sha512.sha224 || {
    create: function() {
        return sha512.create('SHA-512/224');
    }
};
forge.md['sha512/224'] = forge.md.algorithms['sha512/224'] = forge.sha512.sha224;
/**
 * Creates a SHA-2 message digest object.
 *
 * @param algorithm the algorithm to use (SHA-512, SHA-384, SHA-512/224,
 *          SHA-512/256).
 *
 * @return a message digest object.
 */ sha512.create = function(algorithm) {
    // do initialization as necessary
    if (!_initialized) _init();
    if (typeof algorithm === 'undefined') algorithm = 'SHA-512';
    if (!(algorithm in _states)) throw new Error('Invalid SHA-512 algorithm: ' + algorithm);
    // SHA-512 state contains eight 64-bit integers (each as two 32-bit ints)
    var _state = _states[algorithm];
    var _h = null;
    // input buffer
    var _input = forge.util.createBuffer();
    // used for 64-bit word storage
    var _w = new Array(80);
    for(var wi = 0; wi < 80; ++wi)_w[wi] = new Array(2);
    // determine digest length by algorithm name (default)
    var digestLength = 64;
    switch(algorithm){
        case 'SHA-384':
            digestLength = 48;
            break;
        case 'SHA-512/256':
            digestLength = 32;
            break;
        case 'SHA-512/224':
            digestLength = 28;
            break;
    }
    // message digest object
    var md = {
        // SHA-512 => sha512
        algorithm: algorithm.replace('-', '').toLowerCase(),
        blockLength: 128,
        digestLength: digestLength,
        // 56-bit length of message so far (does not including padding)
        messageLength: 0,
        // true message length
        fullMessageLength: null,
        // size of message length in bytes
        messageLengthSize: 16
    };
    /**
   * Starts the digest.
   *
   * @return this digest object.
   */ md.start = function() {
        // up to 56-bit message length for convenience
        md.messageLength = 0;
        // full message length (set md.messageLength128 for backwards-compatibility)
        md.fullMessageLength = md.messageLength128 = [];
        var int32s = md.messageLengthSize / 4;
        for(var i = 0; i < int32s; ++i)md.fullMessageLength.push(0);
        _input = forge.util.createBuffer();
        _h = new Array(_state.length);
        for(var i = 0; i < _state.length; ++i)_h[i] = _state[i].slice(0);
        return md;
    };
    // start digest automatically for first time
    md.start();
    /**
   * Updates the digest with the given message input. The given input can
   * treated as raw input (no encoding will be applied) or an encoding of
   * 'utf8' maybe given to encode the input using UTF-8.
   *
   * @param msg the message input to update with.
   * @param encoding the encoding to use (default: 'raw', other: 'utf8').
   *
   * @return this digest object.
   */ md.update = function(msg, encoding) {
        if (encoding === 'utf8') msg = forge.util.encodeUtf8(msg);
        // update message length
        var len = msg.length;
        md.messageLength += len;
        len = [
            len / 4294967296 >>> 0,
            len >>> 0
        ];
        for(var i = md.fullMessageLength.length - 1; i >= 0; --i){
            md.fullMessageLength[i] += len[1];
            len[1] = len[0] + (md.fullMessageLength[i] / 4294967296 >>> 0);
            md.fullMessageLength[i] = md.fullMessageLength[i] >>> 0;
            len[0] = len[1] / 4294967296 >>> 0;
        }
        // add bytes to input buffer
        _input.putBytes(msg);
        // process bytes
        _update(_h, _w, _input);
        // compact input buffer every 2K or if empty
        if (_input.read > 2048 || _input.length() === 0) _input.compact();
        return md;
    };
    /**
   * Produces the digest.
   *
   * @return a byte buffer containing the digest value.
   */ md.digest = function() {
        /* Note: Here we copy the remaining bytes in the input buffer and
    add the appropriate SHA-512 padding. Then we do the final update
    on a copy of the state so that if the user wants to get
    intermediate digests they can do so. */ /* Determine the number of bytes that must be added to the message
    to ensure its length is congruent to 896 mod 1024. In other words,
    the data to be digested must be a multiple of 1024 bits (or 128 bytes).
    This data includes the message, some padding, and the length of the
    message. Since the length of the message will be encoded as 16 bytes (128
    bits), that means that the last segment of the data must have 112 bytes
    (896 bits) of message and padding. Therefore, the length of the message
    plus the padding must be congruent to 896 mod 1024 because
    1024 - 128 = 896.

    In order to fill up the message length it must be filled with
    padding that begins with 1 bit followed by all 0 bits. Padding
    must *always* be present, so if the message length is already
    congruent to 896 mod 1024, then 1024 padding bits must be added. */ var finalBlock = forge.util.createBuffer();
        finalBlock.putBytes(_input.bytes());
        // compute remaining size to be digested (include message length size)
        var remaining = md.fullMessageLength[md.fullMessageLength.length - 1] + md.messageLengthSize;
        // add padding for overflow blockSize - overflow
        // _padding starts with 1 byte with first bit is set (byte value 128), then
        // there may be up to (blockSize - 1) other pad bytes
        var overflow = remaining & md.blockLength - 1;
        finalBlock.putBytes(_padding.substr(0, md.blockLength - overflow));
        // serialize message length in bits in big-endian order; since length
        // is stored in bytes we multiply by 8 and add carry from next int
        var next, carry;
        var bits = md.fullMessageLength[0] * 8;
        for(var i = 0; i < md.fullMessageLength.length - 1; ++i){
            next = md.fullMessageLength[i + 1] * 8;
            carry = next / 4294967296 >>> 0;
            bits += carry;
            finalBlock.putInt32(bits >>> 0);
            bits = next >>> 0;
        }
        finalBlock.putInt32(bits);
        var h = new Array(_h.length);
        for(var i = 0; i < _h.length; ++i)h[i] = _h[i].slice(0);
        _update(h, _w, finalBlock);
        var rval = forge.util.createBuffer();
        var hlen;
        if (algorithm === 'SHA-512') hlen = h.length;
        else if (algorithm === 'SHA-384') hlen = h.length - 2;
        else hlen = h.length - 4;
        for(var i = 0; i < hlen; ++i){
            rval.putInt32(h[i][0]);
            if (i !== hlen - 1 || algorithm !== 'SHA-512/224') rval.putInt32(h[i][1]);
        }
        return rval;
    };
    return md;
};
// sha-512 padding bytes not initialized yet
var _padding = null;
var _initialized = false;
// table of constants
var _k = null;
// initial hash states
var _states = null;
/**
 * Initializes the constant tables.
 */ function _init() {
    // create padding
    _padding = String.fromCharCode(128);
    _padding += forge.util.fillString(String.fromCharCode(0), 128);
    // create K table for SHA-512
    _k = [
        [
            1116352408,
            3609767458
        ],
        [
            1899447441,
            602891725
        ],
        [
            3049323471,
            3964484399
        ],
        [
            3921009573,
            2173295548
        ],
        [
            961987163,
            4081628472
        ],
        [
            1508970993,
            3053834265
        ],
        [
            2453635748,
            2937671579
        ],
        [
            2870763221,
            3664609560
        ],
        [
            3624381080,
            2734883394
        ],
        [
            310598401,
            1164996542
        ],
        [
            607225278,
            1323610764
        ],
        [
            1426881987,
            3590304994
        ],
        [
            1925078388,
            4068182383
        ],
        [
            2162078206,
            991336113
        ],
        [
            2614888103,
            633803317
        ],
        [
            3248222580,
            3479774868
        ],
        [
            3835390401,
            2666613458
        ],
        [
            4022224774,
            944711139
        ],
        [
            264347078,
            2341262773
        ],
        [
            604807628,
            2007800933
        ],
        [
            770255983,
            1495990901
        ],
        [
            1249150122,
            1856431235
        ],
        [
            1555081692,
            3175218132
        ],
        [
            1996064986,
            2198950837
        ],
        [
            2554220882,
            3999719339
        ],
        [
            2821834349,
            766784016
        ],
        [
            2952996808,
            2566594879
        ],
        [
            3210313671,
            3203337956
        ],
        [
            3336571891,
            1034457026
        ],
        [
            3584528711,
            2466948901
        ],
        [
            113926993,
            3758326383
        ],
        [
            338241895,
            168717936
        ],
        [
            666307205,
            1188179964
        ],
        [
            773529912,
            1546045734
        ],
        [
            1294757372,
            1522805485
        ],
        [
            1396182291,
            2643833823
        ],
        [
            1695183700,
            2343527390
        ],
        [
            1986661051,
            1014477480
        ],
        [
            2177026350,
            1206759142
        ],
        [
            2456956037,
            344077627
        ],
        [
            2730485921,
            1290863460
        ],
        [
            2820302411,
            3158454273
        ],
        [
            3259730800,
            3505952657
        ],
        [
            3345764771,
            106217008
        ],
        [
            3516065817,
            3606008344
        ],
        [
            3600352804,
            1432725776
        ],
        [
            4094571909,
            1467031594
        ],
        [
            275423344,
            851169720
        ],
        [
            430227734,
            3100823752
        ],
        [
            506948616,
            1363258195
        ],
        [
            659060556,
            3750685593
        ],
        [
            883997877,
            3785050280
        ],
        [
            958139571,
            3318307427
        ],
        [
            1322822218,
            3812723403
        ],
        [
            1537002063,
            2003034995
        ],
        [
            1747873779,
            3602036899
        ],
        [
            1955562222,
            1575990012
        ],
        [
            2024104815,
            1125592928
        ],
        [
            2227730452,
            2716904306
        ],
        [
            2361852424,
            442776044
        ],
        [
            2428436474,
            593698344
        ],
        [
            2756734187,
            3733110249
        ],
        [
            3204031479,
            2999351573
        ],
        [
            3329325298,
            3815920427
        ],
        [
            3391569614,
            3928383900
        ],
        [
            3515267271,
            566280711
        ],
        [
            3940187606,
            3454069534
        ],
        [
            4118630271,
            4000239992
        ],
        [
            116418474,
            1914138554
        ],
        [
            174292421,
            2731055270
        ],
        [
            289380356,
            3203993006
        ],
        [
            460393269,
            320620315
        ],
        [
            685471733,
            587496836
        ],
        [
            852142971,
            1086792851
        ],
        [
            1017036298,
            365543100
        ],
        [
            1126000580,
            2618297676
        ],
        [
            1288033470,
            3409855158
        ],
        [
            1501505948,
            4234509866
        ],
        [
            1607167915,
            987167468
        ],
        [
            1816402316,
            1246189591
        ]
    ];
    // initial hash states
    _states = {
    };
    _states['SHA-512'] = [
        [
            1779033703,
            4089235720
        ],
        [
            3144134277,
            2227873595
        ],
        [
            1013904242,
            4271175723
        ],
        [
            2773480762,
            1595750129
        ],
        [
            1359893119,
            2917565137
        ],
        [
            2600822924,
            725511199
        ],
        [
            528734635,
            4215389547
        ],
        [
            1541459225,
            327033209
        ]
    ];
    _states['SHA-384'] = [
        [
            3418070365,
            3238371032
        ],
        [
            1654270250,
            914150663
        ],
        [
            2438529370,
            812702999
        ],
        [
            355462360,
            4144912697
        ],
        [
            1731405415,
            4290775857
        ],
        [
            2394180231,
            1750603025
        ],
        [
            3675008525,
            1694076839
        ],
        [
            1203062813,
            3204075428
        ]
    ];
    _states['SHA-512/256'] = [
        [
            573645204,
            4230739756
        ],
        [
            2673172387,
            3360449730
        ],
        [
            596883563,
            1867755857
        ],
        [
            2520282905,
            1497426621
        ],
        [
            2519219938,
            2827943907
        ],
        [
            3193839141,
            1401305490
        ],
        [
            721525244,
            746961066
        ],
        [
            246885852,
            2177182882
        ]
    ];
    _states['SHA-512/224'] = [
        [
            2352822216,
            424955298
        ],
        [
            1944164710,
            2312950998
        ],
        [
            502970286,
            855612546
        ],
        [
            1738396948,
            1479516111
        ],
        [
            258812777,
            2077511080
        ],
        [
            2011393907,
            79989058
        ],
        [
            1067287976,
            1780299464
        ],
        [
            286451373,
            2446758561
        ]
    ];
    // now initialized
    _initialized = true;
}
/**
 * Updates a SHA-512 state with the given byte buffer.
 *
 * @param s the SHA-512 state to update.
 * @param w the array to use to store words.
 * @param bytes the byte buffer to update with.
 */ function _update(s, w, bytes) {
    // consume 512 bit (128 byte) chunks
    var t1_hi, t1_lo;
    var t2_hi, t2_lo;
    var s0_hi, s0_lo;
    var s1_hi, s1_lo;
    var ch_hi, ch_lo;
    var maj_hi, maj_lo;
    var a_hi, a_lo;
    var b_hi, b_lo;
    var c_hi, c_lo;
    var d_hi, d_lo;
    var e_hi, e_lo;
    var f_hi, f_lo;
    var g_hi, g_lo;
    var h_hi, h_lo;
    var i, hi, lo, w2, w7, w15, w16;
    var len = bytes.length();
    while(len >= 128){
        // the w array will be populated with sixteen 64-bit big-endian words
        // and then extended into 64 64-bit words according to SHA-512
        for(i = 0; i < 16; ++i){
            w[i][0] = bytes.getInt32() >>> 0;
            w[i][1] = bytes.getInt32() >>> 0;
        }
        for(; i < 80; ++i){
            // for word 2 words ago: ROTR 19(x) ^ ROTR 61(x) ^ SHR 6(x)
            w2 = w[i - 2];
            hi = w2[0];
            lo = w2[1];
            // high bits
            t1_hi = ((hi >>> 19 | lo << 13) ^ (lo >>> 29 | hi << 3) ^ hi >>> 6) >>> 0; // SHR 6
            // low bits
            t1_lo = ((hi << 13 | lo >>> 19) ^ (lo << 3 | hi >>> 29) ^ (hi << 26 | lo >>> 6)) >>> 0; // SHR 6
            // for word 15 words ago: ROTR 1(x) ^ ROTR 8(x) ^ SHR 7(x)
            w15 = w[i - 15];
            hi = w15[0];
            lo = w15[1];
            // high bits
            t2_hi = ((hi >>> 1 | lo << 31) ^ (hi >>> 8 | lo << 24) ^ hi >>> 7) >>> 0; // SHR 7
            // low bits
            t2_lo = ((hi << 31 | lo >>> 1) ^ (hi << 24 | lo >>> 8) ^ (hi << 25 | lo >>> 7)) >>> 0; // SHR 7
            // sum(t1, word 7 ago, t2, word 16 ago) modulo 2^64 (carry lo overflow)
            w7 = w[i - 7];
            w16 = w[i - 16];
            lo = t1_lo + w7[1] + t2_lo + w16[1];
            w[i][0] = t1_hi + w7[0] + t2_hi + w16[0] + (lo / 4294967296 >>> 0) >>> 0;
            w[i][1] = lo >>> 0;
        }
        // initialize hash value for this chunk
        a_hi = s[0][0];
        a_lo = s[0][1];
        b_hi = s[1][0];
        b_lo = s[1][1];
        c_hi = s[2][0];
        c_lo = s[2][1];
        d_hi = s[3][0];
        d_lo = s[3][1];
        e_hi = s[4][0];
        e_lo = s[4][1];
        f_hi = s[5][0];
        f_lo = s[5][1];
        g_hi = s[6][0];
        g_lo = s[6][1];
        h_hi = s[7][0];
        h_lo = s[7][1];
        // round function
        for(i = 0; i < 80; ++i){
            // Sum1(e) = ROTR 14(e) ^ ROTR 18(e) ^ ROTR 41(e)
            s1_hi = ((e_hi >>> 14 | e_lo << 18) ^ (e_hi >>> 18 | e_lo << 14) ^ (e_lo >>> 9 | e_hi << 23)) >>> 0; // ROTR 41/(swap + ROTR 9)
            s1_lo = ((e_hi << 18 | e_lo >>> 14) ^ (e_hi << 14 | e_lo >>> 18) ^ (e_lo << 23 | e_hi >>> 9)) >>> 0; // ROTR 41/(swap + ROTR 9)
            // Ch(e, f, g) (optimized the same way as SHA-1)
            ch_hi = (g_hi ^ e_hi & (f_hi ^ g_hi)) >>> 0;
            ch_lo = (g_lo ^ e_lo & (f_lo ^ g_lo)) >>> 0;
            // Sum0(a) = ROTR 28(a) ^ ROTR 34(a) ^ ROTR 39(a)
            s0_hi = ((a_hi >>> 28 | a_lo << 4) ^ (a_lo >>> 2 | a_hi << 30) ^ (a_lo >>> 7 | a_hi << 25)) >>> 0; // ROTR 39/(swap + ROTR 7)
            s0_lo = ((a_hi << 4 | a_lo >>> 28) ^ (a_lo << 30 | a_hi >>> 2) ^ (a_lo << 25 | a_hi >>> 7)) >>> 0; // ROTR 39/(swap + ROTR 7)
            // Maj(a, b, c) (optimized the same way as SHA-1)
            maj_hi = (a_hi & b_hi | c_hi & (a_hi ^ b_hi)) >>> 0;
            maj_lo = (a_lo & b_lo | c_lo & (a_lo ^ b_lo)) >>> 0;
            // main algorithm
            // t1 = (h + s1 + ch + _k[i] + _w[i]) modulo 2^64 (carry lo overflow)
            lo = h_lo + s1_lo + ch_lo + _k[i][1] + w[i][1];
            t1_hi = h_hi + s1_hi + ch_hi + _k[i][0] + w[i][0] + (lo / 4294967296 >>> 0) >>> 0;
            t1_lo = lo >>> 0;
            // t2 = s0 + maj modulo 2^64 (carry lo overflow)
            lo = s0_lo + maj_lo;
            t2_hi = s0_hi + maj_hi + (lo / 4294967296 >>> 0) >>> 0;
            t2_lo = lo >>> 0;
            h_hi = g_hi;
            h_lo = g_lo;
            g_hi = f_hi;
            g_lo = f_lo;
            f_hi = e_hi;
            f_lo = e_lo;
            // e = (d + t1) modulo 2^64 (carry lo overflow)
            lo = d_lo + t1_lo;
            e_hi = d_hi + t1_hi + (lo / 4294967296 >>> 0) >>> 0;
            e_lo = lo >>> 0;
            d_hi = c_hi;
            d_lo = c_lo;
            c_hi = b_hi;
            c_lo = b_lo;
            b_hi = a_hi;
            b_lo = a_lo;
            // a = (t1 + t2) modulo 2^64 (carry lo overflow)
            lo = t1_lo + t2_lo;
            a_hi = t1_hi + t2_hi + (lo / 4294967296 >>> 0) >>> 0;
            a_lo = lo >>> 0;
        }
        // update hash state (additional modulo 2^64)
        lo = s[0][1] + a_lo;
        s[0][0] = s[0][0] + a_hi + (lo / 4294967296 >>> 0) >>> 0;
        s[0][1] = lo >>> 0;
        lo = s[1][1] + b_lo;
        s[1][0] = s[1][0] + b_hi + (lo / 4294967296 >>> 0) >>> 0;
        s[1][1] = lo >>> 0;
        lo = s[2][1] + c_lo;
        s[2][0] = s[2][0] + c_hi + (lo / 4294967296 >>> 0) >>> 0;
        s[2][1] = lo >>> 0;
        lo = s[3][1] + d_lo;
        s[3][0] = s[3][0] + d_hi + (lo / 4294967296 >>> 0) >>> 0;
        s[3][1] = lo >>> 0;
        lo = s[4][1] + e_lo;
        s[4][0] = s[4][0] + e_hi + (lo / 4294967296 >>> 0) >>> 0;
        s[4][1] = lo >>> 0;
        lo = s[5][1] + f_lo;
        s[5][0] = s[5][0] + f_hi + (lo / 4294967296 >>> 0) >>> 0;
        s[5][1] = lo >>> 0;
        lo = s[6][1] + g_lo;
        s[6][0] = s[6][0] + g_hi + (lo / 4294967296 >>> 0) >>> 0;
        s[6][1] = lo >>> 0;
        lo = s[7][1] + h_lo;
        s[7][0] = s[7][0] + h_hi + (lo / 4294967296 >>> 0) >>> 0;
        s[7][1] = lo >>> 0;
        len -= 128;
    }
}

},{"./forge":"7AnVp","./md":"9dnCj","./util":"cHj6b"}],"3DfIA":[function(require,module,exports) {
var Buffer = require("buffer").Buffer;
/**
 * JavaScript implementation of Ed25519.
 *
 * Copyright (c) 2017-2019 Digital Bazaar, Inc.
 *
 * This implementation is based on the most excellent TweetNaCl which is
 * in the public domain. Many thanks to its contributors:
 *
 * https://github.com/dchest/tweetnacl-js
 */ var forge = require('./forge');
require('./jsbn');
require('./random');
require('./sha512');
require('./util');
var asn1Validator = require('./asn1-validator');
var publicKeyValidator = asn1Validator.publicKeyValidator;
var privateKeyValidator = asn1Validator.privateKeyValidator;
if (typeof BigInteger === 'undefined') var BigInteger = forge.jsbn.BigInteger;
var ByteBuffer = forge.util.ByteBuffer;
var NativeBuffer = typeof Buffer === 'undefined' ? Uint8Array : Buffer;
/*
 * Ed25519 algorithms, see RFC 8032:
 * https://tools.ietf.org/html/rfc8032
 */ forge.pki = forge.pki || {
};
module.exports = forge.pki.ed25519 = forge.ed25519 = forge.ed25519 || {
};
var ed25519 = forge.ed25519;
ed25519.constants = {
};
ed25519.constants.PUBLIC_KEY_BYTE_LENGTH = 32;
ed25519.constants.PRIVATE_KEY_BYTE_LENGTH = 64;
ed25519.constants.SEED_BYTE_LENGTH = 32;
ed25519.constants.SIGN_BYTE_LENGTH = 64;
ed25519.constants.HASH_BYTE_LENGTH = 64;
ed25519.generateKeyPair = function(options) {
    options = options || {
    };
    var seed = options.seed;
    if (seed === undefined) // generate seed
    seed = forge.random.getBytesSync(ed25519.constants.SEED_BYTE_LENGTH);
    else if (typeof seed === 'string') {
        if (seed.length !== ed25519.constants.SEED_BYTE_LENGTH) throw new TypeError('"seed" must be ' + ed25519.constants.SEED_BYTE_LENGTH + ' bytes in length.');
    } else if (!(seed instanceof Uint8Array)) throw new TypeError('"seed" must be a node.js Buffer, Uint8Array, or a binary string.');
    seed = messageToNativeBuffer({
        message: seed,
        encoding: 'binary'
    });
    var pk = new NativeBuffer(ed25519.constants.PUBLIC_KEY_BYTE_LENGTH);
    var sk = new NativeBuffer(ed25519.constants.PRIVATE_KEY_BYTE_LENGTH);
    for(var i = 0; i < 32; ++i)sk[i] = seed[i];
    crypto_sign_keypair(pk, sk);
    return {
        publicKey: pk,
        privateKey: sk
    };
};
/**
 * Converts a private key from a RFC8410 ASN.1 encoding.
 *
 * @param obj - The asn1 representation of a private key.
 *
 * @returns {Object} keyInfo - The key information.
 * @returns {Buffer|Uint8Array} keyInfo.privateKeyBytes - 32 private key bytes.
 */ ed25519.privateKeyFromAsn1 = function(obj) {
    var capture = {
    };
    var errors = [];
    var valid = forge.asn1.validate(obj, privateKeyValidator, capture, errors);
    if (!valid) {
        var error = new Error('Invalid Key.');
        error.errors = errors;
        throw error;
    }
    var oid = forge.asn1.derToOid(capture.privateKeyOid);
    var ed25519Oid = forge.oids.EdDSA25519;
    if (oid !== ed25519Oid) throw new Error('Invalid OID "' + oid + '"; OID must be "' + ed25519Oid + '".');
    var privateKey = capture.privateKey;
    // manually extract the private key bytes from nested octet string, see FIXME:
    // https://github.com/digitalbazaar/forge/blob/master/lib/asn1.js#L542
    var privateKeyBytes = messageToNativeBuffer({
        message: forge.asn1.fromDer(privateKey).value,
        encoding: 'binary'
    });
    // TODO: RFC8410 specifies a format for encoding the public key bytes along
    // with the private key bytes. `publicKeyBytes` can be returned in the
    // future. https://tools.ietf.org/html/rfc8410#section-10.3
    return {
        privateKeyBytes: privateKeyBytes
    };
};
/**
 * Converts a public key from a RFC8410 ASN.1 encoding.
 *
 * @param obj - The asn1 representation of a public key.
 *
 * @return {Buffer|Uint8Array} - 32 public key bytes.
 */ ed25519.publicKeyFromAsn1 = function(obj) {
    // get SubjectPublicKeyInfo
    var capture = {
    };
    var errors = [];
    var valid = forge.asn1.validate(obj, publicKeyValidator, capture, errors);
    if (!valid) {
        var error = new Error('Invalid Key.');
        error.errors = errors;
        throw error;
    }
    var oid = forge.asn1.derToOid(capture.publicKeyOid);
    var ed25519Oid = forge.oids.EdDSA25519;
    if (oid !== ed25519Oid) throw new Error('Invalid OID "' + oid + '"; OID must be "' + ed25519Oid + '".');
    var publicKeyBytes = capture.ed25519PublicKey;
    if (publicKeyBytes.length !== ed25519.constants.PUBLIC_KEY_BYTE_LENGTH) throw new Error('Key length is invalid.');
    return messageToNativeBuffer({
        message: publicKeyBytes,
        encoding: 'binary'
    });
};
ed25519.publicKeyFromPrivateKey = function(options) {
    options = options || {
    };
    var privateKey = messageToNativeBuffer({
        message: options.privateKey,
        encoding: 'binary'
    });
    if (privateKey.length !== ed25519.constants.PRIVATE_KEY_BYTE_LENGTH) throw new TypeError('"options.privateKey" must have a byte length of ' + ed25519.constants.PRIVATE_KEY_BYTE_LENGTH);
    var pk = new NativeBuffer(ed25519.constants.PUBLIC_KEY_BYTE_LENGTH);
    for(var i = 0; i < pk.length; ++i)pk[i] = privateKey[32 + i];
    return pk;
};
ed25519.sign = function(options) {
    options = options || {
    };
    var msg = messageToNativeBuffer(options);
    var privateKey = messageToNativeBuffer({
        message: options.privateKey,
        encoding: 'binary'
    });
    if (privateKey.length === ed25519.constants.SEED_BYTE_LENGTH) {
        var keyPair = ed25519.generateKeyPair({
            seed: privateKey
        });
        privateKey = keyPair.privateKey;
    } else if (privateKey.length !== ed25519.constants.PRIVATE_KEY_BYTE_LENGTH) throw new TypeError('"options.privateKey" must have a byte length of ' + ed25519.constants.SEED_BYTE_LENGTH + ' or ' + ed25519.constants.PRIVATE_KEY_BYTE_LENGTH);
    var signedMsg = new NativeBuffer(ed25519.constants.SIGN_BYTE_LENGTH + msg.length);
    crypto_sign(signedMsg, msg, msg.length, privateKey);
    var sig = new NativeBuffer(ed25519.constants.SIGN_BYTE_LENGTH);
    for(var i = 0; i < sig.length; ++i)sig[i] = signedMsg[i];
    return sig;
};
ed25519.verify = function(options) {
    options = options || {
    };
    var msg = messageToNativeBuffer(options);
    if (options.signature === undefined) throw new TypeError("\"options.signature\" must be a node.js Buffer, a Uint8Array, a forge ByteBuffer, or a binary string.");
    var sig = messageToNativeBuffer({
        message: options.signature,
        encoding: 'binary'
    });
    if (sig.length !== ed25519.constants.SIGN_BYTE_LENGTH) throw new TypeError('"options.signature" must have a byte length of ' + ed25519.constants.SIGN_BYTE_LENGTH);
    var publicKey = messageToNativeBuffer({
        message: options.publicKey,
        encoding: 'binary'
    });
    if (publicKey.length !== ed25519.constants.PUBLIC_KEY_BYTE_LENGTH) throw new TypeError('"options.publicKey" must have a byte length of ' + ed25519.constants.PUBLIC_KEY_BYTE_LENGTH);
    var sm = new NativeBuffer(ed25519.constants.SIGN_BYTE_LENGTH + msg.length);
    var m = new NativeBuffer(ed25519.constants.SIGN_BYTE_LENGTH + msg.length);
    var i;
    for(i = 0; i < ed25519.constants.SIGN_BYTE_LENGTH; ++i)sm[i] = sig[i];
    for(i = 0; i < msg.length; ++i)sm[i + ed25519.constants.SIGN_BYTE_LENGTH] = msg[i];
    return crypto_sign_open(m, sm, sm.length, publicKey) >= 0;
};
function messageToNativeBuffer(options) {
    var message = options.message;
    if (message instanceof Uint8Array || message instanceof NativeBuffer) return message;
    var encoding = options.encoding;
    if (message === undefined) {
        if (options.md) {
            // TODO: more rigorous validation that `md` is a MessageDigest
            message = options.md.digest().getBytes();
            encoding = 'binary';
        } else throw new TypeError('"options.message" or "options.md" not specified.');
    }
    if (typeof message === 'string' && !encoding) throw new TypeError('"options.encoding" must be "binary" or "utf8".');
    if (typeof message === 'string') {
        if (typeof Buffer !== 'undefined') return Buffer.from(message, encoding);
        message = new ByteBuffer(message, encoding);
    } else if (!(message instanceof ByteBuffer)) throw new TypeError("\"options.message\" must be a node.js Buffer, a Uint8Array, a forge ByteBuffer, or a string with \"options.encoding\" specifying its encoding.");
    // convert to native buffer
    var buffer = new NativeBuffer(message.length());
    for(var i = 0; i < buffer.length; ++i)buffer[i] = message.at(i);
    return buffer;
}
var gf0 = gf();
var gf1 = gf([
    1
]);
var D = gf([
    30883,
    4953,
    19914,
    30187,
    55467,
    16705,
    2637,
    112,
    59544,
    30585,
    16505,
    36039,
    65139,
    11119,
    27886,
    20995
]);
var D2 = gf([
    61785,
    9906,
    39828,
    60374,
    45398,
    33411,
    5274,
    224,
    53552,
    61171,
    33010,
    6542,
    64743,
    22239,
    55772,
    9222
]);
var X = gf([
    54554,
    36645,
    11616,
    51542,
    42930,
    38181,
    51040,
    26924,
    56412,
    64982,
    57905,
    49316,
    21502,
    52590,
    14035,
    8553
]);
var Y = gf([
    26200,
    26214,
    26214,
    26214,
    26214,
    26214,
    26214,
    26214,
    26214,
    26214,
    26214,
    26214,
    26214,
    26214,
    26214,
    26214
]);
var L = new Float64Array([
    237,
    211,
    245,
    92,
    26,
    99,
    18,
    88,
    214,
    156,
    247,
    162,
    222,
    249,
    222,
    20,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    16
]);
var I = gf([
    41136,
    18958,
    6951,
    50414,
    58488,
    44335,
    6150,
    12099,
    55207,
    15867,
    153,
    11085,
    57099,
    20417,
    9344,
    11139
]);
// TODO: update forge buffer implementation to use `Buffer` or `Uint8Array`,
// whichever is available, to improve performance
function sha512(msg, msgLen) {
    // Note: `out` and `msg` are NativeBuffer
    var md = forge.md.sha512.create();
    var buffer = new ByteBuffer(msg);
    md.update(buffer.getBytes(msgLen), 'binary');
    var hash = md.digest().getBytes();
    if (typeof Buffer !== 'undefined') return Buffer.from(hash, 'binary');
    var out = new NativeBuffer(ed25519.constants.HASH_BYTE_LENGTH);
    for(var i = 0; i < 64; ++i)out[i] = hash.charCodeAt(i);
    return out;
}
function crypto_sign_keypair(pk, sk) {
    var p = [
        gf(),
        gf(),
        gf(),
        gf()
    ];
    var i;
    var d = sha512(sk, 32);
    d[0] &= 248;
    d[31] &= 127;
    d[31] |= 64;
    scalarbase(p, d);
    pack(pk, p);
    for(i = 0; i < 32; ++i)sk[i + 32] = pk[i];
    return 0;
}
// Note: difference from C - smlen returned, not passed as argument.
function crypto_sign(sm, m, n, sk) {
    var i, j, x = new Float64Array(64);
    var p = [
        gf(),
        gf(),
        gf(),
        gf()
    ];
    var d = sha512(sk, 32);
    d[0] &= 248;
    d[31] &= 127;
    d[31] |= 64;
    var smlen = n + 64;
    for(i = 0; i < n; ++i)sm[64 + i] = m[i];
    for(i = 0; i < 32; ++i)sm[32 + i] = d[32 + i];
    var r = sha512(sm.subarray(32), n + 32);
    reduce(r);
    scalarbase(p, r);
    pack(sm, p);
    for(i = 32; i < 64; ++i)sm[i] = sk[i];
    var h = sha512(sm, n + 64);
    reduce(h);
    for(i = 32; i < 64; ++i)x[i] = 0;
    for(i = 0; i < 32; ++i)x[i] = r[i];
    for(i = 0; i < 32; ++i)for(j = 0; j < 32; j++)x[i + j] += h[i] * d[j];
    modL(sm.subarray(32), x);
    return smlen;
}
function crypto_sign_open(m, sm, n, pk) {
    var i, mlen;
    var t = new NativeBuffer(32);
    var p = [
        gf(),
        gf(),
        gf(),
        gf()
    ], q = [
        gf(),
        gf(),
        gf(),
        gf()
    ];
    mlen = -1;
    if (n < 64) return -1;
    if (unpackneg(q, pk)) return -1;
    for(i = 0; i < n; ++i)m[i] = sm[i];
    for(i = 0; i < 32; ++i)m[i + 32] = pk[i];
    var h = sha512(m, n);
    reduce(h);
    scalarmult(p, q, h);
    scalarbase(q, sm.subarray(32));
    add(p, q);
    pack(t, p);
    n -= 64;
    if (crypto_verify_32(sm, 0, t, 0)) {
        for(i = 0; i < n; ++i)m[i] = 0;
        return -1;
    }
    for(i = 0; i < n; ++i)m[i] = sm[i + 64];
    mlen = n;
    return mlen;
}
function modL(r, x) {
    var carry, i, j, k;
    for(i = 63; i >= 32; --i){
        carry = 0;
        for(j = i - 32, k = i - 12; j < k; ++j){
            x[j] += carry - 16 * x[i] * L[j - (i - 32)];
            carry = x[j] + 128 >> 8;
            x[j] -= carry * 256;
        }
        x[j] += carry;
        x[i] = 0;
    }
    carry = 0;
    for(j = 0; j < 32; ++j){
        x[j] += carry - (x[31] >> 4) * L[j];
        carry = x[j] >> 8;
        x[j] &= 255;
    }
    for(j = 0; j < 32; ++j)x[j] -= carry * L[j];
    for(i = 0; i < 32; ++i){
        x[i + 1] += x[i] >> 8;
        r[i] = x[i] & 255;
    }
}
function reduce(r) {
    var x = new Float64Array(64);
    for(var i = 0; i < 64; ++i){
        x[i] = r[i];
        r[i] = 0;
    }
    modL(r, x);
}
function add(p, q) {
    var a = gf(), b = gf(), c = gf(), d = gf(), e = gf(), f = gf(), g = gf(), h = gf(), t = gf();
    Z(a, p[1], p[0]);
    Z(t, q[1], q[0]);
    M(a, a, t);
    A(b, p[0], p[1]);
    A(t, q[0], q[1]);
    M(b, b, t);
    M(c, p[3], q[3]);
    M(c, c, D2);
    M(d, p[2], q[2]);
    A(d, d, d);
    Z(e, b, a);
    Z(f, d, c);
    A(g, d, c);
    A(h, b, a);
    M(p[0], e, f);
    M(p[1], h, g);
    M(p[2], g, f);
    M(p[3], e, h);
}
function cswap(p, q, b) {
    for(var i = 0; i < 4; ++i)sel25519(p[i], q[i], b);
}
function pack(r, p) {
    var tx = gf(), ty = gf(), zi = gf();
    inv25519(zi, p[2]);
    M(tx, p[0], zi);
    M(ty, p[1], zi);
    pack25519(r, ty);
    r[31] ^= par25519(tx) << 7;
}
function pack25519(o, n) {
    var i, j, b;
    var m = gf(), t = gf();
    for(i = 0; i < 16; ++i)t[i] = n[i];
    car25519(t);
    car25519(t);
    car25519(t);
    for(j = 0; j < 2; ++j){
        m[0] = t[0] - 65517;
        for(i = 1; i < 15; ++i){
            m[i] = t[i] - 65535 - (m[i - 1] >> 16 & 1);
            m[i - 1] &= 65535;
        }
        m[15] = t[15] - 32767 - (m[14] >> 16 & 1);
        b = m[15] >> 16 & 1;
        m[14] &= 65535;
        sel25519(t, m, 1 - b);
    }
    for(i = 0; i < 16; i++){
        o[2 * i] = t[i] & 255;
        o[2 * i + 1] = t[i] >> 8;
    }
}
function unpackneg(r, p) {
    var t = gf(), chk = gf(), num = gf(), den = gf(), den2 = gf(), den4 = gf(), den6 = gf();
    set25519(r[2], gf1);
    unpack25519(r[1], p);
    S(num, r[1]);
    M(den, num, D);
    Z(num, num, r[2]);
    A(den, r[2], den);
    S(den2, den);
    S(den4, den2);
    M(den6, den4, den2);
    M(t, den6, num);
    M(t, t, den);
    pow2523(t, t);
    M(t, t, num);
    M(t, t, den);
    M(t, t, den);
    M(r[0], t, den);
    S(chk, r[0]);
    M(chk, chk, den);
    if (neq25519(chk, num)) M(r[0], r[0], I);
    S(chk, r[0]);
    M(chk, chk, den);
    if (neq25519(chk, num)) return -1;
    if (par25519(r[0]) === p[31] >> 7) Z(r[0], gf0, r[0]);
    M(r[3], r[0], r[1]);
    return 0;
}
function unpack25519(o, n) {
    var i;
    for(i = 0; i < 16; ++i)o[i] = n[2 * i] + (n[2 * i + 1] << 8);
    o[15] &= 32767;
}
function pow2523(o, i) {
    var c = gf();
    var a;
    for(a = 0; a < 16; ++a)c[a] = i[a];
    for(a = 250; a >= 0; --a){
        S(c, c);
        if (a !== 1) M(c, c, i);
    }
    for(a = 0; a < 16; ++a)o[a] = c[a];
}
function neq25519(a, b) {
    var c = new NativeBuffer(32);
    var d = new NativeBuffer(32);
    pack25519(c, a);
    pack25519(d, b);
    return crypto_verify_32(c, 0, d, 0);
}
function crypto_verify_32(x, xi, y, yi) {
    return vn(x, xi, y, yi, 32);
}
function vn(x, xi, y, yi, n) {
    var i, d = 0;
    for(i = 0; i < n; ++i)d |= x[xi + i] ^ y[yi + i];
    return (1 & d - 1 >>> 8) - 1;
}
function par25519(a) {
    var d = new NativeBuffer(32);
    pack25519(d, a);
    return d[0] & 1;
}
function scalarmult(p, q, s) {
    var b, i;
    set25519(p[0], gf0);
    set25519(p[1], gf1);
    set25519(p[2], gf1);
    set25519(p[3], gf0);
    for(i = 255; i >= 0; --i){
        b = s[i / 8 | 0] >> (i & 7) & 1;
        cswap(p, q, b);
        add(q, p);
        add(p, p);
        cswap(p, q, b);
    }
}
function scalarbase(p, s) {
    var q = [
        gf(),
        gf(),
        gf(),
        gf()
    ];
    set25519(q[0], X);
    set25519(q[1], Y);
    set25519(q[2], gf1);
    M(q[3], X, Y);
    scalarmult(p, q, s);
}
function set25519(r, a) {
    var i;
    for(i = 0; i < 16; i++)r[i] = a[i] | 0;
}
function inv25519(o, i) {
    var c = gf();
    var a;
    for(a = 0; a < 16; ++a)c[a] = i[a];
    for(a = 253; a >= 0; --a){
        S(c, c);
        if (a !== 2 && a !== 4) M(c, c, i);
    }
    for(a = 0; a < 16; ++a)o[a] = c[a];
}
function car25519(o) {
    var i, v, c = 1;
    for(i = 0; i < 16; ++i){
        v = o[i] + c + 65535;
        c = Math.floor(v / 65536);
        o[i] = v - c * 65536;
    }
    o[0] += c - 1 + 37 * (c - 1);
}
function sel25519(p, q, b) {
    var t, c = ~(b - 1);
    for(var i = 0; i < 16; ++i){
        t = c & (p[i] ^ q[i]);
        p[i] ^= t;
        q[i] ^= t;
    }
}
function gf(init) {
    var i, r = new Float64Array(16);
    if (init) for(i = 0; i < init.length; ++i)r[i] = init[i];
    return r;
}
function A(o, a, b) {
    for(var i = 0; i < 16; ++i)o[i] = a[i] + b[i];
}
function Z(o, a, b) {
    for(var i = 0; i < 16; ++i)o[i] = a[i] - b[i];
}
function S(o, a) {
    M(o, a, a);
}
function M(o, a, b) {
    var v, c, t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0, t8 = 0, t9 = 0, t10 = 0, t11 = 0, t12 = 0, t13 = 0, t14 = 0, t15 = 0, t16 = 0, t17 = 0, t18 = 0, t19 = 0, t20 = 0, t21 = 0, t22 = 0, t23 = 0, t24 = 0, t25 = 0, t26 = 0, t27 = 0, t28 = 0, t29 = 0, t30 = 0, b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3], b4 = b[4], b5 = b[5], b6 = b[6], b7 = b[7], b8 = b[8], b9 = b[9], b10 = b[10], b11 = b[11], b12 = b[12], b13 = b[13], b14 = b[14], b15 = b[15];
    v = a[0];
    t0 += v * b0;
    t1 += v * b1;
    t2 += v * b2;
    t3 += v * b3;
    t4 += v * b4;
    t5 += v * b5;
    t6 += v * b6;
    t7 += v * b7;
    t8 += v * b8;
    t9 += v * b9;
    t10 += v * b10;
    t11 += v * b11;
    t12 += v * b12;
    t13 += v * b13;
    t14 += v * b14;
    t15 += v * b15;
    v = a[1];
    t1 += v * b0;
    t2 += v * b1;
    t3 += v * b2;
    t4 += v * b3;
    t5 += v * b4;
    t6 += v * b5;
    t7 += v * b6;
    t8 += v * b7;
    t9 += v * b8;
    t10 += v * b9;
    t11 += v * b10;
    t12 += v * b11;
    t13 += v * b12;
    t14 += v * b13;
    t15 += v * b14;
    t16 += v * b15;
    v = a[2];
    t2 += v * b0;
    t3 += v * b1;
    t4 += v * b2;
    t5 += v * b3;
    t6 += v * b4;
    t7 += v * b5;
    t8 += v * b6;
    t9 += v * b7;
    t10 += v * b8;
    t11 += v * b9;
    t12 += v * b10;
    t13 += v * b11;
    t14 += v * b12;
    t15 += v * b13;
    t16 += v * b14;
    t17 += v * b15;
    v = a[3];
    t3 += v * b0;
    t4 += v * b1;
    t5 += v * b2;
    t6 += v * b3;
    t7 += v * b4;
    t8 += v * b5;
    t9 += v * b6;
    t10 += v * b7;
    t11 += v * b8;
    t12 += v * b9;
    t13 += v * b10;
    t14 += v * b11;
    t15 += v * b12;
    t16 += v * b13;
    t17 += v * b14;
    t18 += v * b15;
    v = a[4];
    t4 += v * b0;
    t5 += v * b1;
    t6 += v * b2;
    t7 += v * b3;
    t8 += v * b4;
    t9 += v * b5;
    t10 += v * b6;
    t11 += v * b7;
    t12 += v * b8;
    t13 += v * b9;
    t14 += v * b10;
    t15 += v * b11;
    t16 += v * b12;
    t17 += v * b13;
    t18 += v * b14;
    t19 += v * b15;
    v = a[5];
    t5 += v * b0;
    t6 += v * b1;
    t7 += v * b2;
    t8 += v * b3;
    t9 += v * b4;
    t10 += v * b5;
    t11 += v * b6;
    t12 += v * b7;
    t13 += v * b8;
    t14 += v * b9;
    t15 += v * b10;
    t16 += v * b11;
    t17 += v * b12;
    t18 += v * b13;
    t19 += v * b14;
    t20 += v * b15;
    v = a[6];
    t6 += v * b0;
    t7 += v * b1;
    t8 += v * b2;
    t9 += v * b3;
    t10 += v * b4;
    t11 += v * b5;
    t12 += v * b6;
    t13 += v * b7;
    t14 += v * b8;
    t15 += v * b9;
    t16 += v * b10;
    t17 += v * b11;
    t18 += v * b12;
    t19 += v * b13;
    t20 += v * b14;
    t21 += v * b15;
    v = a[7];
    t7 += v * b0;
    t8 += v * b1;
    t9 += v * b2;
    t10 += v * b3;
    t11 += v * b4;
    t12 += v * b5;
    t13 += v * b6;
    t14 += v * b7;
    t15 += v * b8;
    t16 += v * b9;
    t17 += v * b10;
    t18 += v * b11;
    t19 += v * b12;
    t20 += v * b13;
    t21 += v * b14;
    t22 += v * b15;
    v = a[8];
    t8 += v * b0;
    t9 += v * b1;
    t10 += v * b2;
    t11 += v * b3;
    t12 += v * b4;
    t13 += v * b5;
    t14 += v * b6;
    t15 += v * b7;
    t16 += v * b8;
    t17 += v * b9;
    t18 += v * b10;
    t19 += v * b11;
    t20 += v * b12;
    t21 += v * b13;
    t22 += v * b14;
    t23 += v * b15;
    v = a[9];
    t9 += v * b0;
    t10 += v * b1;
    t11 += v * b2;
    t12 += v * b3;
    t13 += v * b4;
    t14 += v * b5;
    t15 += v * b6;
    t16 += v * b7;
    t17 += v * b8;
    t18 += v * b9;
    t19 += v * b10;
    t20 += v * b11;
    t21 += v * b12;
    t22 += v * b13;
    t23 += v * b14;
    t24 += v * b15;
    v = a[10];
    t10 += v * b0;
    t11 += v * b1;
    t12 += v * b2;
    t13 += v * b3;
    t14 += v * b4;
    t15 += v * b5;
    t16 += v * b6;
    t17 += v * b7;
    t18 += v * b8;
    t19 += v * b9;
    t20 += v * b10;
    t21 += v * b11;
    t22 += v * b12;
    t23 += v * b13;
    t24 += v * b14;
    t25 += v * b15;
    v = a[11];
    t11 += v * b0;
    t12 += v * b1;
    t13 += v * b2;
    t14 += v * b3;
    t15 += v * b4;
    t16 += v * b5;
    t17 += v * b6;
    t18 += v * b7;
    t19 += v * b8;
    t20 += v * b9;
    t21 += v * b10;
    t22 += v * b11;
    t23 += v * b12;
    t24 += v * b13;
    t25 += v * b14;
    t26 += v * b15;
    v = a[12];
    t12 += v * b0;
    t13 += v * b1;
    t14 += v * b2;
    t15 += v * b3;
    t16 += v * b4;
    t17 += v * b5;
    t18 += v * b6;
    t19 += v * b7;
    t20 += v * b8;
    t21 += v * b9;
    t22 += v * b10;
    t23 += v * b11;
    t24 += v * b12;
    t25 += v * b13;
    t26 += v * b14;
    t27 += v * b15;
    v = a[13];
    t13 += v * b0;
    t14 += v * b1;
    t15 += v * b2;
    t16 += v * b3;
    t17 += v * b4;
    t18 += v * b5;
    t19 += v * b6;
    t20 += v * b7;
    t21 += v * b8;
    t22 += v * b9;
    t23 += v * b10;
    t24 += v * b11;
    t25 += v * b12;
    t26 += v * b13;
    t27 += v * b14;
    t28 += v * b15;
    v = a[14];
    t14 += v * b0;
    t15 += v * b1;
    t16 += v * b2;
    t17 += v * b3;
    t18 += v * b4;
    t19 += v * b5;
    t20 += v * b6;
    t21 += v * b7;
    t22 += v * b8;
    t23 += v * b9;
    t24 += v * b10;
    t25 += v * b11;
    t26 += v * b12;
    t27 += v * b13;
    t28 += v * b14;
    t29 += v * b15;
    v = a[15];
    t15 += v * b0;
    t16 += v * b1;
    t17 += v * b2;
    t18 += v * b3;
    t19 += v * b4;
    t20 += v * b5;
    t21 += v * b6;
    t22 += v * b7;
    t23 += v * b8;
    t24 += v * b9;
    t25 += v * b10;
    t26 += v * b11;
    t27 += v * b12;
    t28 += v * b13;
    t29 += v * b14;
    t30 += v * b15;
    t0 += 38 * t16;
    t1 += 38 * t17;
    t2 += 38 * t18;
    t3 += 38 * t19;
    t4 += 38 * t20;
    t5 += 38 * t21;
    t6 += 38 * t22;
    t7 += 38 * t23;
    t8 += 38 * t24;
    t9 += 38 * t25;
    t10 += 38 * t26;
    t11 += 38 * t27;
    t12 += 38 * t28;
    t13 += 38 * t29;
    t14 += 38 * t30;
    // t15 left as is
    // first car
    c = 1;
    v = t0 + c + 65535;
    c = Math.floor(v / 65536);
    t0 = v - c * 65536;
    v = t1 + c + 65535;
    c = Math.floor(v / 65536);
    t1 = v - c * 65536;
    v = t2 + c + 65535;
    c = Math.floor(v / 65536);
    t2 = v - c * 65536;
    v = t3 + c + 65535;
    c = Math.floor(v / 65536);
    t3 = v - c * 65536;
    v = t4 + c + 65535;
    c = Math.floor(v / 65536);
    t4 = v - c * 65536;
    v = t5 + c + 65535;
    c = Math.floor(v / 65536);
    t5 = v - c * 65536;
    v = t6 + c + 65535;
    c = Math.floor(v / 65536);
    t6 = v - c * 65536;
    v = t7 + c + 65535;
    c = Math.floor(v / 65536);
    t7 = v - c * 65536;
    v = t8 + c + 65535;
    c = Math.floor(v / 65536);
    t8 = v - c * 65536;
    v = t9 + c + 65535;
    c = Math.floor(v / 65536);
    t9 = v - c * 65536;
    v = t10 + c + 65535;
    c = Math.floor(v / 65536);
    t10 = v - c * 65536;
    v = t11 + c + 65535;
    c = Math.floor(v / 65536);
    t11 = v - c * 65536;
    v = t12 + c + 65535;
    c = Math.floor(v / 65536);
    t12 = v - c * 65536;
    v = t13 + c + 65535;
    c = Math.floor(v / 65536);
    t13 = v - c * 65536;
    v = t14 + c + 65535;
    c = Math.floor(v / 65536);
    t14 = v - c * 65536;
    v = t15 + c + 65535;
    c = Math.floor(v / 65536);
    t15 = v - c * 65536;
    t0 += c - 1 + 37 * (c - 1);
    // second car
    c = 1;
    v = t0 + c + 65535;
    c = Math.floor(v / 65536);
    t0 = v - c * 65536;
    v = t1 + c + 65535;
    c = Math.floor(v / 65536);
    t1 = v - c * 65536;
    v = t2 + c + 65535;
    c = Math.floor(v / 65536);
    t2 = v - c * 65536;
    v = t3 + c + 65535;
    c = Math.floor(v / 65536);
    t3 = v - c * 65536;
    v = t4 + c + 65535;
    c = Math.floor(v / 65536);
    t4 = v - c * 65536;
    v = t5 + c + 65535;
    c = Math.floor(v / 65536);
    t5 = v - c * 65536;
    v = t6 + c + 65535;
    c = Math.floor(v / 65536);
    t6 = v - c * 65536;
    v = t7 + c + 65535;
    c = Math.floor(v / 65536);
    t7 = v - c * 65536;
    v = t8 + c + 65535;
    c = Math.floor(v / 65536);
    t8 = v - c * 65536;
    v = t9 + c + 65535;
    c = Math.floor(v / 65536);
    t9 = v - c * 65536;
    v = t10 + c + 65535;
    c = Math.floor(v / 65536);
    t10 = v - c * 65536;
    v = t11 + c + 65535;
    c = Math.floor(v / 65536);
    t11 = v - c * 65536;
    v = t12 + c + 65535;
    c = Math.floor(v / 65536);
    t12 = v - c * 65536;
    v = t13 + c + 65535;
    c = Math.floor(v / 65536);
    t13 = v - c * 65536;
    v = t14 + c + 65535;
    c = Math.floor(v / 65536);
    t14 = v - c * 65536;
    v = t15 + c + 65535;
    c = Math.floor(v / 65536);
    t15 = v - c * 65536;
    t0 += c - 1 + 37 * (c - 1);
    o[0] = t0;
    o[1] = t1;
    o[2] = t2;
    o[3] = t3;
    o[4] = t4;
    o[5] = t5;
    o[6] = t6;
    o[7] = t7;
    o[8] = t8;
    o[9] = t9;
    o[10] = t10;
    o[11] = t11;
    o[12] = t12;
    o[13] = t13;
    o[14] = t14;
    o[15] = t15;
}

},{"buffer":"joWnX","./forge":"7AnVp","./jsbn":"6OVnc","./random":"7GrCn","./sha512":"kidGB","./util":"cHj6b","./asn1-validator":"7jIzK"}],"7jIzK":[function(require,module,exports) {
/**
 * Copyright (c) 2019 Digital Bazaar, Inc.
 */ var forge = require('./forge');
require('./asn1');
var asn1 = forge.asn1;
exports.privateKeyValidator = {
    // PrivateKeyInfo
    name: 'PrivateKeyInfo',
    tagClass: asn1.Class.UNIVERSAL,
    type: asn1.Type.SEQUENCE,
    constructed: true,
    value: [
        {
            // Version (INTEGER)
            name: 'PrivateKeyInfo.version',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.INTEGER,
            constructed: false,
            capture: 'privateKeyVersion'
        },
        {
            // privateKeyAlgorithm
            name: 'PrivateKeyInfo.privateKeyAlgorithm',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.SEQUENCE,
            constructed: true,
            value: [
                {
                    name: 'AlgorithmIdentifier.algorithm',
                    tagClass: asn1.Class.UNIVERSAL,
                    type: asn1.Type.OID,
                    constructed: false,
                    capture: 'privateKeyOid'
                }
            ]
        },
        {
            // PrivateKey
            name: 'PrivateKeyInfo',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.OCTETSTRING,
            constructed: false,
            capture: 'privateKey'
        }
    ]
};
exports.publicKeyValidator = {
    name: 'SubjectPublicKeyInfo',
    tagClass: asn1.Class.UNIVERSAL,
    type: asn1.Type.SEQUENCE,
    constructed: true,
    captureAsn1: 'subjectPublicKeyInfo',
    value: [
        {
            name: 'SubjectPublicKeyInfo.AlgorithmIdentifier',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.SEQUENCE,
            constructed: true,
            value: [
                {
                    name: 'AlgorithmIdentifier.algorithm',
                    tagClass: asn1.Class.UNIVERSAL,
                    type: asn1.Type.OID,
                    constructed: false,
                    capture: 'publicKeyOid'
                }
            ]
        },
        // capture group for ed25519PublicKey
        {
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.BITSTRING,
            constructed: false,
            composed: true,
            captureBitStringValue: 'ed25519PublicKey'
        }
    ]
};

},{"./forge":"7AnVp","./asn1":"fLyrX"}],"gtCsO":[function(require,module,exports) {
'use strict';
const webcrypto = require('../webcrypto');
const randomBytes = require('../random-bytes');
const { toString: uint8ArrayToString  } = require('uint8arrays/to-string');
const { fromString: uint8ArrayFromString  } = require('uint8arrays/from-string');
exports.utils = require('./rsa-utils');
exports.generateKey = async function(bits) {
    const pair = await webcrypto.get().subtle.generateKey({
        name: 'RSASSA-PKCS1-v1_5',
        modulusLength: bits,
        publicExponent: new Uint8Array([
            1,
            0,
            1
        ]),
        hash: {
            name: 'SHA-256'
        }
    }, true, [
        'sign',
        'verify'
    ]);
    const keys = await exportKey(pair);
    return {
        privateKey: keys[0],
        publicKey: keys[1]
    };
};
// Takes a jwk key
exports.unmarshalPrivateKey = async function(key) {
    const privateKey = await webcrypto.get().subtle.importKey('jwk', key, {
        name: 'RSASSA-PKCS1-v1_5',
        hash: {
            name: 'SHA-256'
        }
    }, true, [
        'sign'
    ]);
    const pair = [
        privateKey,
        await derivePublicFromPrivate(key)
    ];
    const keys = await exportKey({
        privateKey: pair[0],
        publicKey: pair[1]
    });
    return {
        privateKey: keys[0],
        publicKey: keys[1]
    };
};
exports.getRandomValues = randomBytes;
exports.hashAndSign = async function(key, msg) {
    const privateKey = await webcrypto.get().subtle.importKey('jwk', key, {
        name: 'RSASSA-PKCS1-v1_5',
        hash: {
            name: 'SHA-256'
        }
    }, false, [
        'sign'
    ]);
    const sig = await webcrypto.get().subtle.sign({
        name: 'RSASSA-PKCS1-v1_5'
    }, privateKey, Uint8Array.from(msg));
    return new Uint8Array(sig, sig.byteOffset, sig.byteLength);
};
exports.hashAndVerify = async function(key, sig, msg) {
    const publicKey = await webcrypto.get().subtle.importKey('jwk', key, {
        name: 'RSASSA-PKCS1-v1_5',
        hash: {
            name: 'SHA-256'
        }
    }, false, [
        'verify'
    ]);
    return webcrypto.get().subtle.verify({
        name: 'RSASSA-PKCS1-v1_5'
    }, publicKey, sig, msg);
};
function exportKey(pair) {
    return Promise.all([
        webcrypto.get().subtle.exportKey('jwk', pair.privateKey),
        webcrypto.get().subtle.exportKey('jwk', pair.publicKey)
    ]);
}
function derivePublicFromPrivate(jwKey) {
    return webcrypto.get().subtle.importKey('jwk', {
        kty: jwKey.kty,
        n: jwKey.n,
        e: jwKey.e
    }, {
        name: 'RSASSA-PKCS1-v1_5',
        hash: {
            name: 'SHA-256'
        }
    }, true, [
        'verify'
    ]);
}
/*

RSA encryption/decryption for the browser with webcrypto workarround
"bloody dark magic. webcrypto's why."

Explanation:
  - Convert JWK to nodeForge
  - Convert msg Uint8Array to nodeForge buffer: ByteBuffer is a "binary-string backed buffer", so let's make our Uint8Array a binary string
  - Convert resulting nodeForge buffer to Uint8Array: it returns a binary string, turn that into a Uint8Array

*/ const { jwk2pub , jwk2priv  } = require('./jwk2pem');
function convertKey(key, pub, msg, handle) {
    const fkey = pub ? jwk2pub(key) : jwk2priv(key);
    const fmsg = uint8ArrayToString(Uint8Array.from(msg), 'ascii');
    const fomsg = handle(fmsg, fkey);
    return uint8ArrayFromString(fomsg, 'ascii');
}
exports.encrypt = function(key1, msg1) {
    return convertKey(key1, true, msg1, (msg, key)=>key.encrypt(msg)
    );
};
exports.decrypt = function(key2, msg2) {
    return convertKey(key2, false, msg2, (msg, key)=>key.decrypt(msg)
    );
};

},{"../webcrypto":"hKlQS","../random-bytes":"1G1Dz","uint8arrays/to-string":"g3mCQ","uint8arrays/from-string":"lo45E","./rsa-utils":"fu7Fc","./jwk2pem":"7s9Y1"}],"1G1Dz":[function(require,module,exports) {
'use strict';
const randomBytes = require('iso-random-stream/src/random');
const errcode = require('err-code');
module.exports = function(length) {
    if (isNaN(length) || length <= 0) throw errcode(new Error('random bytes length must be a Number bigger than 0'), 'ERR_INVALID_LENGTH');
    return randomBytes(length);
};

},{"iso-random-stream/src/random":"4APIs","err-code":"eQvyh"}],"4APIs":[function(require,module,exports) {
'use strict';
// limit of Crypto.getRandomValues()
// https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues
const MAX_BYTES = 65536;
/**
 * @param {number} size
 */ function randomBytes(size) {
    const bytes = new Uint8Array(size);
    let generated = 0;
    if (size > 0) {
        // getRandomValues fails on IE if size == 0
        if (size > MAX_BYTES) {
            while(generated < size)if (generated + MAX_BYTES > size) {
                crypto.getRandomValues(bytes.subarray(generated, generated + (size - generated)));
                generated += size - generated;
            } else {
                crypto.getRandomValues(bytes.subarray(generated, generated + MAX_BYTES));
                generated += MAX_BYTES;
            }
        } else crypto.getRandomValues(bytes);
    }
    return bytes;
}
module.exports = randomBytes;

},{}],"fu7Fc":[function(require,module,exports) {
'use strict';
require('node-forge/lib/asn1');
require('node-forge/lib/rsa');
const forge = require('node-forge/lib/forge');
const { bigIntegerToUintBase64url , base64urlToBigInteger  } = require('./../util');
const { fromString: uint8ArrayFromString  } = require('uint8arrays/from-string');
const { toString: uint8ArrayToString  } = require('uint8arrays/to-string');
// Convert a PKCS#1 in ASN1 DER format to a JWK key
exports.pkcs1ToJwk = function(bytes) {
    const asn1 = forge.asn1.fromDer(uint8ArrayToString(bytes, 'ascii'));
    const privateKey = forge.pki.privateKeyFromAsn1(asn1);
    // https://tools.ietf.org/html/rfc7518#section-6.3.1
    return {
        kty: 'RSA',
        n: bigIntegerToUintBase64url(privateKey.n),
        e: bigIntegerToUintBase64url(privateKey.e),
        d: bigIntegerToUintBase64url(privateKey.d),
        p: bigIntegerToUintBase64url(privateKey.p),
        q: bigIntegerToUintBase64url(privateKey.q),
        dp: bigIntegerToUintBase64url(privateKey.dP),
        dq: bigIntegerToUintBase64url(privateKey.dQ),
        qi: bigIntegerToUintBase64url(privateKey.qInv),
        alg: 'RS256',
        kid: '2011-04-29'
    };
};
// Convert a JWK key into PKCS#1 in ASN1 DER format
exports.jwkToPkcs1 = function(jwk) {
    const asn1 = forge.pki.privateKeyToAsn1({
        n: base64urlToBigInteger(jwk.n),
        e: base64urlToBigInteger(jwk.e),
        d: base64urlToBigInteger(jwk.d),
        p: base64urlToBigInteger(jwk.p),
        q: base64urlToBigInteger(jwk.q),
        dP: base64urlToBigInteger(jwk.dp),
        dQ: base64urlToBigInteger(jwk.dq),
        qInv: base64urlToBigInteger(jwk.qi)
    });
    return uint8ArrayFromString(forge.asn1.toDer(asn1).getBytes(), 'ascii');
};
// Convert a PKCIX in ASN1 DER format to a JWK key
exports.pkixToJwk = function(bytes) {
    const asn1 = forge.asn1.fromDer(uint8ArrayToString(bytes, 'ascii'));
    const publicKey = forge.pki.publicKeyFromAsn1(asn1);
    return {
        kty: 'RSA',
        n: bigIntegerToUintBase64url(publicKey.n),
        e: bigIntegerToUintBase64url(publicKey.e),
        alg: 'RS256',
        kid: '2011-04-29'
    };
};
// Convert a JWK key to PKCIX in ASN1 DER format
exports.jwkToPkix = function(jwk) {
    const asn1 = forge.pki.publicKeyToAsn1({
        n: base64urlToBigInteger(jwk.n),
        e: base64urlToBigInteger(jwk.e)
    });
    return uint8ArrayFromString(forge.asn1.toDer(asn1).getBytes(), 'ascii');
};

},{"node-forge/lib/asn1":"fLyrX","node-forge/lib/rsa":"2GXRz","node-forge/lib/forge":"7AnVp","./../util":"GsPr7","uint8arrays/from-string":"lo45E","uint8arrays/to-string":"g3mCQ"}],"GsPr7":[function(require,module,exports) {
'use strict';
require('node-forge/lib/util');
require('node-forge/lib/jsbn');
const forge = require('node-forge/lib/forge');
const { fromString: uint8ArrayFromString  } = require('uint8arrays/from-string');
const { toString: uint8ArrayToString  } = require('uint8arrays/to-string');
const { concat: uint8ArrayConcat  } = require('uint8arrays/concat');
exports.bigIntegerToUintBase64url = (num, len)=>{
    // Call `.abs()` to convert to unsigned
    let buf = Uint8Array.from(num.abs().toByteArray()) // toByteArray converts to big endian
    ;
    // toByteArray() gives us back a signed array, which will include a leading 0
    // byte if the most significant bit of the number is 1:
    // https://docs.microsoft.com/en-us/windows/win32/seccertenroll/about-integer
    // Our number will always be positive so we should remove the leading padding.
    buf = buf[0] === 0 ? buf.slice(1) : buf;
    if (len != null) {
        if (buf.length > len) throw new Error('byte array longer than desired length');
        buf = uint8ArrayConcat([
            new Uint8Array(len - buf.length),
            buf
        ]);
    }
    return uint8ArrayToString(buf, 'base64url');
};
// Convert a base64url encoded string to a BigInteger
exports.base64urlToBigInteger = (str)=>{
    const buf = exports.base64urlToBuffer(str);
    return new forge.jsbn.BigInteger(uint8ArrayToString(buf, 'base16'), 16);
};
exports.base64urlToBuffer = (str, len)=>{
    let buf = uint8ArrayFromString(str, 'base64urlpad');
    if (len != null) {
        if (buf.length > len) throw new Error('byte array longer than desired length');
        buf = uint8ArrayConcat([
            new Uint8Array(len - buf.length),
            buf
        ]);
    }
    return buf;
};

},{"node-forge/lib/util":"cHj6b","node-forge/lib/jsbn":"6OVnc","node-forge/lib/forge":"7AnVp","uint8arrays/from-string":"lo45E","uint8arrays/to-string":"g3mCQ","uint8arrays/concat":"fLIrL"}],"7s9Y1":[function(require,module,exports) {
'use strict';
require('node-forge/lib/rsa');
const forge = require('node-forge/lib/forge');
const { base64urlToBigInteger  } = require('../util');
function convert(key, types) {
    return types.map((t)=>base64urlToBigInteger(key[t])
    );
}
function jwk2priv(key) {
    return forge.pki.setRsaPrivateKey(...convert(key, [
        'n',
        'e',
        'd',
        'p',
        'q',
        'dp',
        'dq',
        'qi'
    ]));
}
function jwk2pub(key) {
    return forge.pki.setRsaPublicKey(...convert(key, [
        'n',
        'e'
    ]));
}
module.exports = {
    jwk2pub,
    jwk2priv
};

},{"node-forge/lib/rsa":"2GXRz","node-forge/lib/forge":"7AnVp","../util":"GsPr7"}],"3mrEx":[function(require,module,exports) {
'use strict';
const { base64  } = require('multiformats/bases/base64');
const ciphers = require('../ciphers/aes-gcm');
module.exports = {
    /**
   * Exports the given PrivateKey as a base64 encoded string.
   * The PrivateKey is encrypted via a password derived PBKDF2 key
   * leveraging the aes-gcm cipher algorithm.
   *
   * @param {Uint8Array} privateKey - The PrivateKey protobuf
   * @param {string} password
   * @returns {Promise<string>} A base64 encoded string
   */ export: async function(privateKey, password) {
        const cipher = ciphers.create();
        const encryptedKey = await cipher.encrypt(privateKey, password);
        return base64.encode(encryptedKey);
    }
};

},{"multiformats/bases/base64":"7Lo1j","../ciphers/aes-gcm":"cNDE6"}],"Gg3Pl":[function(require,module,exports) {
'use strict';
const errcode = require('err-code');
const { equals: uint8ArrayEquals  } = require('uint8arrays/equals');
const { sha256  } = require('multiformats/hashes/sha2');
const { base58btc  } = require('multiformats/bases/base58');
const { identity  } = require('multiformats/hashes/identity');
const crypto = require('./ed25519');
const pbm = require('./keys');
const exporter = require('./exporter');
class Ed25519PublicKey {
    constructor(key4){
        this._key = ensureKey(key4, crypto.publicKeyLength);
    }
    async verify(data, sig) {
        return crypto.hashAndVerify(this._key, sig, data);
    }
    marshal() {
        return this._key;
    }
    get bytes() {
        return pbm.PublicKey.encode({
            Type: pbm.KeyType.Ed25519,
            Data: this.marshal()
        }).finish();
    }
    equals(key1) {
        return uint8ArrayEquals(this.bytes, key1.bytes);
    }
    async hash() {
        const { bytes  } = await sha256.digest(this.bytes);
        return bytes;
    }
}
class Ed25519PrivateKey {
    // key       - 64 byte Uint8Array containing private key
    // publicKey - 32 byte Uint8Array containing public key
    constructor(key2, publicKey1){
        this._key = ensureKey(key2, crypto.privateKeyLength);
        this._publicKey = ensureKey(publicKey1, crypto.publicKeyLength);
    }
    async sign(message) {
        return crypto.hashAndSign(this._key, message);
    }
    get public() {
        return new Ed25519PublicKey(this._publicKey);
    }
    marshal() {
        return this._key;
    }
    get bytes() {
        return pbm.PrivateKey.encode({
            Type: pbm.KeyType.Ed25519,
            Data: this.marshal()
        }).finish();
    }
    equals(key3) {
        return uint8ArrayEquals(this.bytes, key3.bytes);
    }
    async hash() {
        const { bytes  } = await sha256.digest(this.bytes);
        return bytes;
    }
    /**
   * Gets the ID of the key.
   *
   * The key id is the base58 encoding of the identity multihash containing its public key.
   * The public key is a protobuf encoding containing a type and the DER encoding
   * of the PKCS SubjectPublicKeyInfo.
   *
   * @returns {Promise<string>}
   */ async id() {
        const encoding = await identity.digest(this.public.bytes);
        return base58btc.encode(encoding.bytes).substring(1);
    }
    /**
   * Exports the key into a password protected `format`
   *
   * @param {string} password - The password to encrypt the key
   * @param {string} [format=libp2p-key] - The format in which to export as
   * @returns {Promise<Uint8Array>} The encrypted private key
   */ async export(password, format = 'libp2p-key') {
        if (format === 'libp2p-key') return exporter.export(this.bytes, password);
        else throw errcode(new Error(`export format '${format}' is not supported`), 'ERR_INVALID_EXPORT_FORMAT');
    }
}
function unmarshalEd25519PrivateKey(bytes) {
    // Try the old, redundant public key version
    if (bytes.length > crypto.privateKeyLength) {
        bytes = ensureKey(bytes, crypto.privateKeyLength + crypto.publicKeyLength);
        const privateKeyBytes = bytes.slice(0, crypto.privateKeyLength);
        const publicKeyBytes = bytes.slice(crypto.privateKeyLength, bytes.length);
        return new Ed25519PrivateKey(privateKeyBytes, publicKeyBytes);
    }
    bytes = ensureKey(bytes, crypto.privateKeyLength);
    const privateKeyBytes = bytes.slice(0, crypto.privateKeyLength);
    const publicKeyBytes = bytes.slice(crypto.publicKeyLength);
    return new Ed25519PrivateKey(privateKeyBytes, publicKeyBytes);
}
function unmarshalEd25519PublicKey(bytes) {
    bytes = ensureKey(bytes, crypto.publicKeyLength);
    return new Ed25519PublicKey(bytes);
}
async function generateKeyPair() {
    const { privateKey , publicKey  } = await crypto.generateKey();
    return new Ed25519PrivateKey(privateKey, publicKey);
}
async function generateKeyPairFromSeed(seed) {
    const { privateKey , publicKey  } = await crypto.generateKeyFromSeed(seed);
    return new Ed25519PrivateKey(privateKey, publicKey);
}
function ensureKey(key, length) {
    key = Uint8Array.from(key || []);
    if (key.length !== length) throw errcode(new Error(`Key must be a Uint8Array of length ${length}, got ${key.length}`), 'ERR_INVALID_KEY_TYPE');
    return key;
}
module.exports = {
    Ed25519PublicKey,
    Ed25519PrivateKey,
    unmarshalEd25519PrivateKey,
    unmarshalEd25519PublicKey,
    generateKeyPair,
    generateKeyPairFromSeed
};

},{"err-code":"eQvyh","uint8arrays/equals":"fjLeN","multiformats/hashes/sha2":"i8JnP","multiformats/bases/base58":"6Rnqi","multiformats/hashes/identity":"7Cndu","./ed25519":"OXz8r","./keys":"jQuh5","./exporter":"3mrEx"}],"OXz8r":[function(require,module,exports) {
'use strict';
require('node-forge/lib/ed25519');
const forge = require('node-forge/lib/forge');
exports.publicKeyLength = forge.pki.ed25519.constants.PUBLIC_KEY_BYTE_LENGTH;
exports.privateKeyLength = forge.pki.ed25519.constants.PRIVATE_KEY_BYTE_LENGTH;
exports.generateKey = async function() {
    return forge.pki.ed25519.generateKeyPair();
};
// seed should be a 32 byte uint8array
exports.generateKeyFromSeed = async function(seed) {
    return forge.pki.ed25519.generateKeyPair({
        seed
    });
};
exports.hashAndSign = async function(key, msg) {
    return forge.pki.ed25519.sign({
        message: msg,
        privateKey: key
    });
// return Uint8Array.from(nacl.sign.detached(msg, key))
};
exports.hashAndVerify = async function(key, sig, msg) {
    return forge.pki.ed25519.verify({
        signature: sig,
        message: msg,
        publicKey: key
    });
};

},{"node-forge/lib/ed25519":"3DfIA","node-forge/lib/forge":"7AnVp"}],"6ex4h":[function(require,module,exports) {
'use strict';
const { sha256  } = require('multiformats/hashes/sha2');
const errcode = require('err-code');
const { equals: uint8ArrayEquals  } = require('uint8arrays/equals');
const { toString: uint8ArrayToString  } = require('uint8arrays/to-string');
const exporter = require('./exporter');
module.exports = (keysProtobuf, randomBytes, crypto)=>{
    crypto = crypto || require('./secp256k1')(randomBytes);
    class Secp256k1PublicKey {
        constructor(key){
            crypto.validatePublicKey(key);
            this._key = key;
        }
        verify(data, sig) {
            return crypto.hashAndVerify(this._key, sig, data);
        }
        marshal() {
            return crypto.compressPublicKey(this._key);
        }
        get bytes() {
            return keysProtobuf.PublicKey.encode({
                Type: keysProtobuf.KeyType.Secp256k1,
                Data: this.marshal()
            }).finish();
        }
        equals(key1) {
            return uint8ArrayEquals(this.bytes, key1.bytes);
        }
        async hash() {
            const { bytes  } = await sha256.digest(this.bytes);
            return bytes;
        }
    }
    class Secp256k1PrivateKey {
        constructor(key2, publicKey){
            this._key = key2;
            this._publicKey = publicKey || crypto.computePublicKey(key2);
            crypto.validatePrivateKey(this._key);
            crypto.validatePublicKey(this._publicKey);
        }
        sign(message) {
            return crypto.hashAndSign(this._key, message);
        }
        get public() {
            return new Secp256k1PublicKey(this._publicKey);
        }
        marshal() {
            return this._key;
        }
        get bytes() {
            return keysProtobuf.PrivateKey.encode({
                Type: keysProtobuf.KeyType.Secp256k1,
                Data: this.marshal()
            }).finish();
        }
        equals(key3) {
            return uint8ArrayEquals(this.bytes, key3.bytes);
        }
        async hash() {
            const { bytes  } = await sha256.digest(this.bytes);
            return bytes;
        }
        /**
     * Gets the ID of the key.
     *
     * The key id is the base58 encoding of the SHA-256 multihash of its public key.
     * The public key is a protobuf encoding containing a type and the DER encoding
     * of the PKCS SubjectPublicKeyInfo.
     *
     * @returns {Promise<string>}
     */ async id() {
            const hash = await this.public.hash();
            return uint8ArrayToString(hash, 'base58btc');
        }
        /**
     * Exports the key into a password protected `format`
     *
     * @param {string} password - The password to encrypt the key
     * @param {string} [format=libp2p-key] - The format in which to export as
     * @returns {Promise<string>} The encrypted private key
     */ async export(password, format = 'libp2p-key') {
            if (format === 'libp2p-key') return exporter.export(this.bytes, password);
            else throw errcode(new Error(`export format '${format}' is not supported`), 'ERR_INVALID_EXPORT_FORMAT');
        }
    }
    function unmarshalSecp256k1PrivateKey(bytes) {
        return new Secp256k1PrivateKey(bytes);
    }
    function unmarshalSecp256k1PublicKey(bytes) {
        return new Secp256k1PublicKey(bytes);
    }
    async function generateKeyPair() {
        const privateKeyBytes = await crypto.generateKey();
        return new Secp256k1PrivateKey(privateKeyBytes);
    }
    return {
        Secp256k1PublicKey,
        Secp256k1PrivateKey,
        unmarshalSecp256k1PrivateKey,
        unmarshalSecp256k1PublicKey,
        generateKeyPair
    };
};

},{"multiformats/hashes/sha2":"i8JnP","err-code":"eQvyh","uint8arrays/equals":"fjLeN","uint8arrays/to-string":"g3mCQ","./exporter":"3mrEx","./secp256k1":"3TGCF"}],"3TGCF":[function(require,module,exports) {
'use strict';
const secp256k1 = require('secp256k1');
const { sha256  } = require('multiformats/hashes/sha2');
module.exports = (randomBytes)=>{
    const privateKeyLength = 32;
    function generateKey() {
        let privateKey;
        do privateKey = randomBytes(32);
        while (!secp256k1.privateKeyVerify(privateKey))
        return privateKey;
    }
    async function hashAndSign(key, msg) {
        const { digest  } = await sha256.digest(msg);
        const sig = secp256k1.ecdsaSign(digest, key);
        return secp256k1.signatureExport(sig.signature);
    }
    async function hashAndVerify(key, sig, msg) {
        const { digest  } = await sha256.digest(msg);
        sig = secp256k1.signatureImport(sig);
        return secp256k1.ecdsaVerify(sig, digest, key);
    }
    function compressPublicKey(key) {
        if (!secp256k1.publicKeyVerify(key)) throw new Error('Invalid public key');
        return secp256k1.publicKeyConvert(key, true);
    }
    function decompressPublicKey(key) {
        return secp256k1.publicKeyConvert(key, false);
    }
    function validatePrivateKey(key) {
        if (!secp256k1.privateKeyVerify(key)) throw new Error('Invalid private key');
    }
    function validatePublicKey(key) {
        if (!secp256k1.publicKeyVerify(key)) throw new Error('Invalid public key');
    }
    function computePublicKey(privateKey) {
        validatePrivateKey(privateKey);
        return secp256k1.publicKeyCreate(privateKey);
    }
    return {
        generateKey,
        privateKeyLength,
        hashAndSign,
        hashAndVerify,
        compressPublicKey,
        decompressPublicKey,
        validatePrivateKey,
        validatePublicKey,
        computePublicKey
    };
};

},{"secp256k1":"d3C5s","multiformats/hashes/sha2":"i8JnP"}],"d3C5s":[function(require,module,exports) {
module.exports = require('./lib')(require('./lib/elliptic'));

},{"./lib":"joMwN","./lib/elliptic":"kA7Lc"}],"joMwN":[function(require,module,exports) {
const errors = {
    IMPOSSIBLE_CASE: 'Impossible case. Please create issue.',
    TWEAK_ADD: 'The tweak was out of range or the resulted private key is invalid',
    TWEAK_MUL: 'The tweak was out of range or equal to zero',
    CONTEXT_RANDOMIZE_UNKNOW: 'Unknow error on context randomization',
    SECKEY_INVALID: 'Private Key is invalid',
    PUBKEY_PARSE: 'Public Key could not be parsed',
    PUBKEY_SERIALIZE: 'Public Key serialization error',
    PUBKEY_COMBINE: 'The sum of the public keys is not valid',
    SIG_PARSE: 'Signature could not be parsed',
    SIGN: 'The nonce generation function failed, or the private key was invalid',
    RECOVER: 'Public key could not be recover',
    ECDH: 'Scalar was invalid (zero or overflow)'
};
function assert(cond, msg) {
    if (!cond) throw new Error(msg);
}
function isUint8Array(name, value, length) {
    assert(value instanceof Uint8Array, `Expected ${name} to be an Uint8Array`);
    if (length !== undefined) {
        if (Array.isArray(length)) {
            const numbers = length.join(', ');
            const msg = `Expected ${name} to be an Uint8Array with length [${numbers}]`;
            assert(length.includes(value.length), msg);
        } else {
            const msg = `Expected ${name} to be an Uint8Array with length ${length}`;
            assert(value.length === length, msg);
        }
    }
}
function isCompressed(value) {
    assert(toTypeString(value) === 'Boolean', 'Expected compressed to be a Boolean');
}
function getAssertedOutput(output = (len)=>new Uint8Array(len)
, length) {
    if (typeof output === 'function') output = output(length);
    isUint8Array('output', output, length);
    return output;
}
function toTypeString(value) {
    return Object.prototype.toString.call(value).slice(8, -1);
}
module.exports = (secp256k1)=>{
    return {
        contextRandomize (seed) {
            assert(seed === null || seed instanceof Uint8Array, 'Expected seed to be an Uint8Array or null');
            if (seed !== null) isUint8Array('seed', seed, 32);
            switch(secp256k1.contextRandomize(seed)){
                case 1:
                    throw new Error(errors.CONTEXT_RANDOMIZE_UNKNOW);
            }
        },
        privateKeyVerify (seckey) {
            isUint8Array('private key', seckey, 32);
            return secp256k1.privateKeyVerify(seckey) === 0;
        },
        privateKeyNegate (seckey) {
            isUint8Array('private key', seckey, 32);
            switch(secp256k1.privateKeyNegate(seckey)){
                case 0:
                    return seckey;
                case 1:
                    throw new Error(errors.IMPOSSIBLE_CASE);
            }
        },
        privateKeyTweakAdd (seckey, tweak) {
            isUint8Array('private key', seckey, 32);
            isUint8Array('tweak', tweak, 32);
            switch(secp256k1.privateKeyTweakAdd(seckey, tweak)){
                case 0:
                    return seckey;
                case 1:
                    throw new Error(errors.TWEAK_ADD);
            }
        },
        privateKeyTweakMul (seckey, tweak) {
            isUint8Array('private key', seckey, 32);
            isUint8Array('tweak', tweak, 32);
            switch(secp256k1.privateKeyTweakMul(seckey, tweak)){
                case 0:
                    return seckey;
                case 1:
                    throw new Error(errors.TWEAK_MUL);
            }
        },
        publicKeyVerify (pubkey) {
            isUint8Array('public key', pubkey, [
                33,
                65
            ]);
            return secp256k1.publicKeyVerify(pubkey) === 0;
        },
        publicKeyCreate (seckey, compressed = true, output) {
            isUint8Array('private key', seckey, 32);
            isCompressed(compressed);
            output = getAssertedOutput(output, compressed ? 33 : 65);
            switch(secp256k1.publicKeyCreate(output, seckey)){
                case 0:
                    return output;
                case 1:
                    throw new Error(errors.SECKEY_INVALID);
                case 2:
                    throw new Error(errors.PUBKEY_SERIALIZE);
            }
        },
        publicKeyConvert (pubkey, compressed = true, output) {
            isUint8Array('public key', pubkey, [
                33,
                65
            ]);
            isCompressed(compressed);
            output = getAssertedOutput(output, compressed ? 33 : 65);
            switch(secp256k1.publicKeyConvert(output, pubkey)){
                case 0:
                    return output;
                case 1:
                    throw new Error(errors.PUBKEY_PARSE);
                case 2:
                    throw new Error(errors.PUBKEY_SERIALIZE);
            }
        },
        publicKeyNegate (pubkey, compressed = true, output) {
            isUint8Array('public key', pubkey, [
                33,
                65
            ]);
            isCompressed(compressed);
            output = getAssertedOutput(output, compressed ? 33 : 65);
            switch(secp256k1.publicKeyNegate(output, pubkey)){
                case 0:
                    return output;
                case 1:
                    throw new Error(errors.PUBKEY_PARSE);
                case 2:
                    throw new Error(errors.IMPOSSIBLE_CASE);
                case 3:
                    throw new Error(errors.PUBKEY_SERIALIZE);
            }
        },
        publicKeyCombine (pubkeys, compressed = true, output) {
            assert(Array.isArray(pubkeys), 'Expected public keys to be an Array');
            assert(pubkeys.length > 0, 'Expected public keys array will have more than zero items');
            for (const pubkey of pubkeys)isUint8Array('public key', pubkey, [
                33,
                65
            ]);
            isCompressed(compressed);
            output = getAssertedOutput(output, compressed ? 33 : 65);
            switch(secp256k1.publicKeyCombine(output, pubkeys)){
                case 0:
                    return output;
                case 1:
                    throw new Error(errors.PUBKEY_PARSE);
                case 2:
                    throw new Error(errors.PUBKEY_COMBINE);
                case 3:
                    throw new Error(errors.PUBKEY_SERIALIZE);
            }
        },
        publicKeyTweakAdd (pubkey, tweak, compressed = true, output) {
            isUint8Array('public key', pubkey, [
                33,
                65
            ]);
            isUint8Array('tweak', tweak, 32);
            isCompressed(compressed);
            output = getAssertedOutput(output, compressed ? 33 : 65);
            switch(secp256k1.publicKeyTweakAdd(output, pubkey, tweak)){
                case 0:
                    return output;
                case 1:
                    throw new Error(errors.PUBKEY_PARSE);
                case 2:
                    throw new Error(errors.TWEAK_ADD);
            }
        },
        publicKeyTweakMul (pubkey, tweak, compressed = true, output) {
            isUint8Array('public key', pubkey, [
                33,
                65
            ]);
            isUint8Array('tweak', tweak, 32);
            isCompressed(compressed);
            output = getAssertedOutput(output, compressed ? 33 : 65);
            switch(secp256k1.publicKeyTweakMul(output, pubkey, tweak)){
                case 0:
                    return output;
                case 1:
                    throw new Error(errors.PUBKEY_PARSE);
                case 2:
                    throw new Error(errors.TWEAK_MUL);
            }
        },
        signatureNormalize (sig) {
            isUint8Array('signature', sig, 64);
            switch(secp256k1.signatureNormalize(sig)){
                case 0:
                    return sig;
                case 1:
                    throw new Error(errors.SIG_PARSE);
            }
        },
        signatureExport (sig, output) {
            isUint8Array('signature', sig, 64);
            output = getAssertedOutput(output, 72);
            const obj = {
                output,
                outputlen: 72
            };
            switch(secp256k1.signatureExport(obj, sig)){
                case 0:
                    return output.slice(0, obj.outputlen);
                case 1:
                    throw new Error(errors.SIG_PARSE);
                case 2:
                    throw new Error(errors.IMPOSSIBLE_CASE);
            }
        },
        signatureImport (sig, output) {
            isUint8Array('signature', sig);
            output = getAssertedOutput(output, 64);
            switch(secp256k1.signatureImport(output, sig)){
                case 0:
                    return output;
                case 1:
                    throw new Error(errors.SIG_PARSE);
                case 2:
                    throw new Error(errors.IMPOSSIBLE_CASE);
            }
        },
        ecdsaSign (msg32, seckey, options = {
        }, output) {
            isUint8Array('message', msg32, 32);
            isUint8Array('private key', seckey, 32);
            assert(toTypeString(options) === 'Object', 'Expected options to be an Object');
            if (options.data !== undefined) isUint8Array('options.data', options.data);
            if (options.noncefn !== undefined) assert(toTypeString(options.noncefn) === 'Function', 'Expected options.noncefn to be a Function');
            output = getAssertedOutput(output, 64);
            const obj = {
                signature: output,
                recid: null
            };
            switch(secp256k1.ecdsaSign(obj, msg32, seckey, options.data, options.noncefn)){
                case 0:
                    return obj;
                case 1:
                    throw new Error(errors.SIGN);
                case 2:
                    throw new Error(errors.IMPOSSIBLE_CASE);
            }
        },
        ecdsaVerify (sig, msg32, pubkey) {
            isUint8Array('signature', sig, 64);
            isUint8Array('message', msg32, 32);
            isUint8Array('public key', pubkey, [
                33,
                65
            ]);
            switch(secp256k1.ecdsaVerify(sig, msg32, pubkey)){
                case 0:
                    return true;
                case 3:
                    return false;
                case 1:
                    throw new Error(errors.SIG_PARSE);
                case 2:
                    throw new Error(errors.PUBKEY_PARSE);
            }
        },
        ecdsaRecover (sig, recid, msg32, compressed = true, output) {
            isUint8Array('signature', sig, 64);
            assert(toTypeString(recid) === 'Number' && recid >= 0 && recid <= 3, 'Expected recovery id to be a Number within interval [0, 3]');
            isUint8Array('message', msg32, 32);
            isCompressed(compressed);
            output = getAssertedOutput(output, compressed ? 33 : 65);
            switch(secp256k1.ecdsaRecover(output, sig, recid, msg32)){
                case 0:
                    return output;
                case 1:
                    throw new Error(errors.SIG_PARSE);
                case 2:
                    throw new Error(errors.RECOVER);
                case 3:
                    throw new Error(errors.IMPOSSIBLE_CASE);
            }
        },
        ecdh (pubkey, seckey, options = {
        }, output) {
            isUint8Array('public key', pubkey, [
                33,
                65
            ]);
            isUint8Array('private key', seckey, 32);
            assert(toTypeString(options) === 'Object', 'Expected options to be an Object');
            if (options.data !== undefined) isUint8Array('options.data', options.data);
            if (options.hashfn !== undefined) {
                assert(toTypeString(options.hashfn) === 'Function', 'Expected options.hashfn to be a Function');
                if (options.xbuf !== undefined) isUint8Array('options.xbuf', options.xbuf, 32);
                if (options.ybuf !== undefined) isUint8Array('options.ybuf', options.ybuf, 32);
                isUint8Array('output', output);
            } else output = getAssertedOutput(output, 32);
            switch(secp256k1.ecdh(output, pubkey, seckey, options.data, options.hashfn, options.xbuf, options.ybuf)){
                case 0:
                    return output;
                case 1:
                    throw new Error(errors.PUBKEY_PARSE);
                case 2:
                    throw new Error(errors.ECDH);
            }
        }
    };
};

},{}],"kA7Lc":[function(require,module,exports) {
const EC = require('elliptic').ec;
const ec = new EC('secp256k1');
const ecparams = ec.curve;
// Hack, we can not use bn.js@5, while elliptic uses bn.js@4
// See https://github.com/indutny/elliptic/issues/191#issuecomment-569888758
const BN = ecparams.n.constructor;
function loadCompressedPublicKey(first, xbuf) {
    let x = new BN(xbuf);
    // overflow
    if (x.cmp(ecparams.p) >= 0) return null;
    x = x.toRed(ecparams.red);
    // compute corresponding Y
    let y = x.redSqr().redIMul(x).redIAdd(ecparams.b).redSqrt();
    if (first === 3 !== y.isOdd()) y = y.redNeg();
    return ec.keyPair({
        pub: {
            x: x,
            y: y
        }
    });
}
function loadUncompressedPublicKey(first, xbuf, ybuf) {
    let x = new BN(xbuf);
    let y = new BN(ybuf);
    // overflow
    if (x.cmp(ecparams.p) >= 0 || y.cmp(ecparams.p) >= 0) return null;
    x = x.toRed(ecparams.red);
    y = y.toRed(ecparams.red);
    // is odd flag
    if ((first === 6 || first === 7) && y.isOdd() !== (first === 7)) return null;
    // x*x*x + b = y*y
    const x3 = x.redSqr().redIMul(x);
    if (!y.redSqr().redISub(x3.redIAdd(ecparams.b)).isZero()) return null;
    return ec.keyPair({
        pub: {
            x: x,
            y: y
        }
    });
}
function loadPublicKey(pubkey) {
    // length should be validated in interface
    const first = pubkey[0];
    switch(first){
        case 2:
        case 3:
            if (pubkey.length !== 33) return null;
            return loadCompressedPublicKey(first, pubkey.subarray(1, 33));
        case 4:
        case 6:
        case 7:
            if (pubkey.length !== 65) return null;
            return loadUncompressedPublicKey(first, pubkey.subarray(1, 33), pubkey.subarray(33, 65));
        default:
            return null;
    }
}
function savePublicKey(output, point) {
    const pubkey = point.encode(null, output.length === 33);
    // Loop should be faster because we do not need create extra Uint8Array
    // output.set(new Uint8Array(pubkey))
    for(let i = 0; i < output.length; ++i)output[i] = pubkey[i];
}
module.exports = {
    contextRandomize () {
        return 0;
    },
    privateKeyVerify (seckey) {
        const bn = new BN(seckey);
        return bn.cmp(ecparams.n) < 0 && !bn.isZero() ? 0 : 1;
    },
    privateKeyNegate (seckey) {
        const bn = new BN(seckey);
        const negate = ecparams.n.sub(bn).umod(ecparams.n).toArrayLike(Uint8Array, 'be', 32);
        seckey.set(negate);
        return 0;
    },
    privateKeyTweakAdd (seckey, tweak) {
        const bn = new BN(tweak);
        if (bn.cmp(ecparams.n) >= 0) return 1;
        bn.iadd(new BN(seckey));
        if (bn.cmp(ecparams.n) >= 0) bn.isub(ecparams.n);
        if (bn.isZero()) return 1;
        const tweaked = bn.toArrayLike(Uint8Array, 'be', 32);
        seckey.set(tweaked);
        return 0;
    },
    privateKeyTweakMul (seckey, tweak) {
        let bn = new BN(tweak);
        if (bn.cmp(ecparams.n) >= 0 || bn.isZero()) return 1;
        bn.imul(new BN(seckey));
        if (bn.cmp(ecparams.n) >= 0) bn = bn.umod(ecparams.n);
        const tweaked = bn.toArrayLike(Uint8Array, 'be', 32);
        seckey.set(tweaked);
        return 0;
    },
    publicKeyVerify (pubkey) {
        const pair = loadPublicKey(pubkey);
        return pair === null ? 1 : 0;
    },
    publicKeyCreate (output, seckey) {
        const bn = new BN(seckey);
        if (bn.cmp(ecparams.n) >= 0 || bn.isZero()) return 1;
        const point = ec.keyFromPrivate(seckey).getPublic();
        savePublicKey(output, point);
        return 0;
    },
    publicKeyConvert (output, pubkey) {
        const pair = loadPublicKey(pubkey);
        if (pair === null) return 1;
        const point = pair.getPublic();
        savePublicKey(output, point);
        return 0;
    },
    publicKeyNegate (output, pubkey) {
        const pair = loadPublicKey(pubkey);
        if (pair === null) return 1;
        const point = pair.getPublic();
        point.y = point.y.redNeg();
        savePublicKey(output, point);
        return 0;
    },
    publicKeyCombine (output, pubkeys) {
        const pairs = new Array(pubkeys.length);
        for(let i = 0; i < pubkeys.length; ++i){
            pairs[i] = loadPublicKey(pubkeys[i]);
            if (pairs[i] === null) return 1;
        }
        let point = pairs[0].getPublic();
        for(let i1 = 1; i1 < pairs.length; ++i1)point = point.add(pairs[i1].pub);
        if (point.isInfinity()) return 2;
        savePublicKey(output, point);
        return 0;
    },
    publicKeyTweakAdd (output, pubkey, tweak) {
        const pair = loadPublicKey(pubkey);
        if (pair === null) return 1;
        tweak = new BN(tweak);
        if (tweak.cmp(ecparams.n) >= 0) return 2;
        const point = pair.getPublic().add(ecparams.g.mul(tweak));
        if (point.isInfinity()) return 2;
        savePublicKey(output, point);
        return 0;
    },
    publicKeyTweakMul (output, pubkey, tweak) {
        const pair = loadPublicKey(pubkey);
        if (pair === null) return 1;
        tweak = new BN(tweak);
        if (tweak.cmp(ecparams.n) >= 0 || tweak.isZero()) return 2;
        const point = pair.getPublic().mul(tweak);
        savePublicKey(output, point);
        return 0;
    },
    signatureNormalize (sig) {
        const r = new BN(sig.subarray(0, 32));
        const s = new BN(sig.subarray(32, 64));
        if (r.cmp(ecparams.n) >= 0 || s.cmp(ecparams.n) >= 0) return 1;
        if (s.cmp(ec.nh) === 1) sig.set(ecparams.n.sub(s).toArrayLike(Uint8Array, 'be', 32), 32);
        return 0;
    },
    // Copied 1-to-1 from https://github.com/bitcoinjs/bip66/blob/master/index.js
    // Adapted for Uint8Array instead Buffer
    signatureExport (obj, sig) {
        const sigR = sig.subarray(0, 32);
        const sigS = sig.subarray(32, 64);
        if (new BN(sigR).cmp(ecparams.n) >= 0) return 1;
        if (new BN(sigS).cmp(ecparams.n) >= 0) return 1;
        const { output  } = obj;
        // Prepare R
        let r = output.subarray(4, 37);
        r[0] = 0;
        r.set(sigR, 1);
        let lenR = 33;
        let posR = 0;
        for(; lenR > 1 && r[posR] === 0 && !(r[posR + 1] & 128); --lenR, ++posR);
        r = r.subarray(posR);
        if (r[0] & 128) return 1;
        if (lenR > 1 && r[0] === 0 && !(r[1] & 128)) return 1;
        // Prepare S
        let s = output.subarray(39, 72);
        s[0] = 0;
        s.set(sigS, 1);
        let lenS = 33;
        let posS = 0;
        for(; lenS > 1 && s[posS] === 0 && !(s[posS + 1] & 128); --lenS, ++posS);
        s = s.subarray(posS);
        if (s[0] & 128) return 1;
        if (lenS > 1 && s[0] === 0 && !(s[1] & 128)) return 1;
        // Set output length for return
        obj.outputlen = 6 + lenR + lenS;
        // Output in specified format
        // 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S]
        output[0] = 48;
        output[1] = obj.outputlen - 2;
        output[2] = 2;
        output[3] = r.length;
        output.set(r, 4);
        output[4 + lenR] = 2;
        output[5 + lenR] = s.length;
        output.set(s, 6 + lenR);
        return 0;
    },
    // Copied 1-to-1 from https://github.com/bitcoinjs/bip66/blob/master/index.js
    // Adapted for Uint8Array instead Buffer
    signatureImport (output, sig) {
        if (sig.length < 8) return 1;
        if (sig.length > 72) return 1;
        if (sig[0] !== 48) return 1;
        if (sig[1] !== sig.length - 2) return 1;
        if (sig[2] !== 2) return 1;
        const lenR = sig[3];
        if (lenR === 0) return 1;
        if (5 + lenR >= sig.length) return 1;
        if (sig[4 + lenR] !== 2) return 1;
        const lenS = sig[5 + lenR];
        if (lenS === 0) return 1;
        if (6 + lenR + lenS !== sig.length) return 1;
        if (sig[4] & 128) return 1;
        if (lenR > 1 && sig[4] === 0 && !(sig[5] & 128)) return 1;
        if (sig[lenR + 6] & 128) return 1;
        if (lenS > 1 && sig[lenR + 6] === 0 && !(sig[lenR + 7] & 128)) return 1;
        let sigR = sig.subarray(4, 4 + lenR);
        if (sigR.length === 33 && sigR[0] === 0) sigR = sigR.subarray(1);
        if (sigR.length > 32) return 1;
        let sigS = sig.subarray(6 + lenR);
        if (sigS.length === 33 && sigS[0] === 0) sigS = sigS.slice(1);
        if (sigS.length > 32) throw new Error('S length is too long');
        let r = new BN(sigR);
        if (r.cmp(ecparams.n) >= 0) r = new BN(0);
        let s = new BN(sig.subarray(6 + lenR));
        if (s.cmp(ecparams.n) >= 0) s = new BN(0);
        output.set(r.toArrayLike(Uint8Array, 'be', 32), 0);
        output.set(s.toArrayLike(Uint8Array, 'be', 32), 32);
        return 0;
    },
    ecdsaSign (obj, message, seckey, data, noncefn) {
        if (noncefn) {
            const _noncefn = noncefn;
            noncefn = (counter)=>{
                const nonce = _noncefn(message, seckey, null, data, counter);
                const isValid = nonce instanceof Uint8Array && nonce.length === 32;
                if (!isValid) throw new Error('This is the way');
                return new BN(nonce);
            };
        }
        const d = new BN(seckey);
        if (d.cmp(ecparams.n) >= 0 || d.isZero()) return 1;
        let sig;
        try {
            sig = ec.sign(message, seckey, {
                canonical: true,
                k: noncefn,
                pers: data
            });
        } catch (err) {
            return 1;
        }
        obj.signature.set(sig.r.toArrayLike(Uint8Array, 'be', 32), 0);
        obj.signature.set(sig.s.toArrayLike(Uint8Array, 'be', 32), 32);
        obj.recid = sig.recoveryParam;
        return 0;
    },
    ecdsaVerify (sig, msg32, pubkey) {
        const sigObj = {
            r: sig.subarray(0, 32),
            s: sig.subarray(32, 64)
        };
        const sigr = new BN(sigObj.r);
        const sigs = new BN(sigObj.s);
        if (sigr.cmp(ecparams.n) >= 0 || sigs.cmp(ecparams.n) >= 0) return 1;
        if (sigs.cmp(ec.nh) === 1 || sigr.isZero() || sigs.isZero()) return 3;
        const pair = loadPublicKey(pubkey);
        if (pair === null) return 2;
        const point = pair.getPublic();
        const isValid = ec.verify(msg32, sigObj, point);
        return isValid ? 0 : 3;
    },
    ecdsaRecover (output, sig, recid, msg32) {
        const sigObj = {
            r: sig.slice(0, 32),
            s: sig.slice(32, 64)
        };
        const sigr = new BN(sigObj.r);
        const sigs = new BN(sigObj.s);
        if (sigr.cmp(ecparams.n) >= 0 || sigs.cmp(ecparams.n) >= 0) return 1;
        if (sigr.isZero() || sigs.isZero()) return 2;
        // Can throw `throw new Error('Unable to find sencond key candinate');`
        let point;
        try {
            point = ec.recoverPubKey(msg32, sigObj, recid);
        } catch (err) {
            return 2;
        }
        savePublicKey(output, point);
        return 0;
    },
    ecdh (output, pubkey, seckey, data, hashfn, xbuf, ybuf) {
        const pair = loadPublicKey(pubkey);
        if (pair === null) return 1;
        const scalar = new BN(seckey);
        if (scalar.cmp(ecparams.n) >= 0 || scalar.isZero()) return 2;
        const point = pair.getPublic().mul(scalar);
        if (hashfn === undefined) {
            const data = point.encode(null, true);
            const sha256 = ec.hash().update(data).digest();
            for(let i = 0; i < 32; ++i)output[i] = sha256[i];
        } else {
            if (!xbuf) xbuf = new Uint8Array(32);
            const x = point.getX().toArray('be', 32);
            for(let i = 0; i < 32; ++i)xbuf[i] = x[i];
            if (!ybuf) ybuf = new Uint8Array(32);
            const y = point.getY().toArray('be', 32);
            for(let i2 = 0; i2 < 32; ++i2)ybuf[i2] = y[i2];
            const hash = hashfn(xbuf, ybuf, data);
            const isValid = hash instanceof Uint8Array && hash.length === output.length;
            if (!isValid) return 2;
            output.set(hash);
        }
        return 0;
    }
};

},{"elliptic":"5ORyj"}],"5ORyj":[function(require,module,exports) {
'use strict';
var elliptic = exports;
elliptic.version = require('../package.json').version;
elliptic.utils = require('./elliptic/utils');
elliptic.rand = require('brorand');
elliptic.curve = require('./elliptic/curve');
elliptic.curves = require('./elliptic/curves');
// Protocols
elliptic.ec = require('./elliptic/ec');
elliptic.eddsa = require('./elliptic/eddsa');

},{"../package.json":"gjl4S","./elliptic/utils":"8fQ1m","brorand":"ekppu","./elliptic/curve":"kUMBS","./elliptic/curves":"jyUMP","./elliptic/ec":"18hLW","./elliptic/eddsa":"fk7wS"}],"gjl4S":[function(require,module,exports) {
module.exports = JSON.parse("{\"name\":\"elliptic\",\"version\":\"6.5.4\",\"description\":\"EC cryptography\",\"main\":\"lib/elliptic.js\",\"files\":[\"lib\"],\"scripts\":{\"lint\":\"eslint lib test\",\"lint:fix\":\"npm run lint -- --fix\",\"unit\":\"istanbul test _mocha --reporter=spec test/index.js\",\"test\":\"npm run lint && npm run unit\",\"version\":\"grunt dist && git add dist/\"},\"repository\":{\"type\":\"git\",\"url\":\"git@github.com:indutny/elliptic\"},\"keywords\":[\"EC\",\"Elliptic\",\"curve\",\"Cryptography\"],\"author\":\"Fedor Indutny <fedor@indutny.com>\",\"license\":\"MIT\",\"bugs\":{\"url\":\"https://github.com/indutny/elliptic/issues\"},\"homepage\":\"https://github.com/indutny/elliptic\",\"devDependencies\":{\"brfs\":\"^2.0.2\",\"coveralls\":\"^3.1.0\",\"eslint\":\"^7.6.0\",\"grunt\":\"^1.2.1\",\"grunt-browserify\":\"^5.3.0\",\"grunt-cli\":\"^1.3.2\",\"grunt-contrib-connect\":\"^3.0.0\",\"grunt-contrib-copy\":\"^1.0.0\",\"grunt-contrib-uglify\":\"^5.0.0\",\"grunt-mocha-istanbul\":\"^5.0.2\",\"grunt-saucelabs\":\"^9.0.1\",\"istanbul\":\"^0.4.5\",\"mocha\":\"^8.0.1\"},\"dependencies\":{\"bn.js\":\"^4.11.9\",\"brorand\":\"^1.1.0\",\"hash.js\":\"^1.0.0\",\"hmac-drbg\":\"^1.0.1\",\"inherits\":\"^2.0.4\",\"minimalistic-assert\":\"^1.0.1\",\"minimalistic-crypto-utils\":\"^1.0.1\"}}");

},{}],"8fQ1m":[function(require,module,exports) {
'use strict';
var utils = exports;
var BN = require('bn.js');
var minAssert = require('minimalistic-assert');
var minUtils = require('minimalistic-crypto-utils');
utils.assert = minAssert;
utils.toArray = minUtils.toArray;
utils.zero2 = minUtils.zero2;
utils.toHex = minUtils.toHex;
utils.encode = minUtils.encode;
// Represent num in a w-NAF form
function getNAF(num, w, bits) {
    var naf = new Array(Math.max(num.bitLength(), bits) + 1);
    naf.fill(0);
    var ws = 1 << w + 1;
    var k = num.clone();
    for(var i = 0; i < naf.length; i++){
        var z;
        var mod = k.andln(ws - 1);
        if (k.isOdd()) {
            if (mod > (ws >> 1) - 1) z = (ws >> 1) - mod;
            else z = mod;
            k.isubn(z);
        } else z = 0;
        naf[i] = z;
        k.iushrn(1);
    }
    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;
    var m8;
    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 {
            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 {
            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;

},{"bn.js":"7NXhe","minimalistic-assert":"8j7xw","minimalistic-crypto-utils":"b17ct"}],"7NXhe":[function(require,module,exports) {
(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 {
        if (typeof window !== 'undefined' && typeof window.Buffer !== 'undefined') Buffer = window.Buffer;
        else Buffer = require('buffer').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++;
            this.negative = 1;
        }
        if (start < number.length) {
            if (base === 16) this._parseHex(number, start, endian);
            else {
                this._parseBase(number, base, start);
                if (endian === 'le') this._initArray(this.toArray(), base, endian);
            }
        }
    };
    BN.prototype._initNumber = function _initNumber(number, base, endian) {
        if (number < 0) {
            this.negative = 1;
            number = -number;
        }
        if (number < 67108864) {
            this.words = [
                number & 67108863
            ];
            this.length = 1;
        } else if (number < 4503599627370496) {
            this.words = [
                number & 67108863,
                number / 67108864 & 67108863
            ];
            this.length = 2;
        } else {
            assert(number < 9007199254740992); // 2 ^ 53 (unsafe)
            this.words = [
                number & 67108863,
                number / 67108864 & 67108863,
                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 & 67108863;
            this.words[j + 1] = w >>> 26 - off & 67108863;
            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 & 67108863;
            this.words[j + 1] = w >>> 26 - off & 67108863;
            off += 24;
            if (off >= 26) {
                off -= 26;
                j++;
            }
        }
        return this.strip();
    };
    function parseHex4Bits(string, index) {
        var c = string.charCodeAt(index);
        // 'A' - 'F'
        if (c >= 65 && c <= 70) return c - 55;
        else if (c >= 97 && c <= 102) return c - 87;
        else return c - 48 & 15;
    }
    function parseHexByte(string, lowerBound, index) {
        var r = parseHex4Bits(string, index);
        if (index - 1 >= lowerBound) r |= parseHex4Bits(string, index - 1) << 4;
        return r;
    }
    BN.prototype._parseHex = function _parseHex(number, start, endian) {
        // 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;
        // 24-bits chunks
        var off = 0;
        var j = 0;
        var w;
        if (endian === 'be') for(i = number.length - 1; i >= start; i -= 2){
            w = parseHexByte(number, start, i) << off;
            this.words[j] |= w & 67108863;
            if (off >= 18) {
                off -= 18;
                j += 1;
                this.words[j] |= w >>> 26;
            } else off += 8;
        }
        else {
            var parseLength = number.length - start;
            for(i = parseLength % 2 === 0 ? start + 1 : start; i < number.length; i += 2){
                w = parseHexByte(number, start, i) << off;
                this.words[j] |= w & 67108863;
                if (off >= 18) {
                    off -= 18;
                    j += 1;
                    this.words[j] |= w >>> 26;
                } else off += 8;
            }
        }
        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 + 10;
            else if (c >= 17) r += c - 17 + 10;
            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 <= 67108863; 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 < 67108864) 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 < 67108864) this.words[0] += word;
            else this._iaddn(word);
        }
        this.strip();
    };
    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) & 16777215).toString(16);
                carry = w >>> 24 - off & 16777215;
                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] * 67108864;
        else if (this.length === 3 && this.words[2] === 1) // NOTE: at this stage it is known that the top bit is set
        ret += 4503599627370496 + this.words[1] * 67108864;
        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(255);
                q.iushrn(8);
                res[reqLength - i - 1] = b;
            }
        } else {
            for(i = 0; !q.isZero(); i++){
                b = q.andln(255);
                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 >= 4096) {
            r += 13;
            t >>>= 13;
        }
        if (t >= 64) {
            r += 7;
            t >>>= 7;
        }
        if (t >= 8) {
            r += 4;
            t >>>= 4;
        }
        if (t >= 2) {
            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 & 8191) === 0) {
            r += 13;
            t >>>= 13;
        }
        if ((t & 127) === 0) {
            r += 7;
            t >>>= 7;
        }
        if ((t & 15) === 0) {
            r += 4;
            t >>>= 4;
        }
        if ((t & 3) === 0) {
            r += 2;
            t >>>= 2;
        }
        if ((t & 1) === 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] & 67108863;
        // Handle the residue
        if (bitsLeft > 0) this.words[i] = ~this.words[i] & 67108863 >> 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 & 67108863;
            carry = r >>> 26;
        }
        for(; carry !== 0 && i < a.length; i++){
            r = (a.words[i] | 0) + carry;
            this.words[i] = r & 67108863;
            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 & 67108863;
        }
        for(; carry !== 0 && i < a.length; i++){
            r = (a.words[i] | 0) + carry;
            carry = r >> 26;
            this.words[i] = r & 67108863;
        }
        // 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 & 67108863;
        var carry = r / 67108864 | 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 & 67108863;
            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 / 67108864 | 0;
                rword = r & 67108863;
            }
            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 & 8191;
        var ah0 = a0 >>> 13;
        var a1 = a[1] | 0;
        var al1 = a1 & 8191;
        var ah1 = a1 >>> 13;
        var a2 = a[2] | 0;
        var al2 = a2 & 8191;
        var ah2 = a2 >>> 13;
        var a3 = a[3] | 0;
        var al3 = a3 & 8191;
        var ah3 = a3 >>> 13;
        var a4 = a[4] | 0;
        var al4 = a4 & 8191;
        var ah4 = a4 >>> 13;
        var a5 = a[5] | 0;
        var al5 = a5 & 8191;
        var ah5 = a5 >>> 13;
        var a6 = a[6] | 0;
        var al6 = a6 & 8191;
        var ah6 = a6 >>> 13;
        var a7 = a[7] | 0;
        var al7 = a7 & 8191;
        var ah7 = a7 >>> 13;
        var a8 = a[8] | 0;
        var al8 = a8 & 8191;
        var ah8 = a8 >>> 13;
        var a9 = a[9] | 0;
        var al9 = a9 & 8191;
        var ah9 = a9 >>> 13;
        var b0 = b[0] | 0;
        var bl0 = b0 & 8191;
        var bh0 = b0 >>> 13;
        var b1 = b[1] | 0;
        var bl1 = b1 & 8191;
        var bh1 = b1 >>> 13;
        var b2 = b[2] | 0;
        var bl2 = b2 & 8191;
        var bh2 = b2 >>> 13;
        var b3 = b[3] | 0;
        var bl3 = b3 & 8191;
        var bh3 = b3 >>> 13;
        var b4 = b[4] | 0;
        var bl4 = b4 & 8191;
        var bh4 = b4 >>> 13;
        var b5 = b[5] | 0;
        var bl5 = b5 & 8191;
        var bh5 = b5 >>> 13;
        var b6 = b[6] | 0;
        var bl6 = b6 & 8191;
        var bh6 = b6 >>> 13;
        var b7 = b[7] | 0;
        var bl7 = b7 & 8191;
        var bh7 = b7 >>> 13;
        var b8 = b[8] | 0;
        var bl8 = b8 & 8191;
        var bh8 = b8 >>> 13;
        var b9 = b[9] | 0;
        var bl9 = b9 & 8191;
        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 & 8191) << 13) | 0;
        c = (hi + (mid >>> 13) | 0) + (w0 >>> 26) | 0;
        w0 &= 67108863;
        /* 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 & 8191) << 13) | 0;
        c = (hi + (mid >>> 13) | 0) + (w1 >>> 26) | 0;
        w1 &= 67108863;
        /* 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 & 8191) << 13) | 0;
        c = (hi + (mid >>> 13) | 0) + (w2 >>> 26) | 0;
        w2 &= 67108863;
        /* 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 & 8191) << 13) | 0;
        c = (hi + (mid >>> 13) | 0) + (w3 >>> 26) | 0;
        w3 &= 67108863;
        /* 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 & 8191) << 13) | 0;
        c = (hi + (mid >>> 13) | 0) + (w4 >>> 26) | 0;
        w4 &= 67108863;
        /* 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 & 8191) << 13) | 0;
        c = (hi + (mid >>> 13) | 0) + (w5 >>> 26) | 0;
        w5 &= 67108863;
        /* 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 & 8191) << 13) | 0;
        c = (hi + (mid >>> 13) | 0) + (w6 >>> 26) | 0;
        w6 &= 67108863;
        /* 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 & 8191) << 13) | 0;
        c = (hi + (mid >>> 13) | 0) + (w7 >>> 26) | 0;
        w7 &= 67108863;
        /* 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 & 8191) << 13) | 0;
        c = (hi + (mid >>> 13) | 0) + (w8 >>> 26) | 0;
        w8 &= 67108863;
        /* 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 & 8191) << 13) | 0;
        c = (hi + (mid >>> 13) | 0) + (w9 >>> 26) | 0;
        w9 &= 67108863;
        /* 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 & 8191) << 13) | 0;
        c = (hi + (mid >>> 13) | 0) + (w10 >>> 26) | 0;
        w10 &= 67108863;
        /* 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 & 8191) << 13) | 0;
        c = (hi + (mid >>> 13) | 0) + (w11 >>> 26) | 0;
        w11 &= 67108863;
        /* 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 & 8191) << 13) | 0;
        c = (hi + (mid >>> 13) | 0) + (w12 >>> 26) | 0;
        w12 &= 67108863;
        /* 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 & 8191) << 13) | 0;
        c = (hi + (mid >>> 13) | 0) + (w13 >>> 26) | 0;
        w13 &= 67108863;
        /* 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 & 8191) << 13) | 0;
        c = (hi + (mid >>> 13) | 0) + (w14 >>> 26) | 0;
        w14 &= 67108863;
        /* 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 & 8191) << 13) | 0;
        c = (hi + (mid >>> 13) | 0) + (w15 >>> 26) | 0;
        w15 &= 67108863;
        /* 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 & 8191) << 13) | 0;
        c = (hi + (mid >>> 13) | 0) + (w16 >>> 26) | 0;
        w16 &= 67108863;
        /* 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 & 8191) << 13) | 0;
        c = (hi + (mid >>> 13) | 0) + (w17 >>> 26) | 0;
        w17 &= 67108863;
        /* 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 & 8191) << 13) | 0;
        c = (hi + (mid >>> 13) | 0) + (w18 >>> 26) | 0;
        w18 &= 67108863;
        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 & 67108863;
            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 & 67108863;
                ncarry = ncarry + (r / 67108864 | 0) | 0;
                lo = lo + rword | 0;
                rword = lo & 67108863;
                ncarry = ncarry + (lo >>> 26) | 0;
                hncarry += ncarry >>> 26;
                ncarry &= 67108863;
            }
            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) * 8192 + Math.round(ws[2 * i] / N) + carry;
            ws[i] = w & 67108863;
            if (w < 67108864) carry = 0;
            else carry = w / 67108864 | 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 & 8191;
            carry = carry >>> 13;
            rws[2 * i + 1] = carry & 8191;
            carry = carry >>> 13;
        }
        // Pad with zeroes
        for(i = 2 * len; i < N; ++i)rws[i] = 0;
        assert(carry === 0);
        assert((carry & -8192) === 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 < 67108864);
        // Carry
        var carry = 0;
        for(var i = 0; i < this.length; i++){
            var w = (this.words[i] | 0) * num;
            var lo = (w & 67108863) + (carry & 67108863);
            carry >>= 26;
            carry += w / 67108864 | 0;
            // NOTE: lo is 27bit maximum
            carry += lo >>> 26;
            this.words[i] = lo & 67108863;
        }
        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 = 67108863 >>> 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 = 67108863 ^ 67108863 >>> 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 = 67108863 ^ 67108863 >>> 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 < 67108864);
        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] >= 67108864; i++){
            this.words[i] -= 67108864;
            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 < 67108864);
        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] += 67108864;
            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 & 67108863;
            carry = (w >> 26) - (right / 67108864 | 0);
            this.words[i + shift] = w & 67108863;
        }
        for(; i < this.length - shift; i++){
            w = (this.words[i + shift] | 0) + carry;
            carry = w >> 26;
            this.words[i + shift] = w & 67108863;
        }
        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 & 67108863;
        }
        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) * 67108864 + (a.words[b.length + j - 1] | 0);
            // NOTE: (qj / bhi) is (0x3ffffff * 0x4000000 + 0x3ffffff) / 0x2000000 max
            // (0x7ffffff)
            qj = Math.min(qj / bhi | 0, 67108863);
            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 <= 67108863);
        var p = 67108864 % 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 <= 67108863);
        var carry = 0;
        for(var i = this.length - 1; i >= 0; i--){
            var w = (this.words[i] | 0) + carry * 67108864;
            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 &= 67108863;
            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 <= 67108863, '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 if (r.strip !== undefined) // r is BN v4 instance
        r.strip();
        else // r is BN v5 instance
        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 = 4194303;
        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 * 977;
            num.words[i] = lo & 67108863;
            lo = w * 64 + (lo / 67108864 | 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) * 19 + carry;
            var lo = hi & 67108863;
            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);
    };
})(typeof module === 'undefined' || module, this);

},{"buffer":"joWnX"}],"8j7xw":[function(require,module,exports) {
module.exports = assert;
function assert(val, msg) {
    if (!val) throw new Error(msg || 'Assertion failed');
}
assert.equal = function assertEqual(l, r, msg) {
    if (l != r) throw new Error(msg || 'Assertion failed: ' + l + ' != ' + r);
};

},{}],"b17ct":[function(require,module,exports) {
'use strict';
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 & 255;
        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;
};

},{}],"ekppu":[function(require,module,exports) {
var r;
module.exports = function rand(len) {
    if (!r) r = new Rand(null);
    return r.generate(len);
};
function Rand(rand) {
    this.rand = rand;
}
module.exports.Rand = 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;
    };
    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 = require('crypto');
    if (typeof crypto.randomBytes !== 'function') throw new Error('Not supported');
    Rand.prototype._rand = function _rand(n) {
        return crypto.randomBytes(n);
    };
} catch (e) {
}

},{"crypto":"joWnX"}],"kUMBS":[function(require,module,exports) {
'use strict';
var curve = exports;
curve.base = require('./base');
curve.short = require('./short');
curve.mont = require('./mont');
curve.edwards = require('./edwards');

},{"./base":"9WNVa","./short":"80dar","./mont":"4O4sW","./edwards":"btnEN"}],"9WNVa":[function(require,module,exports) {
'use strict';
var BN = require('bn.js');
var utils = require('../utils');
var getNAF = utils.getNAF;
var getJSF = utils.getJSF;
var assert = utils.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);
    this._bitLength = this.n ? this.n.bitLength() : 0;
    // 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);
    }
}
module.exports = 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(p.precomputed);
    var doubles = p._getDoubles();
    var naf = getNAF(k, 1, this._bitLength);
    var I = (1 << doubles.step + 1) - (doubles.step % 2 === 0 ? 2 : 1);
    I /= 3;
    // Translate into more windowed form
    var repr = [];
    var j;
    var nafW;
    for(j = 0; j < naf.length; j += doubles.step){
        nafW = 0;
        for(var l = j + doubles.step - 1; l >= j; l--)nafW = (nafW << 1) + naf[l];
        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(j = 0; j < repr.length; j++){
            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, this._bitLength);
    // 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 l = 0; i >= 0 && naf[i] === 0; i--)l++;
        if (i >= 0) l++;
        acc = acc.dblp(l);
        if (i < 0) break;
        var z = naf[i];
        assert(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;
    var i;
    var j;
    var p;
    for(i = 0; i < len; i++){
        p = points[i];
        var nafPoints = p._getNAFPoints(defW);
        wndWidth[i] = nafPoints.wnd;
        wnd[i] = nafPoints.points;
    }
    // Comb small window NAFs
    for(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], this._bitLength);
            naf[b] = getNAF(coeffs[b], wndWidth[b], this._bitLength);
            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]
        ];
        // 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
        ];
        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(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(i = max; i >= 0; i--){
        var k = 0;
        while(i >= 0){
            var zero = true;
            for(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(j = 0; j < len; j++){
            var z = tmp[j];
            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(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() {
    throw new Error('Not implemented');
};
BasePoint.prototype.validate = function validate() {
    return this.curve.validate(this);
};
BaseCurve.prototype.decodePoint = function decodePoint(bytes, enc) {
    bytes = utils.toArray(bytes, enc);
    var len = this.p.byteLength();
    // uncompressed, hybrid-odd, hybrid-even
    if ((bytes[0] === 4 || bytes[0] === 6 || bytes[0] === 7) && bytes.length - 1 === 2 * len) {
        if (bytes[0] === 6) assert(bytes[bytes.length - 1] % 2 === 0);
        else if (bytes[0] === 7) assert(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] === 2 || bytes[0] === 3) && bytes.length - 1 === len) return this.pointFromX(bytes.slice(1, 1 + len), bytes[0] === 3);
    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() ? 2 : 3
    ].concat(x);
    return [
        4
    ].concat(x, this.getY().toArray('be', len));
};
BasePoint.prototype.encode = function encode(enc, compact) {
    return utils.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;
};

},{"bn.js":"7NXhe","../utils":"8fQ1m"}],"80dar":[function(require,module,exports) {
'use strict';
var utils = require('../utils');
var BN = require('bn.js');
var inherits = require('inherits');
var Base = require('./base');
var assert = utils.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);
module.exports = 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(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, obj1, red) {
    if (typeof obj1 === 'string') obj1 = JSON.parse(obj1);
    var res = curve.point(obj1[0], obj1[1], red);
    if (!obj1[2]) return res;
    function obj2point(obj) {
        return curve.point(obj[0], obj[1], red);
    }
    var pre = obj1[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();
    var i;
    if (this.curve.zeroA || this.curve.threeA) {
        var r = this;
        for(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(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;
};

},{"../utils":"8fQ1m","bn.js":"7NXhe","inherits":"d3hL2","./base":"9WNVa"}],"d3hL2":[function(require,module,exports) {
if (typeof Object.create === 'function') // implementation from standard node.js 'util' module
module.exports = function inherits(ctor, superCtor) {
    if (superCtor) {
        ctor.super_ = superCtor;
        ctor.prototype = Object.create(superCtor.prototype, {
            constructor: {
                value: ctor,
                enumerable: false,
                writable: true,
                configurable: true
            }
        });
    }
};
else // old school shim for old browsers
module.exports = function inherits(ctor, superCtor) {
    if (superCtor) {
        ctor.super_ = superCtor;
        var TempCtor = function() {
        };
        TempCtor.prototype = superCtor.prototype;
        ctor.prototype = new TempCtor();
        ctor.prototype.constructor = ctor;
    }
};

},{}],"4O4sW":[function(require,module,exports) {
'use strict';
var BN = require('bn.js');
var inherits = require('inherits');
var Base = require('./base');
var utils = require('../utils');
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);
    this.a24 = this.i4.redMul(this.a.redAdd(this.two));
}
inherits(MontCurve, Base);
module.exports = 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(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, Base.BasePoint);
MontCurve.prototype.decodePoint = function decodePoint(bytes, enc) {
    return this.point(utils.toArray(bytes, enc), 1);
};
MontCurve.prototype.point = function point(x, z) {
    return new Point(this, x, z);
};
MontCurve.prototype.pointFromJSON = function pointFromJSON(obj) {
    return Point.fromJSON(this, obj);
};
Point.prototype.precompute = function precompute() {
// No-op
};
Point.prototype._encode = function _encode() {
    return this.getX().toArray('be', this.curve.p.byteLength());
};
Point.fromJSON = function fromJSON(curve, obj) {
    return new Point(curve, obj[0], obj[1] || curve.one);
};
Point.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.prototype.isInfinity = function isInfinity() {
    // XXX This code assumes that zero is always zero in red
    return this.z.cmpn(0) === 0;
};
Point.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.prototype.add = function add() {
    throw new Error('Not supported on Montgomery curve');
};
Point.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.prototype.mul = function mul(k) {
    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.prototype.mulAdd = function mulAdd() {
    throw new Error('Not supported on Montgomery curve');
};
Point.prototype.jumlAdd = function jumlAdd() {
    throw new Error('Not supported on Montgomery curve');
};
Point.prototype.eq = function eq(other) {
    return this.getX().cmp(other.getX()) === 0;
};
Point.prototype.normalize = function normalize() {
    this.x = this.x.redMul(this.z.redInvm());
    this.z = this.curve.one;
    return this;
};
Point.prototype.getX = function getX() {
    // Normalize coordinates
    this.normalize();
    return this.x.fromRed();
};

},{"bn.js":"7NXhe","inherits":"d3hL2","./base":"9WNVa","../utils":"8fQ1m"}],"btnEN":[function(require,module,exports) {
'use strict';
var utils = require('../utils');
var BN = require('bn.js');
var inherits = require('inherits');
var Base = require('./base');
var assert = utils.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(!this.twisted || this.c.fromRed().cmpn(1) === 0);
    this.oneC = (conf.c | 0) === 1;
}
inherits(EdwardsCurve, Base);
module.exports = 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(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, Base.BasePoint);
EdwardsCurve.prototype.pointFromJSON = function pointFromJSON(obj) {
    return Point.fromJSON(this, obj);
};
EdwardsCurve.prototype.point = function point(x, y, z, t) {
    return new Point(this, x, y, z, t);
};
Point.fromJSON = function fromJSON(curve, obj) {
    return new Point(curve, obj[0], obj[1], obj[2]);
};
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) + ' z: ' + this.z.fromRed().toString(16, 2) + '>';
};
Point.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.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.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;
    var e;
    var h;
    var j;
    if (this.curve.twisted) {
        // E = a * C
        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
            h = this.z.redSqr();
            // J = F - 2 * H
            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
        e = c.redAdd(d);
        // H = (c * Z1)^2
        h = this.curve._mulC(this.z).redSqr();
        // J = E - 2 * H
        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.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.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.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.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.prototype.mul = function mul(k) {
    if (this._hasDoubles(k)) return this.curve._fixedNafMul(this, k);
    else return this.curve._wnafMul(this, k);
};
Point.prototype.mulAdd = function mulAdd(k1, p, k2) {
    return this.curve._wnafMulAdd(1, [
        this,
        p
    ], [
        k1,
        k2
    ], 2, false);
};
Point.prototype.jmulAdd = function jmulAdd(k1, p, k2) {
    return this.curve._wnafMulAdd(1, [
        this,
        p
    ], [
        k1,
        k2
    ], 2, true);
};
Point.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.prototype.neg = function neg() {
    return this.curve.point(this.x.redNeg(), this.y, this.z, this.t && this.t.redNeg());
};
Point.prototype.getX = function getX() {
    this.normalize();
    return this.x.fromRed();
};
Point.prototype.getY = function getY() {
    this.normalize();
    return this.y.fromRed();
};
Point.prototype.eq = function eq(other) {
    return this === other || this.getX().cmp(other.getX()) === 0 && this.getY().cmp(other.getY()) === 0;
};
Point.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.prototype.toP = Point.prototype.normalize;
Point.prototype.mixedAdd = Point.prototype.add;

},{"../utils":"8fQ1m","bn.js":"7NXhe","inherits":"d3hL2","./base":"9WNVa"}],"jyUMP":[function(require,module,exports) {
'use strict';
var curves = exports;
var hash = require('hash.js');
var curve1 = require('./curve');
var utils = require('./utils');
var assert = utils.assert;
function PresetCurve(options) {
    if (options.type === 'short') this.curve = new curve1.short(options);
    else if (options.type === 'edwards') this.curve = new curve1.edwards(options);
    else this.curve = new curve1.mont(options);
    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, G*N != 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.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.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.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.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.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", 
    ]
});
defineCurve('curve25519', {
    type: 'mont',
    prime: 'p25519',
    p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed',
    a: '76d06',
    b: '1',
    n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed',
    hash: hash.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',
    hash: hash.sha256,
    gRed: false,
    g: [
        '216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a',
        // 4/5
        '6666666666666666666666666666666666666666666666666666666666666658', 
    ]
});
var pre;
try {
    pre = require('./precomputed/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.sha256,
    // Precomputed endomorphism
    beta: '7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee',
    lambda: '5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72',
    basis: [
        {
            a: '3086d221a7d46bcde86c90e49284eb15',
            b: '-e4437ed6010e88286f547fa90abfe4c3'
        },
        {
            a: '114ca50f7a8e2f3f657c1108d9d44cfd8',
            b: '3086d221a7d46bcde86c90e49284eb15'
        }, 
    ],
    gRed: false,
    g: [
        '79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798',
        '483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8',
        pre, 
    ]
});

},{"hash.js":"1Eokl","./curve":"kUMBS","./utils":"8fQ1m","./precomputed/secp256k1":"7Nthu"}],"1Eokl":[function(require,module,exports) {
var hash = exports;
hash.utils = require('./hash/utils');
hash.common = require('./hash/common');
hash.sha = require('./hash/sha');
hash.ripemd = require('./hash/ripemd');
hash.hmac = require('./hash/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;

},{"./hash/utils":"fQmVY","./hash/common":"ckLkm","./hash/sha":"ChvZv","./hash/ripemd":"gUo8I","./hash/hmac":"7mszC"}],"fQmVY":[function(require,module,exports) {
'use strict';
var assert = require('minimalistic-assert');
var inherits = require('inherits');
exports.inherits = inherits;
function isSurrogatePair(msg, i) {
    if ((msg.charCodeAt(i) & 64512) !== 55296) return false;
    if (i < 0 || i + 1 >= msg.length) return false;
    return (msg.charCodeAt(i + 1) & 64512) === 56320;
}
function toArray(msg, enc) {
    if (Array.isArray(msg)) return msg.slice();
    if (!msg) return [];
    var res = [];
    if (typeof msg === 'string') {
        if (!enc) {
            // Inspired by stringToUtf8ByteArray() in closure-library by Google
            // https://github.com/google/closure-library/blob/8598d87242af59aac233270742c8984e2b2bdbe0/closure/goog/crypt/crypt.js#L117-L143
            // Apache License 2.0
            // https://github.com/google/closure-library/blob/master/LICENSE
            var p = 0;
            for(var i = 0; i < msg.length; i++){
                var c = msg.charCodeAt(i);
                if (c < 128) res[p++] = c;
                else if (c < 2048) {
                    res[p++] = c >> 6 | 192;
                    res[p++] = c & 63 | 128;
                } else if (isSurrogatePair(msg, i)) {
                    c = 65536 + ((c & 1023) << 10) + (msg.charCodeAt(++i) & 1023);
                    res[p++] = c >> 18 | 240;
                    res[p++] = c >> 12 & 63 | 128;
                    res[p++] = c >> 6 & 63 | 128;
                    res[p++] = c & 63 | 128;
                } else {
                    res[p++] = c >> 12 | 224;
                    res[p++] = c >> 6 & 63 | 128;
                    res[p++] = c & 63 | 128;
                }
            }
        } else if (enc === 'hex') {
            msg = msg.replace(/[^a-z0-9]+/ig, '');
            if (msg.length % 2 !== 0) msg = '0' + msg;
            for(i = 0; i < msg.length; i += 2)res.push(parseInt(msg[i] + msg[i + 1], 16));
        }
    } else for(i = 0; i < msg.length; i++)res[i] = msg[i] | 0;
    return res;
}
exports.toArray = toArray;
function toHex(msg) {
    var res = '';
    for(var i = 0; i < msg.length; i++)res += zero2(msg[i].toString(16));
    return res;
}
exports.toHex = toHex;
function htonl(w) {
    var res = w >>> 24 | w >>> 8 & 65280 | w << 8 & 16711680 | (w & 255) << 24;
    return res >>> 0;
}
exports.htonl = htonl;
function toHex32(msg, endian) {
    var res = '';
    for(var i = 0; i < msg.length; i++){
        var w = msg[i];
        if (endian === 'little') w = htonl(w);
        res += zero8(w.toString(16));
    }
    return res;
}
exports.toHex32 = toHex32;
function zero2(word) {
    if (word.length === 1) return '0' + word;
    else return word;
}
exports.zero2 = zero2;
function zero8(word) {
    if (word.length === 7) return '0' + word;
    else if (word.length === 6) return '00' + word;
    else if (word.length === 5) return '000' + word;
    else if (word.length === 4) return '0000' + word;
    else if (word.length === 3) return '00000' + word;
    else if (word.length === 2) return '000000' + word;
    else if (word.length === 1) return '0000000' + word;
    else return word;
}
exports.zero8 = zero8;
function join32(msg, start, end, endian) {
    var len = end - start;
    assert(len % 4 === 0);
    var res = new Array(len / 4);
    for(var i = 0, k = start; i < res.length; i++, k += 4){
        var w;
        if (endian === 'big') w = msg[k] << 24 | msg[k + 1] << 16 | msg[k + 2] << 8 | msg[k + 3];
        else w = msg[k + 3] << 24 | msg[k + 2] << 16 | msg[k + 1] << 8 | msg[k];
        res[i] = w >>> 0;
    }
    return res;
}
exports.join32 = join32;
function split32(msg, endian) {
    var res = new Array(msg.length * 4);
    for(var i = 0, k = 0; i < msg.length; i++, k += 4){
        var m = msg[i];
        if (endian === 'big') {
            res[k] = m >>> 24;
            res[k + 1] = m >>> 16 & 255;
            res[k + 2] = m >>> 8 & 255;
            res[k + 3] = m & 255;
        } else {
            res[k + 3] = m >>> 24;
            res[k + 2] = m >>> 16 & 255;
            res[k + 1] = m >>> 8 & 255;
            res[k] = m & 255;
        }
    }
    return res;
}
exports.split32 = split32;
function rotr32(w, b) {
    return w >>> b | w << 32 - b;
}
exports.rotr32 = rotr32;
function rotl32(w, b) {
    return w << b | w >>> 32 - b;
}
exports.rotl32 = rotl32;
function sum32(a, b) {
    return a + b >>> 0;
}
exports.sum32 = sum32;
function sum32_3(a, b, c) {
    return a + b + c >>> 0;
}
exports.sum32_3 = sum32_3;
function sum32_4(a, b, c, d) {
    return a + b + c + d >>> 0;
}
exports.sum32_4 = sum32_4;
function sum32_5(a, b, c, d, e) {
    return a + b + c + d + e >>> 0;
}
exports.sum32_5 = sum32_5;
function sum64(buf, pos, ah, al) {
    var bh = buf[pos];
    var bl = buf[pos + 1];
    var lo = al + bl >>> 0;
    var hi = (lo < al ? 1 : 0) + ah + bh;
    buf[pos] = hi >>> 0;
    buf[pos + 1] = lo;
}
exports.sum64 = sum64;
function sum64_hi(ah, al, bh, bl) {
    var lo = al + bl >>> 0;
    var hi = (lo < al ? 1 : 0) + ah + bh;
    return hi >>> 0;
}
exports.sum64_hi = sum64_hi;
function sum64_lo(ah, al, bh, bl) {
    var lo = al + bl;
    return lo >>> 0;
}
exports.sum64_lo = sum64_lo;
function sum64_4_hi(ah, al, bh, bl, ch, cl, dh, dl) {
    var carry = 0;
    var lo = al;
    lo = lo + bl >>> 0;
    carry += lo < al ? 1 : 0;
    lo = lo + cl >>> 0;
    carry += lo < cl ? 1 : 0;
    lo = lo + dl >>> 0;
    carry += lo < dl ? 1 : 0;
    var hi = ah + bh + ch + dh + carry;
    return hi >>> 0;
}
exports.sum64_4_hi = sum64_4_hi;
function sum64_4_lo(ah, al, bh, bl, ch, cl, dh, dl) {
    var lo = al + bl + cl + dl;
    return lo >>> 0;
}
exports.sum64_4_lo = sum64_4_lo;
function sum64_5_hi(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {
    var carry = 0;
    var lo = al;
    lo = lo + bl >>> 0;
    carry += lo < al ? 1 : 0;
    lo = lo + cl >>> 0;
    carry += lo < cl ? 1 : 0;
    lo = lo + dl >>> 0;
    carry += lo < dl ? 1 : 0;
    lo = lo + el >>> 0;
    carry += lo < el ? 1 : 0;
    var hi = ah + bh + ch + dh + eh + carry;
    return hi >>> 0;
}
exports.sum64_5_hi = sum64_5_hi;
function sum64_5_lo(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {
    var lo = al + bl + cl + dl + el;
    return lo >>> 0;
}
exports.sum64_5_lo = sum64_5_lo;
function rotr64_hi(ah, al, num) {
    var r = al << 32 - num | ah >>> num;
    return r >>> 0;
}
exports.rotr64_hi = rotr64_hi;
function rotr64_lo(ah, al, num) {
    var r = ah << 32 - num | al >>> num;
    return r >>> 0;
}
exports.rotr64_lo = rotr64_lo;
function shr64_hi(ah, al, num) {
    return ah >>> num;
}
exports.shr64_hi = shr64_hi;
function shr64_lo(ah, al, num) {
    var r = ah << 32 - num | al >>> num;
    return r >>> 0;
}
exports.shr64_lo = shr64_lo;

},{"minimalistic-assert":"8j7xw","inherits":"d3hL2"}],"ckLkm":[function(require,module,exports) {
'use strict';
var utils = require('./utils');
var assert = require('minimalistic-assert');
function BlockHash() {
    this.pending = null;
    this.pendingTotal = 0;
    this.blockSize = this.constructor.blockSize;
    this.outSize = this.constructor.outSize;
    this.hmacStrength = this.constructor.hmacStrength;
    this.padLength = this.constructor.padLength / 8;
    this.endian = 'big';
    this._delta8 = this.blockSize / 8;
    this._delta32 = this.blockSize / 32;
}
exports.BlockHash = BlockHash;
BlockHash.prototype.update = function update(msg, enc) {
    // Convert message to array, pad it, and join into 32bit blocks
    msg = utils.toArray(msg, enc);
    if (!this.pending) this.pending = msg;
    else this.pending = this.pending.concat(msg);
    this.pendingTotal += msg.length;
    // Enough data, try updating
    if (this.pending.length >= this._delta8) {
        msg = this.pending;
        // Process pending data in blocks
        var r = msg.length % this._delta8;
        this.pending = msg.slice(msg.length - r, msg.length);
        if (this.pending.length === 0) this.pending = null;
        msg = utils.join32(msg, 0, msg.length - r, this.endian);
        for(var i = 0; i < msg.length; i += this._delta32)this._update(msg, i, i + this._delta32);
    }
    return this;
};
BlockHash.prototype.digest = function digest(enc) {
    this.update(this._pad());
    assert(this.pending === null);
    return this._digest(enc);
};
BlockHash.prototype._pad = function pad() {
    var len = this.pendingTotal;
    var bytes = this._delta8;
    var k = bytes - (len + this.padLength) % bytes;
    var res = new Array(k + this.padLength);
    res[0] = 128;
    for(var i = 1; i < k; i++)res[i] = 0;
    // Append length
    len <<= 3;
    if (this.endian === 'big') {
        for(var t = 8; t < this.padLength; t++)res[i++] = 0;
        res[i++] = 0;
        res[i++] = 0;
        res[i++] = 0;
        res[i++] = 0;
        res[i++] = len >>> 24 & 255;
        res[i++] = len >>> 16 & 255;
        res[i++] = len >>> 8 & 255;
        res[i++] = len & 255;
    } else {
        res[i++] = len & 255;
        res[i++] = len >>> 8 & 255;
        res[i++] = len >>> 16 & 255;
        res[i++] = len >>> 24 & 255;
        res[i++] = 0;
        res[i++] = 0;
        res[i++] = 0;
        res[i++] = 0;
        for(t = 8; t < this.padLength; t++)res[i++] = 0;
    }
    return res;
};

},{"./utils":"fQmVY","minimalistic-assert":"8j7xw"}],"ChvZv":[function(require,module,exports) {
'use strict';
exports.sha1 = require('./sha/1');
exports.sha224 = require('./sha/224');
exports.sha256 = require('./sha/256');
exports.sha384 = require('./sha/384');
exports.sha512 = require('./sha/512');

},{"./sha/1":"gpQxu","./sha/224":"dnTqN","./sha/256":"girBx","./sha/384":"50UMd","./sha/512":"kk2dX"}],"gpQxu":[function(require,module,exports) {
'use strict';
var utils = require('../utils');
var common = require('../common');
var shaCommon = require('./common');
var rotl32 = utils.rotl32;
var sum32 = utils.sum32;
var sum32_5 = utils.sum32_5;
var ft_1 = shaCommon.ft_1;
var BlockHash = common.BlockHash;
var sha1_K = [
    1518500249,
    1859775393,
    2400959708,
    3395469782
];
function SHA1() {
    if (!(this instanceof SHA1)) return new SHA1();
    BlockHash.call(this);
    this.h = [
        1732584193,
        4023233417,
        2562383102,
        271733878,
        3285377520
    ];
    this.W = new Array(80);
}
utils.inherits(SHA1, BlockHash);
module.exports = 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(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(rotl32(a, 5), ft_1(s, b, c, d), e, W[i], sha1_K[s]);
        e = d;
        d = c;
        c = rotl32(b, 30);
        b = a;
        a = t;
    }
    this.h[0] = sum32(this.h[0], a);
    this.h[1] = sum32(this.h[1], b);
    this.h[2] = sum32(this.h[2], c);
    this.h[3] = sum32(this.h[3], d);
    this.h[4] = sum32(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');
};

},{"../utils":"fQmVY","../common":"ckLkm","./common":"b6Qrq"}],"b6Qrq":[function(require,module,exports) {
'use strict';
var utils = require('../utils');
var rotr32 = utils.rotr32;
function ft_1(s, x, y, z) {
    if (s === 0) return ch32(x, y, z);
    if (s === 1 || s === 3) return p32(x, y, z);
    if (s === 2) return maj32(x, y, z);
}
exports.ft_1 = ft_1;
function ch32(x, y, z) {
    return x & y ^ ~x & z;
}
exports.ch32 = ch32;
function maj32(x, y, z) {
    return x & y ^ x & z ^ y & z;
}
exports.maj32 = maj32;
function p32(x, y, z) {
    return x ^ y ^ z;
}
exports.p32 = p32;
function s0_256(x) {
    return rotr32(x, 2) ^ rotr32(x, 13) ^ rotr32(x, 22);
}
exports.s0_256 = s0_256;
function s1_256(x) {
    return rotr32(x, 6) ^ rotr32(x, 11) ^ rotr32(x, 25);
}
exports.s1_256 = s1_256;
function g0_256(x) {
    return rotr32(x, 7) ^ rotr32(x, 18) ^ x >>> 3;
}
exports.g0_256 = g0_256;
function g1_256(x) {
    return rotr32(x, 17) ^ rotr32(x, 19) ^ x >>> 10;
}
exports.g1_256 = g1_256;

},{"../utils":"fQmVY"}],"dnTqN":[function(require,module,exports) {
'use strict';
var utils = require('../utils');
var SHA256 = require('./256');
function SHA224() {
    if (!(this instanceof SHA224)) return new SHA224();
    SHA256.call(this);
    this.h = [
        3238371032,
        914150663,
        812702999,
        4144912697,
        4290775857,
        1750603025,
        1694076839,
        3204075428
    ];
}
utils.inherits(SHA224, SHA256);
module.exports = SHA224;
SHA224.blockSize = 512;
SHA224.outSize = 224;
SHA224.hmacStrength = 192;
SHA224.padLength = 64;
SHA224.prototype._digest = function digest(enc) {
    // Just truncate output
    if (enc === 'hex') return utils.toHex32(this.h.slice(0, 7), 'big');
    else return utils.split32(this.h.slice(0, 7), 'big');
};

},{"../utils":"fQmVY","./256":"girBx"}],"girBx":[function(require,module,exports) {
'use strict';
var utils = require('../utils');
var common = require('../common');
var shaCommon = require('./common');
var assert = require('minimalistic-assert');
var sum32 = utils.sum32;
var sum32_4 = utils.sum32_4;
var sum32_5 = utils.sum32_5;
var ch32 = shaCommon.ch32;
var maj32 = shaCommon.maj32;
var s0_256 = shaCommon.s0_256;
var s1_256 = shaCommon.s1_256;
var g0_256 = shaCommon.g0_256;
var g1_256 = shaCommon.g1_256;
var BlockHash = common.BlockHash;
var sha256_K = [
    1116352408,
    1899447441,
    3049323471,
    3921009573,
    961987163,
    1508970993,
    2453635748,
    2870763221,
    3624381080,
    310598401,
    607225278,
    1426881987,
    1925078388,
    2162078206,
    2614888103,
    3248222580,
    3835390401,
    4022224774,
    264347078,
    604807628,
    770255983,
    1249150122,
    1555081692,
    1996064986,
    2554220882,
    2821834349,
    2952996808,
    3210313671,
    3336571891,
    3584528711,
    113926993,
    338241895,
    666307205,
    773529912,
    1294757372,
    1396182291,
    1695183700,
    1986661051,
    2177026350,
    2456956037,
    2730485921,
    2820302411,
    3259730800,
    3345764771,
    3516065817,
    3600352804,
    4094571909,
    275423344,
    430227734,
    506948616,
    659060556,
    883997877,
    958139571,
    1322822218,
    1537002063,
    1747873779,
    1955562222,
    2024104815,
    2227730452,
    2361852424,
    2428436474,
    2756734187,
    3204031479,
    3329325298
];
function SHA256() {
    if (!(this instanceof SHA256)) return new SHA256();
    BlockHash.call(this);
    this.h = [
        1779033703,
        3144134277,
        1013904242,
        2773480762,
        1359893119,
        2600822924,
        528734635,
        1541459225
    ];
    this.k = sha256_K;
    this.W = new Array(64);
}
utils.inherits(SHA256, BlockHash);
module.exports = SHA256;
SHA256.blockSize = 512;
SHA256.outSize = 256;
SHA256.hmacStrength = 192;
SHA256.padLength = 64;
SHA256.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] = sum32_4(g1_256(W[i - 2]), W[i - 7], g0_256(W[i - 15]), W[i - 16]);
    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];
    var f = this.h[5];
    var g = this.h[6];
    var h = this.h[7];
    assert(this.k.length === W.length);
    for(i = 0; i < W.length; i++){
        var T1 = sum32_5(h, s1_256(e), ch32(e, f, g), this.k[i], W[i]);
        var T2 = sum32(s0_256(a), maj32(a, b, c));
        h = g;
        g = f;
        f = e;
        e = sum32(d, T1);
        d = c;
        c = b;
        b = a;
        a = sum32(T1, T2);
    }
    this.h[0] = sum32(this.h[0], a);
    this.h[1] = sum32(this.h[1], b);
    this.h[2] = sum32(this.h[2], c);
    this.h[3] = sum32(this.h[3], d);
    this.h[4] = sum32(this.h[4], e);
    this.h[5] = sum32(this.h[5], f);
    this.h[6] = sum32(this.h[6], g);
    this.h[7] = sum32(this.h[7], h);
};
SHA256.prototype._digest = function digest(enc) {
    if (enc === 'hex') return utils.toHex32(this.h, 'big');
    else return utils.split32(this.h, 'big');
};

},{"../utils":"fQmVY","../common":"ckLkm","./common":"b6Qrq","minimalistic-assert":"8j7xw"}],"50UMd":[function(require,module,exports) {
'use strict';
var utils = require('../utils');
var SHA512 = require('./512');
function SHA384() {
    if (!(this instanceof SHA384)) return new SHA384();
    SHA512.call(this);
    this.h = [
        3418070365,
        3238371032,
        1654270250,
        914150663,
        2438529370,
        812702999,
        355462360,
        4144912697,
        1731405415,
        4290775857,
        2394180231,
        1750603025,
        3675008525,
        1694076839,
        1203062813,
        3204075428
    ];
}
utils.inherits(SHA384, SHA512);
module.exports = SHA384;
SHA384.blockSize = 1024;
SHA384.outSize = 384;
SHA384.hmacStrength = 192;
SHA384.padLength = 128;
SHA384.prototype._digest = function digest(enc) {
    if (enc === 'hex') return utils.toHex32(this.h.slice(0, 12), 'big');
    else return utils.split32(this.h.slice(0, 12), 'big');
};

},{"../utils":"fQmVY","./512":"kk2dX"}],"kk2dX":[function(require,module,exports) {
'use strict';
var utils = require('../utils');
var common = require('../common');
var assert = require('minimalistic-assert');
var rotr64_hi = utils.rotr64_hi;
var rotr64_lo = utils.rotr64_lo;
var shr64_hi = utils.shr64_hi;
var shr64_lo = utils.shr64_lo;
var sum64 = utils.sum64;
var sum64_hi = utils.sum64_hi;
var sum64_lo = utils.sum64_lo;
var sum64_4_hi = utils.sum64_4_hi;
var sum64_4_lo = utils.sum64_4_lo;
var sum64_5_hi = utils.sum64_5_hi;
var sum64_5_lo = utils.sum64_5_lo;
var BlockHash = common.BlockHash;
var sha512_K = [
    1116352408,
    3609767458,
    1899447441,
    602891725,
    3049323471,
    3964484399,
    3921009573,
    2173295548,
    961987163,
    4081628472,
    1508970993,
    3053834265,
    2453635748,
    2937671579,
    2870763221,
    3664609560,
    3624381080,
    2734883394,
    310598401,
    1164996542,
    607225278,
    1323610764,
    1426881987,
    3590304994,
    1925078388,
    4068182383,
    2162078206,
    991336113,
    2614888103,
    633803317,
    3248222580,
    3479774868,
    3835390401,
    2666613458,
    4022224774,
    944711139,
    264347078,
    2341262773,
    604807628,
    2007800933,
    770255983,
    1495990901,
    1249150122,
    1856431235,
    1555081692,
    3175218132,
    1996064986,
    2198950837,
    2554220882,
    3999719339,
    2821834349,
    766784016,
    2952996808,
    2566594879,
    3210313671,
    3203337956,
    3336571891,
    1034457026,
    3584528711,
    2466948901,
    113926993,
    3758326383,
    338241895,
    168717936,
    666307205,
    1188179964,
    773529912,
    1546045734,
    1294757372,
    1522805485,
    1396182291,
    2643833823,
    1695183700,
    2343527390,
    1986661051,
    1014477480,
    2177026350,
    1206759142,
    2456956037,
    344077627,
    2730485921,
    1290863460,
    2820302411,
    3158454273,
    3259730800,
    3505952657,
    3345764771,
    106217008,
    3516065817,
    3606008344,
    3600352804,
    1432725776,
    4094571909,
    1467031594,
    275423344,
    851169720,
    430227734,
    3100823752,
    506948616,
    1363258195,
    659060556,
    3750685593,
    883997877,
    3785050280,
    958139571,
    3318307427,
    1322822218,
    3812723403,
    1537002063,
    2003034995,
    1747873779,
    3602036899,
    1955562222,
    1575990012,
    2024104815,
    1125592928,
    2227730452,
    2716904306,
    2361852424,
    442776044,
    2428436474,
    593698344,
    2756734187,
    3733110249,
    3204031479,
    2999351573,
    3329325298,
    3815920427,
    3391569614,
    3928383900,
    3515267271,
    566280711,
    3940187606,
    3454069534,
    4118630271,
    4000239992,
    116418474,
    1914138554,
    174292421,
    2731055270,
    289380356,
    3203993006,
    460393269,
    320620315,
    685471733,
    587496836,
    852142971,
    1086792851,
    1017036298,
    365543100,
    1126000580,
    2618297676,
    1288033470,
    3409855158,
    1501505948,
    4234509866,
    1607167915,
    987167468,
    1816402316,
    1246189591
];
function SHA512() {
    if (!(this instanceof SHA512)) return new SHA512();
    BlockHash.call(this);
    this.h = [
        1779033703,
        4089235720,
        3144134277,
        2227873595,
        1013904242,
        4271175723,
        2773480762,
        1595750129,
        1359893119,
        2917565137,
        2600822924,
        725511199,
        528734635,
        4215389547,
        1541459225,
        327033209
    ];
    this.k = sha512_K;
    this.W = new Array(160);
}
utils.inherits(SHA512, BlockHash);
module.exports = SHA512;
SHA512.blockSize = 1024;
SHA512.outSize = 512;
SHA512.hmacStrength = 192;
SHA512.padLength = 128;
SHA512.prototype._prepareBlock = function _prepareBlock(msg, start) {
    var W = this.W;
    // 32 x 32bit words
    for(var i = 0; i < 32; i++)W[i] = msg[start + i];
    for(; i < W.length; i += 2){
        var c0_hi = g1_512_hi(W[i - 4], W[i - 3]); // i - 2
        var c0_lo = g1_512_lo(W[i - 4], W[i - 3]);
        var c1_hi = W[i - 14]; // i - 7
        var c1_lo = W[i - 13];
        var c2_hi = g0_512_hi(W[i - 30], W[i - 29]); // i - 15
        var c2_lo = g0_512_lo(W[i - 30], W[i - 29]);
        var c3_hi = W[i - 32]; // i - 16
        var c3_lo = W[i - 31];
        W[i] = sum64_4_hi(c0_hi, c0_lo, c1_hi, c1_lo, c2_hi, c2_lo, c3_hi, c3_lo);
        W[i + 1] = sum64_4_lo(c0_hi, c0_lo, c1_hi, c1_lo, c2_hi, c2_lo, c3_hi, c3_lo);
    }
};
SHA512.prototype._update = function _update(msg, start) {
    this._prepareBlock(msg, start);
    var W = this.W;
    var ah = this.h[0];
    var al = this.h[1];
    var bh = this.h[2];
    var bl = this.h[3];
    var ch = this.h[4];
    var cl = this.h[5];
    var dh = this.h[6];
    var dl = this.h[7];
    var eh = this.h[8];
    var el = this.h[9];
    var fh = this.h[10];
    var fl = this.h[11];
    var gh = this.h[12];
    var gl = this.h[13];
    var hh = this.h[14];
    var hl = this.h[15];
    assert(this.k.length === W.length);
    for(var i = 0; i < W.length; i += 2){
        var c0_hi = hh;
        var c0_lo = hl;
        var c1_hi = s1_512_hi(eh, el);
        var c1_lo = s1_512_lo(eh, el);
        var c2_hi = ch64_hi(eh, el, fh, fl, gh, gl);
        var c2_lo = ch64_lo(eh, el, fh, fl, gh, gl);
        var c3_hi = this.k[i];
        var c3_lo = this.k[i + 1];
        var c4_hi = W[i];
        var c4_lo = W[i + 1];
        var T1_hi = sum64_5_hi(c0_hi, c0_lo, c1_hi, c1_lo, c2_hi, c2_lo, c3_hi, c3_lo, c4_hi, c4_lo);
        var T1_lo = sum64_5_lo(c0_hi, c0_lo, c1_hi, c1_lo, c2_hi, c2_lo, c3_hi, c3_lo, c4_hi, c4_lo);
        c0_hi = s0_512_hi(ah, al);
        c0_lo = s0_512_lo(ah, al);
        c1_hi = maj64_hi(ah, al, bh, bl, ch, cl);
        c1_lo = maj64_lo(ah, al, bh, bl, ch, cl);
        var T2_hi = sum64_hi(c0_hi, c0_lo, c1_hi, c1_lo);
        var T2_lo = sum64_lo(c0_hi, c0_lo, c1_hi, c1_lo);
        hh = gh;
        hl = gl;
        gh = fh;
        gl = fl;
        fh = eh;
        fl = el;
        eh = sum64_hi(dh, dl, T1_hi, T1_lo);
        el = sum64_lo(dl, dl, T1_hi, T1_lo);
        dh = ch;
        dl = cl;
        ch = bh;
        cl = bl;
        bh = ah;
        bl = al;
        ah = sum64_hi(T1_hi, T1_lo, T2_hi, T2_lo);
        al = sum64_lo(T1_hi, T1_lo, T2_hi, T2_lo);
    }
    sum64(this.h, 0, ah, al);
    sum64(this.h, 2, bh, bl);
    sum64(this.h, 4, ch, cl);
    sum64(this.h, 6, dh, dl);
    sum64(this.h, 8, eh, el);
    sum64(this.h, 10, fh, fl);
    sum64(this.h, 12, gh, gl);
    sum64(this.h, 14, hh, hl);
};
SHA512.prototype._digest = function digest(enc) {
    if (enc === 'hex') return utils.toHex32(this.h, 'big');
    else return utils.split32(this.h, 'big');
};
function ch64_hi(xh, xl, yh, yl, zh) {
    var r = xh & yh ^ ~xh & zh;
    if (r < 0) r += 4294967296;
    return r;
}
function ch64_lo(xh, xl, yh, yl, zh, zl) {
    var r = xl & yl ^ ~xl & zl;
    if (r < 0) r += 4294967296;
    return r;
}
function maj64_hi(xh, xl, yh, yl, zh) {
    var r = xh & yh ^ xh & zh ^ yh & zh;
    if (r < 0) r += 4294967296;
    return r;
}
function maj64_lo(xh, xl, yh, yl, zh, zl) {
    var r = xl & yl ^ xl & zl ^ yl & zl;
    if (r < 0) r += 4294967296;
    return r;
}
function s0_512_hi(xh, xl) {
    var c0_hi = rotr64_hi(xh, xl, 28);
    var c1_hi = rotr64_hi(xl, xh, 2); // 34
    var c2_hi = rotr64_hi(xl, xh, 7); // 39
    var r = c0_hi ^ c1_hi ^ c2_hi;
    if (r < 0) r += 4294967296;
    return r;
}
function s0_512_lo(xh, xl) {
    var c0_lo = rotr64_lo(xh, xl, 28);
    var c1_lo = rotr64_lo(xl, xh, 2); // 34
    var c2_lo = rotr64_lo(xl, xh, 7); // 39
    var r = c0_lo ^ c1_lo ^ c2_lo;
    if (r < 0) r += 4294967296;
    return r;
}
function s1_512_hi(xh, xl) {
    var c0_hi = rotr64_hi(xh, xl, 14);
    var c1_hi = rotr64_hi(xh, xl, 18);
    var c2_hi = rotr64_hi(xl, xh, 9); // 41
    var r = c0_hi ^ c1_hi ^ c2_hi;
    if (r < 0) r += 4294967296;
    return r;
}
function s1_512_lo(xh, xl) {
    var c0_lo = rotr64_lo(xh, xl, 14);
    var c1_lo = rotr64_lo(xh, xl, 18);
    var c2_lo = rotr64_lo(xl, xh, 9); // 41
    var r = c0_lo ^ c1_lo ^ c2_lo;
    if (r < 0) r += 4294967296;
    return r;
}
function g0_512_hi(xh, xl) {
    var c0_hi = rotr64_hi(xh, xl, 1);
    var c1_hi = rotr64_hi(xh, xl, 8);
    var c2_hi = shr64_hi(xh, xl, 7);
    var r = c0_hi ^ c1_hi ^ c2_hi;
    if (r < 0) r += 4294967296;
    return r;
}
function g0_512_lo(xh, xl) {
    var c0_lo = rotr64_lo(xh, xl, 1);
    var c1_lo = rotr64_lo(xh, xl, 8);
    var c2_lo = shr64_lo(xh, xl, 7);
    var r = c0_lo ^ c1_lo ^ c2_lo;
    if (r < 0) r += 4294967296;
    return r;
}
function g1_512_hi(xh, xl) {
    var c0_hi = rotr64_hi(xh, xl, 19);
    var c1_hi = rotr64_hi(xl, xh, 29); // 61
    var c2_hi = shr64_hi(xh, xl, 6);
    var r = c0_hi ^ c1_hi ^ c2_hi;
    if (r < 0) r += 4294967296;
    return r;
}
function g1_512_lo(xh, xl) {
    var c0_lo = rotr64_lo(xh, xl, 19);
    var c1_lo = rotr64_lo(xl, xh, 29); // 61
    var c2_lo = shr64_lo(xh, xl, 6);
    var r = c0_lo ^ c1_lo ^ c2_lo;
    if (r < 0) r += 4294967296;
    return r;
}

},{"../utils":"fQmVY","../common":"ckLkm","minimalistic-assert":"8j7xw"}],"gUo8I":[function(require,module,exports) {
'use strict';
var utils = require('./utils');
var common = require('./common');
var rotl32 = utils.rotl32;
var sum32 = utils.sum32;
var sum32_3 = utils.sum32_3;
var sum32_4 = utils.sum32_4;
var BlockHash = common.BlockHash;
function RIPEMD160() {
    if (!(this instanceof RIPEMD160)) return new RIPEMD160();
    BlockHash.call(this);
    this.h = [
        1732584193,
        4023233417,
        2562383102,
        271733878,
        3285377520
    ];
    this.endian = 'little';
}
utils.inherits(RIPEMD160, BlockHash);
exports.ripemd160 = RIPEMD160;
RIPEMD160.blockSize = 512;
RIPEMD160.outSize = 160;
RIPEMD160.hmacStrength = 192;
RIPEMD160.padLength = 64;
RIPEMD160.prototype._update = function update(msg, start) {
    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];
    var Ah = A;
    var Bh = B;
    var Ch = C;
    var Dh = D;
    var Eh = E;
    for(var j = 0; j < 80; j++){
        var T = sum32(rotl32(sum32_4(A, f(j, B, C, D), msg[r[j] + start], K(j)), s[j]), E);
        A = E;
        E = D;
        D = rotl32(C, 10);
        C = B;
        B = T;
        T = sum32(rotl32(sum32_4(Ah, f(79 - j, Bh, Ch, Dh), msg[rh[j] + start], Kh(j)), sh[j]), Eh);
        Ah = Eh;
        Eh = Dh;
        Dh = rotl32(Ch, 10);
        Ch = Bh;
        Bh = T;
    }
    T = sum32_3(this.h[1], C, Dh);
    this.h[1] = sum32_3(this.h[2], D, Eh);
    this.h[2] = sum32_3(this.h[3], E, Ah);
    this.h[3] = sum32_3(this.h[4], A, Bh);
    this.h[4] = sum32_3(this.h[0], B, Ch);
    this.h[0] = T;
};
RIPEMD160.prototype._digest = function digest(enc) {
    if (enc === 'hex') return utils.toHex32(this.h, 'little');
    else return utils.split32(this.h, 'little');
};
function f(j, x, y, z) {
    if (j <= 15) return x ^ y ^ z;
    else if (j <= 31) return x & y | ~x & z;
    else if (j <= 47) return (x | ~y) ^ z;
    else if (j <= 63) return x & z | y & ~z;
    else return x ^ (y | ~z);
}
function K(j) {
    if (j <= 15) return 0;
    else if (j <= 31) return 1518500249;
    else if (j <= 47) return 1859775393;
    else if (j <= 63) return 2400959708;
    else return 2840853838;
}
function Kh(j) {
    if (j <= 15) return 1352829926;
    else if (j <= 31) return 1548603684;
    else if (j <= 47) return 1836072691;
    else if (j <= 63) return 2053994217;
    else return 0;
}
var r = [
    0,
    1,
    2,
    3,
    4,
    5,
    6,
    7,
    8,
    9,
    10,
    11,
    12,
    13,
    14,
    15,
    7,
    4,
    13,
    1,
    10,
    6,
    15,
    3,
    12,
    0,
    9,
    5,
    2,
    14,
    11,
    8,
    3,
    10,
    14,
    4,
    9,
    15,
    8,
    1,
    2,
    7,
    0,
    6,
    13,
    11,
    5,
    12,
    1,
    9,
    11,
    10,
    0,
    8,
    12,
    4,
    13,
    3,
    7,
    15,
    14,
    5,
    6,
    2,
    4,
    0,
    5,
    9,
    7,
    12,
    2,
    10,
    14,
    1,
    3,
    8,
    11,
    6,
    15,
    13
];
var rh = [
    5,
    14,
    7,
    0,
    9,
    2,
    11,
    4,
    13,
    6,
    15,
    8,
    1,
    10,
    3,
    12,
    6,
    11,
    3,
    7,
    0,
    13,
    5,
    10,
    14,
    15,
    8,
    12,
    4,
    9,
    1,
    2,
    15,
    5,
    1,
    3,
    7,
    14,
    6,
    9,
    11,
    8,
    12,
    2,
    10,
    0,
    4,
    13,
    8,
    6,
    4,
    1,
    3,
    11,
    15,
    0,
    5,
    12,
    2,
    13,
    9,
    7,
    10,
    14,
    12,
    15,
    10,
    4,
    1,
    5,
    8,
    7,
    6,
    2,
    13,
    14,
    0,
    3,
    9,
    11
];
var s = [
    11,
    14,
    15,
    12,
    5,
    8,
    7,
    9,
    11,
    13,
    14,
    15,
    6,
    7,
    9,
    8,
    7,
    6,
    8,
    13,
    11,
    9,
    7,
    15,
    7,
    12,
    15,
    9,
    11,
    7,
    13,
    12,
    11,
    13,
    6,
    7,
    14,
    9,
    13,
    15,
    14,
    8,
    13,
    6,
    5,
    12,
    7,
    5,
    11,
    12,
    14,
    15,
    14,
    15,
    9,
    8,
    9,
    14,
    5,
    6,
    8,
    6,
    5,
    12,
    9,
    15,
    5,
    11,
    6,
    8,
    13,
    12,
    5,
    12,
    13,
    14,
    11,
    8,
    5,
    6
];
var sh = [
    8,
    9,
    9,
    11,
    13,
    15,
    15,
    5,
    7,
    7,
    8,
    11,
    14,
    14,
    12,
    6,
    9,
    13,
    15,
    7,
    12,
    8,
    9,
    11,
    7,
    7,
    12,
    7,
    6,
    15,
    13,
    11,
    9,
    7,
    15,
    11,
    8,
    6,
    6,
    14,
    12,
    13,
    5,
    14,
    13,
    13,
    7,
    5,
    15,
    5,
    8,
    11,
    14,
    14,
    6,
    14,
    6,
    9,
    12,
    9,
    12,
    5,
    15,
    8,
    8,
    5,
    12,
    9,
    12,
    5,
    14,
    6,
    8,
    13,
    6,
    5,
    15,
    13,
    11,
    11
];

},{"./utils":"fQmVY","./common":"ckLkm"}],"7mszC":[function(require,module,exports) {
'use strict';
var utils = require('./utils');
var assert = require('minimalistic-assert');
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));
}
module.exports = Hmac;
Hmac.prototype._init = function init(key) {
    // Shorten key, if needed
    if (key.length > this.blockSize) key = new this.Hash().update(key).digest();
    assert(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] ^= 54;
    this.inner = new this.Hash().update(key);
    // 0x36 ^ 0x5c = 0x6a
    for(i = 0; i < key.length; i++)key[i] ^= 106;
    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);
};

},{"./utils":"fQmVY","minimalistic-assert":"8j7xw"}],"7Nthu":[function(require,module,exports) {
module.exports = {
    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', 
            ], 
        ]
    }
};

},{}],"18hLW":[function(require,module,exports) {
'use strict';
var BN = require('bn.js');
var HmacDRBG = require('hmac-drbg');
var utils = require('../utils');
var curves = require('../curves');
var rand = require('brorand');
var assert = utils.assert;
var KeyPair = require('./key');
var Signature = require('./signature');
function EC(options) {
    if (!(this instanceof EC)) return new EC(options);
    // Shortcut `elliptic.ec(curve-name)`
    if (typeof options === 'string') {
        assert(Object.prototype.hasOwnProperty.call(curves, options), 'Unknown curve ' + options);
        options = curves[options];
    }
    // Shortcut for `elliptic.ec(elliptic.curves.curveName)`
    if (options instanceof curves.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 for function for DRBG
    this.hash = options.hash || options.curve.hash;
}
module.exports = EC;
EC.prototype.keyPair = function keyPair(options) {
    return new KeyPair(this, options);
};
EC.prototype.keyFromPrivate = function keyFromPrivate(priv, enc) {
    return KeyPair.fromPrivate(this, priv, enc);
};
EC.prototype.keyFromPublic = function keyFromPublic(pub, enc) {
    return KeyPair.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 || rand(this.hash.hmacStrength),
        entropyEnc: options.entropy && options.entropyEnc || 'utf8',
        nonce: this.n.toArray()
    });
    var bytes = this.n.byteLength();
    var ns2 = this.n.sub(new BN(2));
    for(;;){
        var priv = new BN(drbg.generate(bytes));
        if (priv.cmp(ns2) > 0) continue;
        priv.iaddn(1);
        return this.keyFromPrivate(priv);
    }
};
EC.prototype._truncateToN = function _truncateToN(msg, truncOnly) {
    var delta = msg.byteLength() * 8 - 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.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._truncateToN(new BN(msg, 16));
    // 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;; 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({
            r: r,
            s: s,
            recoveryParam: recoveryParam
        });
    }
};
EC.prototype.verify = function verify(msg, signature, key, enc) {
    msg = this._truncateToN(new BN(msg, 16));
    key = this.keyFromPublic(key, enc);
    signature = new Signature(signature, 'hex');
    // 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);
    var p;
    if (!this.curve._maxwellTrick) {
        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
    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((3 & j) === j, 'The recovery param is more than two bits');
    signature = new Signature(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(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');
};

},{"bn.js":"7NXhe","hmac-drbg":"99tHD","../utils":"8fQ1m","../curves":"jyUMP","brorand":"ekppu","./key":"5zqBU","./signature":"8NEFO"}],"99tHD":[function(require,module,exports) {
'use strict';
var hash = require('hash.js');
var utils = require('minimalistic-crypto-utils');
var assert = require('minimalistic-assert');
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.toArray(options.entropy, options.entropyEnc || 'hex');
    var nonce = utils.toArray(options.nonce, options.nonceEnc || 'hex');
    var pers = utils.toArray(options.pers, options.persEnc || 'hex');
    assert(entropy.length >= this.minEntropy / 8, 'Not enough entropy. Minimum is: ' + this.minEntropy + ' bits');
    this._init(entropy, nonce, pers);
}
module.exports = 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] = 0;
        this.V[i] = 1;
    }
    this._update(seed);
    this._reseed = 1;
    this.reseedInterval = 281474976710656; // 2^48
};
HmacDRBG.prototype._hmac = function hmac() {
    return new hash.hmac(this.hash, this.K);
};
HmacDRBG.prototype._update = function update(seed) {
    var kmac = this._hmac().update(this.V).update([
        0
    ]);
    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([
        1
    ]).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.toArray(entropy, entropyEnc);
    add = utils.toArray(add, addEnc);
    assert(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.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.encode(res, enc);
};

},{"hash.js":"1Eokl","minimalistic-crypto-utils":"b17ct","minimalistic-assert":"8j7xw"}],"5zqBU":[function(require,module,exports) {
'use strict';
var BN = require('bn.js');
var utils = require('../utils');
var assert = utils.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);
}
module.exports = 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
    });
};
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(compact, enc) {
    // compact is optional argument
    if (typeof compact === 'string') {
        enc = compact;
        compact = null;
    }
    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);
    // 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(key.x, 'Need x coordinate');
        else if (this.ec.curve.type === 'short' || this.ec.curve.type === 'edwards') assert(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) {
    if (!pub.validate()) assert(pub.validate(), 'public point not validated');
    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()) + ' >';
};

},{"bn.js":"7NXhe","../utils":"8fQ1m"}],"8NEFO":[function(require,module,exports) {
'use strict';
var BN = require('bn.js');
var utils = require('../utils');
var assert = utils.assert;
function Signature(options, enc) {
    if (options instanceof Signature) return options;
    if (this._importDER(options, enc)) return;
    assert(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;
}
module.exports = Signature;
function Position() {
    this.place = 0;
}
function getLength(buf, p) {
    var initial = buf[p.place++];
    if (!(initial & 128)) return initial;
    var octetLen = initial & 15;
    // Indefinite length or overflow
    if (octetLen === 0 || octetLen > 4) return false;
    var val = 0;
    for(var i = 0, off = p.place; i < octetLen; i++, off++){
        val <<= 8;
        val |= buf[off];
        val >>>= 0;
    }
    // Leading zeroes
    if (val <= 127) return false;
    p.place = off;
    return val;
}
function rmPadding(buf) {
    var i = 0;
    var len = buf.length - 1;
    while(!buf[i] && !(buf[i + 1] & 128) && i < len)i++;
    if (i === 0) return buf;
    return buf.slice(i);
}
Signature.prototype._importDER = function _importDER(data, enc) {
    data = utils.toArray(data, enc);
    var p = new Position();
    if (data[p.place++] !== 48) return false;
    var len = getLength(data, p);
    if (len === false) return false;
    if (len + p.place !== data.length) return false;
    if (data[p.place++] !== 2) return false;
    var rlen = getLength(data, p);
    if (rlen === false) return false;
    var r = data.slice(p.place, rlen + p.place);
    p.place += rlen;
    if (data[p.place++] !== 2) return false;
    var slen = getLength(data, p);
    if (slen === false) return false;
    if (data.length !== slen + p.place) return false;
    var s = data.slice(p.place, slen + p.place);
    if (r[0] === 0) {
        if (r[1] & 128) r = r.slice(1);
        else // Leading zeroes
        return false;
    }
    if (s[0] === 0) {
        if (s[1] & 128) s = s.slice(1);
        else // Leading zeroes
        return false;
    }
    this.r = new BN(r);
    this.s = new BN(s);
    this.recoveryParam = null;
    return true;
};
function constructLength(arr, len) {
    if (len < 128) {
        arr.push(len);
        return;
    }
    var octets = 1 + (Math.log(len) / Math.LN2 >>> 3);
    arr.push(octets | 128);
    while(--octets)arr.push(len >>> (octets << 3) & 255);
    arr.push(len);
}
Signature.prototype.toDER = function toDER(enc) {
    var r = this.r.toArray();
    var s = this.s.toArray();
    // Pad values
    if (r[0] & 128) r = [
        0
    ].concat(r);
    // Pad values
    if (s[0] & 128) s = [
        0
    ].concat(s);
    r = rmPadding(r);
    s = rmPadding(s);
    while(!s[0] && !(s[1] & 128))s = s.slice(1);
    var arr = [
        2
    ];
    constructLength(arr, r.length);
    arr = arr.concat(r);
    arr.push(2);
    constructLength(arr, s.length);
    var backHalf = arr.concat(s);
    var res = [
        48
    ];
    constructLength(res, backHalf.length);
    res = res.concat(backHalf);
    return utils.encode(res, enc);
};

},{"bn.js":"7NXhe","../utils":"8fQ1m"}],"fk7wS":[function(require,module,exports) {
'use strict';
var hash1 = require('hash.js');
var curves = require('../curves');
var utils = require('../utils');
var assert = utils.assert;
var parseBytes = utils.parseBytes;
var KeyPair = require('./key');
var Signature = require('./signature');
function EDDSA(curve) {
    assert(curve === 'ed25519', 'only tested with ed25519 so far');
    if (!(this instanceof EDDSA)) return new EDDSA(curve);
    curve = curves[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 = hash1.sha512;
}
module.exports = 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(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(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.intFromLE(hash.digest()).umod(this.curve.n);
};
EDDSA.prototype.keyFromPublic = function keyFromPublic(pub) {
    return KeyPair.fromPublic(this, pub);
};
EDDSA.prototype.keyFromSecret = function keyFromSecret(secret) {
    return KeyPair.fromSecret(this, secret);
};
EDDSA.prototype.makeSignature = function makeSignature(sig) {
    if (sig instanceof Signature) return sig;
    return new Signature(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() ? 128 : 0;
    return enc;
};
EDDSA.prototype.decodePoint = function decodePoint(bytes) {
    bytes = utils.parseBytes(bytes);
    var lastIx = bytes.length - 1;
    var normed = bytes.slice(0, lastIx).concat(bytes[lastIx] & -129);
    var xIsOdd = (bytes[lastIx] & 128) !== 0;
    var y = utils.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.intFromLE(bytes);
};
EDDSA.prototype.isPoint = function isPoint(val) {
    return val instanceof this.pointClass;
};

},{"hash.js":"1Eokl","../curves":"jyUMP","../utils":"8fQ1m","./key":"eBpSK","./signature":"1CSXJ"}],"eBpSK":[function(require,module,exports) {
'use strict';
var utils = require('../utils');
var assert = utils.assert;
var parseBytes = utils.parseBytes;
var cachedProperty = utils.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(eddsa, params) {
    this.eddsa = eddsa;
    this._secret = parseBytes(params.secret);
    if (eddsa.isPoint(params.pub)) this._pub = params.pub;
    else this._pubBytes = parseBytes(params.pub);
}
KeyPair.fromPublic = function fromPublic(eddsa, pub) {
    if (pub instanceof KeyPair) return pub;
    return new KeyPair(eddsa, {
        pub: pub
    });
};
KeyPair.fromSecret = function fromSecret(eddsa, secret) {
    if (secret instanceof KeyPair) return secret;
    return new KeyPair(eddsa, {
        secret: secret
    });
};
KeyPair.prototype.secret = function secret() {
    return this._secret;
};
cachedProperty(KeyPair, 'pubBytes', function pubBytes() {
    return this.eddsa.encodePoint(this.pub());
});
cachedProperty(KeyPair, 'pub', function pub() {
    if (this._pubBytes) return this.eddsa.decodePoint(this._pubBytes);
    return this.eddsa.g.mul(this.priv());
});
cachedProperty(KeyPair, 'privBytes', function privBytes() {
    var eddsa = this.eddsa;
    var hash = this.hash();
    var lastIx = eddsa.encodingLength - 1;
    var a = hash.slice(0, eddsa.encodingLength);
    a[0] &= 248;
    a[lastIx] &= 127;
    a[lastIx] |= 64;
    return a;
});
cachedProperty(KeyPair, 'priv', function priv() {
    return this.eddsa.decodeInt(this.privBytes());
});
cachedProperty(KeyPair, 'hash', function hash() {
    return this.eddsa.hash().update(this.secret()).digest();
});
cachedProperty(KeyPair, 'messagePrefix', function messagePrefix() {
    return this.hash().slice(this.eddsa.encodingLength);
});
KeyPair.prototype.sign = function sign(message) {
    assert(this._secret, 'KeyPair can only verify');
    return this.eddsa.sign(message, this);
};
KeyPair.prototype.verify = function verify(message, sig) {
    return this.eddsa.verify(message, sig, this);
};
KeyPair.prototype.getSecret = function getSecret(enc) {
    assert(this._secret, 'KeyPair is public only');
    return utils.encode(this.secret(), enc);
};
KeyPair.prototype.getPublic = function getPublic(enc) {
    return utils.encode(this.pubBytes(), enc);
};
module.exports = KeyPair;

},{"../utils":"8fQ1m"}],"1CSXJ":[function(require,module,exports) {
'use strict';
var BN = require('bn.js');
var utils = require('../utils');
var assert = utils.assert;
var cachedProperty = utils.cachedProperty;
var parseBytes = utils.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(eddsa, sig) {
    this.eddsa = eddsa;
    if (typeof sig !== 'object') sig = parseBytes(sig);
    if (Array.isArray(sig)) sig = {
        R: sig.slice(0, eddsa.encodingLength),
        S: sig.slice(eddsa.encodingLength)
    };
    assert(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(Signature, 'S', function S() {
    return this.eddsa.decodeInt(this.Sencoded());
});
cachedProperty(Signature, 'R', function R() {
    return this.eddsa.decodePoint(this.Rencoded());
});
cachedProperty(Signature, 'Rencoded', function Rencoded() {
    return this.eddsa.encodePoint(this.R());
});
cachedProperty(Signature, 'Sencoded', function Sencoded() {
    return this.eddsa.encodeInt(this.S());
});
Signature.prototype.toBytes = function toBytes() {
    return this.Rencoded().concat(this.Sencoded());
};
Signature.prototype.toHex = function toHex() {
    return utils.encode(this.toBytes(), 'hex').toUpperCase();
};
module.exports = Signature;

},{"bn.js":"7NXhe","../utils":"8fQ1m"}],"3mB6S":[function(require,module,exports) {
'use strict';
const errcode = require('err-code');
const { concat: uint8ArrayConcat  } = require('uint8arrays/concat');
const { fromString: uint8ArrayFromString  } = require('uint8arrays/from-string');
const hmac = require('../hmac');
const cipherMap = {
    'AES-128': {
        ivSize: 16,
        keySize: 16
    },
    'AES-256': {
        ivSize: 16,
        keySize: 32
    },
    Blowfish: {
        ivSize: 8,
        cipherKeySize: 32
    }
};
// Generates a set of keys for each party by stretching the shared key.
// (myIV, theirIV, myCipherKey, theirCipherKey, myMACKey, theirMACKey)
module.exports = async (cipherType, hash, secret)=>{
    const cipher = cipherMap[cipherType];
    if (!cipher) {
        const allowed = Object.keys(cipherMap).join(' / ');
        throw errcode(new Error(`unknown cipher type '${cipherType}'. Must be ${allowed}`), 'ERR_INVALID_CIPHER_TYPE');
    }
    if (!hash) throw errcode(new Error('missing hash type'), 'ERR_MISSING_HASH_TYPE');
    const cipherKeySize = cipher.keySize;
    const ivSize = cipher.ivSize;
    const hmacKeySize = 20;
    const seed = uint8ArrayFromString('key expansion');
    const resultLength = 2 * (ivSize + cipherKeySize + hmacKeySize);
    const m = await hmac.create(hash, secret);
    let a = await m.digest(seed);
    const result = [];
    let j = 0;
    while(j < resultLength){
        const b = await m.digest(uint8ArrayConcat([
            a,
            seed
        ]));
        let todo = b.length;
        if (j + todo > resultLength) todo = resultLength - j;
        result.push(b);
        j += todo;
        a = await m.digest(a);
    }
    const half = resultLength / 2;
    const resultBuffer = uint8ArrayConcat(result);
    const r1 = resultBuffer.slice(0, half);
    const r2 = resultBuffer.slice(half, resultLength);
    const createKey = (res)=>({
            iv: res.slice(0, ivSize),
            cipherKey: res.slice(ivSize, ivSize + cipherKeySize),
            macKey: res.slice(ivSize + cipherKeySize)
        })
    ;
    return {
        k1: createKey(r1),
        k2: createKey(r2)
    };
};

},{"err-code":"eQvyh","uint8arrays/concat":"fLIrL","uint8arrays/from-string":"lo45E","../hmac":"eZkFq"}],"eZkFq":[function(require,module,exports) {
'use strict';
const webcrypto = require('../webcrypto');
const lengths = require('./lengths');
const hashTypes = {
    SHA1: 'SHA-1',
    SHA256: 'SHA-256',
    SHA512: 'SHA-512'
};
const sign = async (key, data)=>{
    const buf = await webcrypto.get().subtle.sign({
        name: 'HMAC'
    }, key, data);
    return new Uint8Array(buf, buf.byteOffset, buf.byteLength);
};
exports.create = async function(hashType, secret) {
    const hash = hashTypes[hashType];
    const key = await webcrypto.get().subtle.importKey('raw', secret, {
        name: 'HMAC',
        hash: {
            name: hash
        }
    }, false, [
        'sign'
    ]);
    return {
        async digest (data) {
            return sign(key, data);
        },
        length: lengths[hashType]
    };
};

},{"../webcrypto":"hKlQS","./lengths":"78JvJ"}],"78JvJ":[function(require,module,exports) {
'use strict';
module.exports = {
    SHA1: 20,
    SHA256: 32,
    SHA512: 64
};

},{}],"g85te":[function(require,module,exports) {
'use strict';
const ecdh = require('./ecdh');
// Generates an ephemeral public key and returns a function that will compute
// the shared secret key.
//
// Focuses only on ECDH now, but can be made more general in the future.
module.exports = async (curve)=>ecdh.generateEphmeralKeyPair(curve) // eslint-disable-line require-await
;

},{"./ecdh":"jxzTb"}],"jxzTb":[function(require,module,exports) {
'use strict';
const errcode = require('err-code');
const webcrypto = require('../webcrypto');
const { base64urlToBuffer  } = require('../util');
const validateCurveType = require('./validate-curve-type');
const { toString: uint8ArrayToString  } = require('uint8arrays/to-string');
const { concat: uint8ArrayConcat  } = require('uint8arrays/concat');
const { equals: uint8ArrayEquals  } = require('uint8arrays/equals');
const bits = {
    'P-256': 256,
    'P-384': 384,
    'P-521': 521
};
exports.generateEphmeralKeyPair = async function(curve) {
    validateCurveType(Object.keys(bits), curve);
    const pair = await webcrypto.get().subtle.generateKey({
        name: 'ECDH',
        namedCurve: curve
    }, true, [
        'deriveBits'
    ]);
    // forcePrivate is used for testing only
    const genSharedKey = async (theirPub, forcePrivate)=>{
        let privateKey;
        if (forcePrivate) privateKey = await webcrypto.get().subtle.importKey('jwk', unmarshalPrivateKey(curve, forcePrivate), {
            name: 'ECDH',
            namedCurve: curve
        }, false, [
            'deriveBits'
        ]);
        else privateKey = pair.privateKey;
        const keys = [
            await webcrypto.get().subtle.importKey('jwk', unmarshalPublicKey(curve, theirPub), {
                name: 'ECDH',
                namedCurve: curve
            }, false, []),
            privateKey
        ];
        const buffer = await webcrypto.get().subtle.deriveBits({
            name: 'ECDH',
            namedCurve: curve,
            public: keys[0]
        }, keys[1], bits[curve]);
        return new Uint8Array(buffer, buffer.byteOffset, buffer.byteLength);
    };
    const publicKey = await webcrypto.get().subtle.exportKey('jwk', pair.publicKey);
    return {
        key: marshalPublicKey(publicKey),
        genSharedKey
    };
};
const curveLengths = {
    'P-256': 32,
    'P-384': 48,
    'P-521': 66
};
// Marshal converts a jwk encodec ECDH public key into the
// form specified in section 4.3.6 of ANSI X9.62. (This is the format
// go-ipfs uses)
function marshalPublicKey(jwk) {
    const byteLen = curveLengths[jwk.crv];
    return uint8ArrayConcat([
        Uint8Array.from([
            4
        ]),
        base64urlToBuffer(jwk.x, byteLen),
        base64urlToBuffer(jwk.y, byteLen)
    ], 1 + byteLen * 2);
}
// Unmarshal converts a point, serialized by Marshal, into an jwk encoded key
function unmarshalPublicKey(curve, key) {
    const byteLen = curveLengths[curve];
    if (uint8ArrayEquals(!key.slice(0, 1), Uint8Array.from([
        4
    ]))) throw errcode(new Error('Cannot unmarshal public key - invalid key format'), 'ERR_INVALID_KEY_FORMAT');
    return {
        kty: 'EC',
        crv: curve,
        x: uint8ArrayToString(key.slice(1, byteLen + 1), 'base64url'),
        y: uint8ArrayToString(key.slice(1 + byteLen), 'base64url'),
        ext: true
    };
}
const unmarshalPrivateKey = (curve, key)=>({
        ...unmarshalPublicKey(curve, key.public),
        d: uint8ArrayToString(key.private, 'base64url')
    })
;

},{"err-code":"eQvyh","../webcrypto":"hKlQS","../util":"GsPr7","./validate-curve-type":"eXIrZ","uint8arrays/to-string":"g3mCQ","uint8arrays/concat":"fLIrL","uint8arrays/equals":"fjLeN"}],"eXIrZ":[function(require,module,exports) {
'use strict';
const errcode = require('err-code');
module.exports = function(curveTypes, type) {
    if (!curveTypes.includes(type)) {
        const names = curveTypes.join(' / ');
        throw errcode(new Error(`Unknown curve: ${type}. Must be ${names}`), 'ERR_INVALID_CURVE');
    }
};

},{"err-code":"eQvyh"}],"eROOZ":[function(require,module,exports) {
'use strict';
function withIs(Class, { className , symbolName  }) {
    const symbol = Symbol.for(symbolName);
    const ClassIsWrapper = {
        // The code below assigns the class wrapper to an object to trick
        // JavaScript engines to show the name of the extended class when
        // logging an instances.
        // We are assigning an anonymous class (class wrapper) to the object
        // with key `className` to keep the correct name.
        // If this is not supported it falls back to logging `ClassIsWrapper`.
        [className]: class extends Class {
            constructor(...args){
                super(...args);
                Object.defineProperty(this, symbol, {
                    value: true
                });
            }
            get [Symbol.toStringTag]() {
                return className;
            }
        }
    }[className];
    ClassIsWrapper[`is${className}`] = (obj)=>!!(obj && obj[symbol])
    ;
    return ClassIsWrapper;
}
function withIsProto(Class, { className , symbolName , withoutNew  }) {
    const symbol = Symbol.for(symbolName);
    /* eslint-disable object-shorthand */ const ClassIsWrapper = {
        [className]: function(...args) {
            if (withoutNew && !(this instanceof ClassIsWrapper)) return new ClassIsWrapper(...args);
            const _this = Class.call(this, ...args) || this;
            if (_this && !_this[symbol]) Object.defineProperty(_this, symbol, {
                value: true
            });
            return _this;
        }
    }[className];
    /* eslint-enable object-shorthand */ ClassIsWrapper.prototype = Object.create(Class.prototype);
    ClassIsWrapper.prototype.constructor = ClassIsWrapper;
    Object.defineProperty(ClassIsWrapper.prototype, Symbol.toStringTag, {
        get () {
            return className;
        }
    });
    ClassIsWrapper[`is${className}`] = (obj)=>!!(obj && obj[symbol])
    ;
    return ClassIsWrapper;
}
module.exports = withIs;
module.exports.proto = withIsProto;

},{}],"b9Uyl":[function(require,module,exports) {
/*eslint-disable*/ "use strict";
var $protobuf = require("protobufjs/minimal");
// Common aliases
var $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util;
// Exported root namespace
var $root = $protobuf.roots["libp2p-peer-id"] || ($protobuf.roots["libp2p-peer-id"] = {
});
$root.PeerIdProto = (function() {
    /**
     * Properties of a PeerIdProto.
     * @exports IPeerIdProto
     * @interface IPeerIdProto
     * @property {Uint8Array} id PeerIdProto id
     * @property {Uint8Array|null} [pubKey] PeerIdProto pubKey
     * @property {Uint8Array|null} [privKey] PeerIdProto privKey
     */ /**
     * Constructs a new PeerIdProto.
     * @exports PeerIdProto
     * @classdesc Represents a PeerIdProto.
     * @implements IPeerIdProto
     * @constructor
     * @param {IPeerIdProto=} [p] Properties to set
     */ function PeerIdProto(p) {
        if (p) {
            for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
        }
    }
    /**
     * PeerIdProto id.
     * @member {Uint8Array} id
     * @memberof PeerIdProto
     * @instance
     */ PeerIdProto.prototype.id = $util.newBuffer([]);
    /**
     * PeerIdProto pubKey.
     * @member {Uint8Array} pubKey
     * @memberof PeerIdProto
     * @instance
     */ PeerIdProto.prototype.pubKey = $util.newBuffer([]);
    /**
     * PeerIdProto privKey.
     * @member {Uint8Array} privKey
     * @memberof PeerIdProto
     * @instance
     */ PeerIdProto.prototype.privKey = $util.newBuffer([]);
    /**
     * Encodes the specified PeerIdProto message. Does not implicitly {@link PeerIdProto.verify|verify} messages.
     * @function encode
     * @memberof PeerIdProto
     * @static
     * @param {IPeerIdProto} m PeerIdProto message or plain object to encode
     * @param {$protobuf.Writer} [w] Writer to encode to
     * @returns {$protobuf.Writer} Writer
     */ PeerIdProto.encode = function encode(m, w) {
        if (!w) w = $Writer.create();
        w.uint32(10).bytes(m.id);
        if (m.pubKey != null && Object.hasOwnProperty.call(m, "pubKey")) w.uint32(18).bytes(m.pubKey);
        if (m.privKey != null && Object.hasOwnProperty.call(m, "privKey")) w.uint32(26).bytes(m.privKey);
        return w;
    };
    /**
     * Decodes a PeerIdProto message from the specified reader or buffer.
     * @function decode
     * @memberof PeerIdProto
     * @static
     * @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
     * @param {number} [l] Message length if known beforehand
     * @returns {PeerIdProto} PeerIdProto
     * @throws {Error} If the payload is not a reader or valid buffer
     * @throws {$protobuf.util.ProtocolError} If required fields are missing
     */ PeerIdProto.decode = function decode(r, l) {
        if (!(r instanceof $Reader)) r = $Reader.create(r);
        var c = l === undefined ? r.len : r.pos + l, m = new $root.PeerIdProto();
        while(r.pos < c){
            var t = r.uint32();
            switch(t >>> 3){
                case 1:
                    m.id = r.bytes();
                    break;
                case 2:
                    m.pubKey = r.bytes();
                    break;
                case 3:
                    m.privKey = r.bytes();
                    break;
                default:
                    r.skipType(t & 7);
                    break;
            }
        }
        if (!m.hasOwnProperty("id")) throw $util.ProtocolError("missing required 'id'", {
            instance: m
        });
        return m;
    };
    /**
     * Creates a PeerIdProto message from a plain object. Also converts values to their respective internal types.
     * @function fromObject
     * @memberof PeerIdProto
     * @static
     * @param {Object.<string,*>} d Plain object
     * @returns {PeerIdProto} PeerIdProto
     */ PeerIdProto.fromObject = function fromObject(d) {
        if (d instanceof $root.PeerIdProto) return d;
        var m = new $root.PeerIdProto();
        if (d.id != null) {
            if (typeof d.id === "string") $util.base64.decode(d.id, m.id = $util.newBuffer($util.base64.length(d.id)), 0);
            else if (d.id.length) m.id = d.id;
        }
        if (d.pubKey != null) {
            if (typeof d.pubKey === "string") $util.base64.decode(d.pubKey, m.pubKey = $util.newBuffer($util.base64.length(d.pubKey)), 0);
            else if (d.pubKey.length) m.pubKey = d.pubKey;
        }
        if (d.privKey != null) {
            if (typeof d.privKey === "string") $util.base64.decode(d.privKey, m.privKey = $util.newBuffer($util.base64.length(d.privKey)), 0);
            else if (d.privKey.length) m.privKey = d.privKey;
        }
        return m;
    };
    /**
     * Creates a plain object from a PeerIdProto message. Also converts values to other types if specified.
     * @function toObject
     * @memberof PeerIdProto
     * @static
     * @param {PeerIdProto} m PeerIdProto
     * @param {$protobuf.IConversionOptions} [o] Conversion options
     * @returns {Object.<string,*>} Plain object
     */ PeerIdProto.toObject = function toObject(m, o) {
        if (!o) o = {
        };
        var d = {
        };
        if (o.defaults) {
            if (o.bytes === String) d.id = "";
            else {
                d.id = [];
                if (o.bytes !== Array) d.id = $util.newBuffer(d.id);
            }
            if (o.bytes === String) d.pubKey = "";
            else {
                d.pubKey = [];
                if (o.bytes !== Array) d.pubKey = $util.newBuffer(d.pubKey);
            }
            if (o.bytes === String) d.privKey = "";
            else {
                d.privKey = [];
                if (o.bytes !== Array) d.privKey = $util.newBuffer(d.privKey);
            }
        }
        if (m.id != null && m.hasOwnProperty("id")) d.id = o.bytes === String ? $util.base64.encode(m.id, 0, m.id.length) : o.bytes === Array ? Array.prototype.slice.call(m.id) : m.id;
        if (m.pubKey != null && m.hasOwnProperty("pubKey")) d.pubKey = o.bytes === String ? $util.base64.encode(m.pubKey, 0, m.pubKey.length) : o.bytes === Array ? Array.prototype.slice.call(m.pubKey) : m.pubKey;
        if (m.privKey != null && m.hasOwnProperty("privKey")) d.privKey = o.bytes === String ? $util.base64.encode(m.privKey, 0, m.privKey.length) : o.bytes === Array ? Array.prototype.slice.call(m.privKey) : m.privKey;
        return d;
    };
    /**
     * Converts this PeerIdProto to JSON.
     * @function toJSON
     * @memberof PeerIdProto
     * @instance
     * @returns {Object.<string,*>} JSON object
     */ PeerIdProto.prototype.toJSON = function toJSON() {
        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
    };
    return PeerIdProto;
})();
module.exports = $root;

},{"protobufjs/minimal":"9Jmso"}],"eF5jW":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var add = require('./add.js');
var addAll = require('./add-all.js');
var ls = require('./ls.js');
var rm = require('./rm.js');
var rmAll = require('./rm-all.js');
class PinAPI {
    constructor({ codecs , repo  }){
        const addAll$1 = addAll.createAddAll({
            codecs,
            repo
        });
        this.addAll = addAll$1;
        this.add = add.createAdd({
            addAll: addAll$1
        });
        const rmAll$1 = rmAll.createRmAll({
            codecs,
            repo
        });
        this.rmAll = rmAll$1;
        this.rm = rm.createRm({
            rmAll: rmAll$1
        });
        this.ls = ls.createLs({
            codecs,
            repo
        });
        this.remote = {
            add: (cid, options = {
            })=>Promise.reject(new Error('Not implemented'))
            ,
            ls: async function*(query, options = {
            }) {
                return Promise.reject(new Error('Not implemented'));
            },
            rm: (query, options = {
            })=>Promise.reject(new Error('Not implemented'))
            ,
            rmAll: (query, options = {
            })=>Promise.reject(new Error('Not implemented'))
            ,
            service: {
                add: (name, credentials)=>Promise.reject(new Error('Not implemented'))
                ,
                rm: (name, options = {
                })=>Promise.reject(new Error('Not implemented'))
                ,
                ls: (options = {
                })=>Promise.reject(new Error('Not implemented'))
            }
        };
    }
}
exports.PinAPI = PinAPI;

},{"./add.js":"d7iYV","./add-all.js":"beb5u","./ls.js":"3Hwed","./rm.js":"hay9o","./rm-all.js":"akt1o"}],"d7iYV":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var last = require('it-last');
var cid = require('multiformats/cid');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var last__default = /*#__PURE__*/ _interopDefaultLegacy(last);
function createAdd({ addAll  }) {
    return (path, options = {
    })=>{
        let iter;
        const cid$1 = cid.CID.asCID(path);
        if (cid$1) iter = addAll([
            {
                cid: cid$1,
                ...options
            }
        ], options);
        else iter = addAll([
            {
                path: path.toString(),
                ...options
            }
        ], options);
        return last__default['default'](iter);
    };
}
exports.createAdd = createAdd;

},{"it-last":"7VTHF","multiformats/cid":"fJJnW"}],"7VTHF":[function(require,module,exports) {
'use strict';
/**
 * Returns the last item of an (async) iterable, unless empty, in which case
 * return `undefined`.
 *
 * @template T
 * @param {AsyncIterable<T>|Iterable<T>} source
 */ const last = async (source)=>{
    let res;
    for await (const entry of source)res = entry;
    return res;
};
module.exports = last;

},{}],"beb5u":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var utils = require('../../utils.js');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
var normaliseInput = require('ipfs-core-utils/pins/normalise-input');
var pinTypes = require('ipfs-repo/pin-types');
function createAddAll({ repo , codecs  }) {
    async function* addAll(source, options = {
    }) {
        const pinAdd = async function*() {
            for await (const { path , recursive , metadata  } of normaliseInput.normaliseInput(source)){
                const { cid  } = await utils.resolvePath(repo, codecs, path);
                const { reason  } = await repo.pins.isPinnedWithType(cid, [
                    pinTypes.PinTypes.recursive,
                    pinTypes.PinTypes.direct
                ]);
                if (reason === 'recursive' && !recursive) throw new Error(`${cid} already pinned recursively`);
                if (recursive) await repo.pins.pinRecursively(cid, {
                    metadata
                });
                else await repo.pins.pinDirectly(cid, {
                    metadata
                });
                yield cid;
            }
        };
        const lock = Boolean(options.lock);
        if (!lock) {
            yield* pinAdd();
            return;
        }
        const release = await repo.gcLock.readLock();
        try {
            yield* pinAdd();
        } finally{
            release();
        }
    }
    return withTimeoutOption.withTimeoutOption(addAll);
}
exports.createAddAll = createAddAll;

},{"../../utils.js":"4LLx8","ipfs-core-utils/with-timeout-option":"5AiVw","ipfs-core-utils/pins/normalise-input":"azEwN","ipfs-repo/pin-types":"5TeDb"}],"azEwN":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var errCode = require('err-code');
var cid1 = require('multiformats/cid');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
async function* normaliseInput(input) {
    if (input === null || input === undefined) throw errCode__default['default'](new Error(`Unexpected input: ${input}`), 'ERR_UNEXPECTED_INPUT');
    const cid$1 = cid1.CID.asCID(input);
    if (cid$1) {
        yield toPin({
            cid: cid$1
        });
        return;
    }
    if (input instanceof String || typeof input === 'string') {
        yield toPin({
            path: input
        });
        return;
    }
    if (input.cid != null || input.path != null) return yield toPin(input);
    if (Symbol.iterator in input) {
        const iterator = input[Symbol.iterator]();
        const first = iterator.next();
        if (first.done) return iterator;
        if (cid1.CID.asCID(first.value) || first.value instanceof String || typeof first.value === 'string') {
            yield toPin({
                cid: first.value
            });
            for (const cid of iterator)yield toPin({
                cid
            });
            return;
        }
        if (first.value.cid != null || first.value.path != null) {
            yield toPin(first.value);
            for (const obj of iterator)yield toPin(obj);
            return;
        }
        throw errCode__default['default'](new Error('Unexpected input: ' + typeof input), 'ERR_UNEXPECTED_INPUT');
    }
    if (Symbol.asyncIterator in input) {
        const iterator = input[Symbol.asyncIterator]();
        const first = await iterator.next();
        if (first.done) return iterator;
        if (cid1.CID.asCID(first.value) || first.value instanceof String || typeof first.value === 'string') {
            yield toPin({
                cid: first.value
            });
            for await (const cid of iterator)yield toPin({
                cid
            });
            return;
        }
        if (first.value.cid != null || first.value.path != null) {
            yield toPin(first.value);
            for await (const obj of iterator)yield toPin(obj);
            return;
        }
        throw errCode__default['default'](new Error('Unexpected input: ' + typeof input), 'ERR_UNEXPECTED_INPUT');
    }
    throw errCode__default['default'](new Error('Unexpected input: ' + typeof input), 'ERR_UNEXPECTED_INPUT');
}
function toPin(input) {
    const path = input.cid || `${input.path}`;
    if (!path) throw errCode__default['default'](new Error('Unexpected input: Please path either a CID or an IPFS path'), 'ERR_UNEXPECTED_INPUT');
    const pin = {
        path,
        recursive: input.recursive !== false
    };
    if (input.metadata != null) pin.metadata = input.metadata;
    return pin;
}
exports.normaliseInput = normaliseInput;

},{"err-code":"eQvyh","multiformats/cid":"fJJnW"}],"5TeDb":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
const PinTypes = {
    direct: 'direct',
    recursive: 'recursive',
    indirect: 'indirect',
    all: 'all'
};
exports.PinTypes = PinTypes;

},{}],"3Hwed":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var normaliseInput = require('ipfs-core-utils/pins/normalise-input');
var utils = require('../../utils.js');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
var errCode = require('err-code');
var pinTypes = require('ipfs-repo/pin-types');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
function toPin(type, cid, metadata) {
    const output = {
        type,
        cid
    };
    if (metadata) output.metadata = metadata;
    return output;
}
function createLs({ repo , codecs  }) {
    async function* ls(options = {
    }) {
        let type = pinTypes.PinTypes.all;
        if (options.type) {
            type = options.type;
            if (!Object.keys(pinTypes.PinTypes).includes(type)) throw errCode__default['default'](new Error('Invalid pin type'), 'ERR_INVALID_PIN_TYPE');
        }
        if (options.paths) {
            let matched = false;
            for await (const { path  } of normaliseInput.normaliseInput(options.paths)){
                const { cid  } = await utils.resolvePath(repo, codecs, path);
                const { reason , pinned , parent , metadata  } = await repo.pins.isPinnedWithType(cid, type);
                if (!pinned) throw errCode__default['default'](new Error(`path '${path}' is not pinned`), 'ERR_NOT_PINNED');
                switch(reason){
                    case pinTypes.PinTypes.direct:
                    case pinTypes.PinTypes.recursive:
                        matched = true;
                        yield toPin(reason, cid, metadata);
                        break;
                    default:
                        matched = true;
                        yield toPin(`${pinTypes.PinTypes.indirect} through ${parent}`, cid, metadata);
                }
            }
            if (!matched) throw new Error('No match found');
            return;
        }
        if (type === pinTypes.PinTypes.recursive || type === pinTypes.PinTypes.all) for await (const { cid , metadata  } of repo.pins.recursiveKeys())yield toPin(pinTypes.PinTypes.recursive, cid, metadata);
        if (type === pinTypes.PinTypes.indirect || type === pinTypes.PinTypes.all) for await (const cid1 of repo.pins.indirectKeys(options))yield toPin(pinTypes.PinTypes.indirect, cid1);
        if (type === pinTypes.PinTypes.direct || type === pinTypes.PinTypes.all) for await (const { cid: cid2 , metadata: metadata1  } of repo.pins.directKeys())yield toPin(pinTypes.PinTypes.direct, cid2, metadata1);
    }
    return withTimeoutOption.withTimeoutOption(ls);
}
exports.createLs = createLs;

},{"ipfs-core-utils/pins/normalise-input":"azEwN","../../utils.js":"4LLx8","ipfs-core-utils/with-timeout-option":"5AiVw","err-code":"eQvyh","ipfs-repo/pin-types":"5TeDb"}],"hay9o":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var last = require('it-last');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var last__default = /*#__PURE__*/ _interopDefaultLegacy(last);
function createRm({ rmAll  }) {
    async function rm(path, options = {
    }) {
        const cid = await last__default['default'](rmAll([
            {
                path,
                ...options
            }
        ], options));
        if (!cid) throw new Error('CID expected');
        return cid;
    }
    return rm;
}
exports.createRm = createRm;

},{"it-last":"7VTHF"}],"akt1o":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var normaliseInput = require('ipfs-core-utils/pins/normalise-input');
var utils = require('../../utils.js');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
var pinTypes = require('ipfs-repo/pin-types');
function createRmAll({ repo , codecs  }) {
    async function* rmAll(source, _options = {
    }) {
        const release = await repo.gcLock.readLock();
        try {
            for await (const { path , recursive  } of normaliseInput.normaliseInput(source)){
                const { cid  } = await utils.resolvePath(repo, codecs, path);
                const { pinned , reason  } = await repo.pins.isPinnedWithType(cid, pinTypes.PinTypes.all);
                if (!pinned) throw new Error(`${cid} is not pinned`);
                switch(reason){
                    case pinTypes.PinTypes.recursive:
                        if (!recursive) throw new Error(`${cid} is pinned recursively`);
                        await repo.pins.unpin(cid);
                        yield cid;
                        break;
                    case pinTypes.PinTypes.direct:
                        await repo.pins.unpin(cid);
                        yield cid;
                        break;
                    default:
                        throw new Error(`${cid} is pinned indirectly under ${reason}`);
                }
            }
        } finally{
            release();
        }
    }
    return withTimeoutOption.withTimeoutOption(rmAll);
}
exports.createRmAll = createRmAll;

},{"ipfs-core-utils/pins/normalise-input":"azEwN","../../utils.js":"4LLx8","ipfs-core-utils/with-timeout-option":"5AiVw","ipfs-repo/pin-types":"5TeDb"}],"bBMH7":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var index = require('../ipns/index.js');
var config = require('../ipns/routing/config.js');
var offlineDatastore = require('../ipns/routing/offline-datastore.js');
var errors = require('../errors.js');
var debug = require('debug');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
const log = debug__default['default']('ipfs:components:ipns');
class IPNSAPI {
    constructor(options = {
        pass: ''
    }){
        this.options = options;
        this.offline = null;
        this.online = null;
    }
    getIPNS() {
        const ipns = this.online || this.offline;
        if (ipns) return ipns;
        else throw new errors.NotInitializedError();
    }
    get routing() {
        return this.getIPNS().routing;
    }
    startOffline({ repo , peerId , keychain  }) {
        if (this.offline != null) throw new errors.AlreadyInitializedError();
        log('initializing IPNS keyspace');
        const routing = new offlineDatastore.OfflineDatastore(repo);
        const ipns = new index.IPNS(routing, repo.datastore, peerId, keychain, this.options);
        this.offline = ipns;
    }
    async startOnline({ libp2p , repo: repo1 , peerId: peerId1 , keychain: keychain1  }) {
        if (this.online != null) throw new errors.AlreadyInitializedError();
        const routing = config.createRouting({
            libp2p,
            repo: repo1,
            peerId: peerId1,
            options: this.options
        });
        const ipns = new index.IPNS(routing, repo1.datastore, peerId1, keychain1, this.options);
        await ipns.republisher.start();
        this.online = ipns;
    }
    async stop() {
        const ipns = this.online;
        if (ipns) {
            await ipns.republisher.stop();
            this.online = null;
        }
    }
    publish(privKey, value, lifetime) {
        return this.getIPNS().publish(privKey, value, lifetime);
    }
    resolve(name, options1) {
        return this.getIPNS().resolve(name, options1);
    }
    initializeKeyspace(privKey1, value1) {
        return this.getIPNS().initializeKeyspace(privKey1, value1);
    }
}
exports.IPNSAPI = IPNSAPI;

},{"../ipns/index.js":"b38VD","../ipns/routing/config.js":"eKm5u","../ipns/routing/offline-datastore.js":"jVUnq","../errors.js":"itpk8","debug":"lWlU4"}],"b38VD":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var PeerId = require('peer-id');
var errCode = require('err-code');
var debug = require('debug');
var publisher = require('./publisher.js');
var republisher = require('./republisher.js');
var resolver = require('./resolver.js');
var tlru = require('../utils/tlru.js');
var toString = require('uint8arrays/to-string');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
const log = Object.assign(debug__default['default']('ipfs:ipns'), {
    error: debug__default['default']('ipfs:ipns:error')
});
const defaultRecordTtl = 60000;
class IPNS {
    constructor(routing, datastore, peerId, keychain, options){
        this.publisher = new publisher.IpnsPublisher(routing, datastore);
        this.republisher = new republisher.IpnsRepublisher(this.publisher, datastore, peerId, keychain, options);
        this.resolver = new resolver.IpnsResolver(routing);
        this.cache = new tlru.TLRU(1000);
        this.routing = routing;
    }
    async publish(privKey, value, lifetime = publisher.IpnsPublisher.defaultRecordLifetime) {
        try {
            const peerId = await PeerId.createFromPrivKey(privKey.bytes);
            await this.publisher.publishWithEOL(privKey, value, lifetime);
            log(`IPNS value ${toString.toString(value, 'base32')} was published correctly`);
            const id = peerId.toB58String();
            const ttEol = parseFloat(lifetime);
            const ttl = ttEol < defaultRecordTtl ? ttEol : defaultRecordTtl;
            this.cache.set(id, value, ttl);
            log(`IPNS value ${toString.toString(value, 'base32')} was cached correctly`);
            return {
                name: id,
                value: value
            };
        } catch (err) {
            log.error(err);
            throw err;
        }
    }
    async resolve(name, options1 = {
    }) {
        if (typeof name !== 'string') throw errCode__default['default'](new Error('name received is not valid'), 'ERR_INVALID_NAME');
        if (!options1.nocache && !options1.recursive) {
            const id = name.split('/')[2];
            const result = this.cache.get(id);
            if (result) return result;
        }
        try {
            const result = await this.resolver.resolve(name, options1);
            log(`IPNS record from ${name} was resolved correctly`);
            return result;
        } catch (err) {
            log.error(err);
            throw err;
        }
    }
    async initializeKeyspace(privKey1, value1) {
        return this.publish(privKey1, value1, publisher.IpnsPublisher.defaultRecordLifetime);
    }
}
exports.IPNS = IPNS;

},{"peer-id":"4VGWt","err-code":"eQvyh","debug":"lWlU4","./publisher.js":"8WdaY","./republisher.js":"dbOMZ","./resolver.js":"jaAWZ","../utils/tlru.js":"4Epuc","uint8arrays/to-string":"g3mCQ"}],"8WdaY":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var PeerId = require('peer-id');
var key = require('interface-datastore/key');
var Errors = require('datastore-core/errors');
var errCode = require('err-code');
var debug = require('debug');
var toString = require('uint8arrays/to-string');
var equals = require('uint8arrays/equals');
var ipns = require('ipns');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n['default'] = e;
    return Object.freeze(n);
}
var PeerId__default = /*#__PURE__*/ _interopDefaultLegacy(PeerId);
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
var ipns__namespace = /*#__PURE__*/ _interopNamespace(ipns);
const log = Object.assign(debug__default['default']('ipfs:ipns:publisher'), {
    error: debug__default['default']('ipfs:ipns:publisher:error')
});
const ERR_NOT_FOUND = Errors.notFoundError().code;
const defaultRecordLifetime = 3600000;
class IpnsPublisher {
    constructor(routing, datastore){
        this._routing = routing;
        this._datastore = datastore;
    }
    async publishWithEOL(privKey, value, lifetime) {
        if (!privKey || !privKey.bytes) throw errCode__default['default'](new Error('invalid private key'), 'ERR_INVALID_PRIVATE_KEY');
        const peerId = await PeerId__default['default'].createFromPrivKey(privKey.bytes);
        const record = await this._updateOrCreateRecord(privKey, value, lifetime, peerId);
        return this._putRecordToRouting(record, peerId);
    }
    publish(privKey1, value1) {
        return this.publishWithEOL(privKey1, value1, defaultRecordLifetime);
    }
    async _putRecordToRouting(record, peerId) {
        if (!PeerId__default['default'].isPeerId(peerId)) {
            const errMsg = 'peerId received is not valid';
            log.error(errMsg);
            throw errCode__default['default'](new Error(errMsg), 'ERR_INVALID_PEER_ID');
        }
        const publicKey = peerId._pubKey;
        const embedPublicKeyRecord = await ipns__namespace.embedPublicKey(publicKey, record);
        const keys = ipns__namespace.getIdKeys(peerId.toBytes());
        await this._publishEntry(keys.routingKey, embedPublicKeyRecord || record);
        await this._publishPublicKey(keys.routingPubKey, publicKey);
        return embedPublicKeyRecord || record;
    }
    async _publishEntry(key$1, entry) {
        const k = key.Key.asKey(key$1);
        if (!k) {
            const errMsg = 'datastore key does not have a valid format';
            log.error(errMsg);
            throw errCode__default['default'](new Error(errMsg), 'ERR_INVALID_DATASTORE_KEY');
        }
        let entryData;
        try {
            entryData = ipns__namespace.marshal(entry);
        } catch (err) {
            log.error(err);
            throw err;
        }
        try {
            const res = await this._routing.put(k.uint8Array(), entryData);
            log(`ipns record for ${toString.toString(k.uint8Array(), 'base64')} was stored in the routing`);
            return res;
        } catch (err1) {
            const errMsg = `ipns record for ${toString.toString(k.uint8Array(), 'base64')} could not be stored in the routing`;
            log.error(errMsg);
            log.error(err1);
            throw errCode__default['default'](new Error(errMsg), 'ERR_PUTTING_TO_ROUTING');
        }
    }
    async _publishPublicKey(key$11, publicKey) {
        const k = key.Key.asKey(key$11);
        if (!k) {
            const errMsg = 'datastore key does not have a valid format';
            log.error(errMsg);
            throw errCode__default['default'](new Error(errMsg), 'ERR_INVALID_DATASTORE_KEY');
        }
        if (!publicKey || !publicKey.bytes) {
            const errMsg = 'one or more of the provided parameters are not defined';
            log.error(errMsg);
            throw errCode__default['default'](new Error(errMsg), 'ERR_UNDEFINED_PARAMETER');
        }
        try {
            const res = await this._routing.put(k.uint8Array(), publicKey.bytes);
            log(`public key for ${toString.toString(k.uint8Array(), 'base64')} was stored in the routing`);
            return res;
        } catch (err) {
            const errMsg = `public key for ${toString.toString(k.uint8Array(), 'base64')} could not be stored in the routing`;
            log.error(errMsg);
            log.error(err);
            throw errCode__default['default'](new Error(errMsg), 'ERR_PUTTING_TO_ROUTING');
        }
    }
    async _getPublished(peerId1, options = {
    }) {
        if (!PeerId__default['default'].isPeerId(peerId1)) {
            const errMsg = 'peerId received is not valid';
            log.error(errMsg);
            throw errCode__default['default'](new Error(errMsg), 'ERR_INVALID_PEER_ID');
        }
        const checkRouting = options.checkRouting !== false;
        try {
            const dsVal = await this._datastore.get(ipns__namespace.getLocalKey(peerId1.id));
            return this._unmarshalData(dsVal);
        } catch (err) {
            if (err.code !== ERR_NOT_FOUND) {
                const errMsg = `unexpected error getting the ipns record ${peerId1.id} from datastore`;
                log.error(errMsg);
                throw errCode__default['default'](new Error(errMsg), 'ERR_UNEXPECTED_DATASTORE_RESPONSE');
            }
            if (!checkRouting) throw errCode__default['default'](err, 'ERR_NOT_FOUND_AND_CHECK_ROUTING_NOT_ENABLED');
            try {
                const keys = ipns__namespace.getIdKeys(peerId1.toBytes());
                const res = await this._routing.get(keys.routingKey.uint8Array());
                return this._unmarshalData(res);
            } catch (err) {
                log.error(err);
                throw err;
            }
        }
    }
    _unmarshalData(data) {
        try {
            return ipns__namespace.unmarshal(data);
        } catch (err) {
            throw errCode__default['default'](err, 'ERR_INVALID_RECORD_DATA');
        }
    }
    async _updateOrCreateRecord(privKey2, value2, lifetime1, peerId2) {
        if (!PeerId__default['default'].isPeerId(peerId2)) {
            const errMsg = 'peerId received is not valid';
            log.error(errMsg);
            throw errCode__default['default'](new Error(errMsg), 'ERR_INVALID_PEER_ID');
        }
        const getPublishedOptions = {
            checkRouting: true
        };
        let record;
        try {
            record = await this._getPublished(peerId2, getPublishedOptions);
        } catch (err) {
            if (err.code !== ERR_NOT_FOUND) {
                const errMsg = `unexpected error when determining the last published IPNS record for ${peerId2.id} ${err.stack}`;
                log.error(errMsg);
                throw errCode__default['default'](new Error(errMsg), 'ERR_DETERMINING_PUBLISHED_RECORD');
            }
        }
        let seqNumber = 0;
        if (record && record.sequence !== undefined) seqNumber = !equals.equals(record.value, value2) ? BigInt(record.sequence) + BigInt(1) : BigInt(record.sequence);
        let entryData;
        try {
            entryData = await ipns__namespace.create(privKey2, value2, seqNumber, lifetime1);
        } catch (err2) {
            const errMsg = `ipns record for ${value2} could not be created`;
            log.error(err2);
            throw errCode__default['default'](new Error(errMsg), 'ERR_CREATING_IPNS_RECORD');
        }
        try {
            const data = ipns__namespace.marshal(entryData);
            await this._datastore.put(ipns__namespace.getLocalKey(peerId2.id), data);
            log(`ipns record for ${toString.toString(value2, 'base32')} was stored in the datastore`);
            return entryData;
        } catch (err3) {
            const errMsg = `ipns record for ${value2} could not be stored in the datastore`;
            log.error(errMsg);
            throw errCode__default['default'](new Error(errMsg), 'ERR_STORING_IN_DATASTORE');
        }
    }
}
IpnsPublisher.defaultRecordLifetime = defaultRecordLifetime;
exports.IpnsPublisher = IpnsPublisher;

},{"peer-id":"4VGWt","interface-datastore/key":"ccQWS","datastore-core/errors":"hKmom","err-code":"eQvyh","debug":"lWlU4","uint8arrays/to-string":"g3mCQ","uint8arrays/equals":"fjLeN","ipns":"jnLxg"}],"hKmom":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var errCode = require('err-code');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
function dbOpenFailedError(err) {
    err = err || new Error('Cannot open database');
    return errCode__default['default'](err, 'ERR_DB_OPEN_FAILED');
}
function dbDeleteFailedError(err) {
    err = err || new Error('Delete failed');
    return errCode__default['default'](err, 'ERR_DB_DELETE_FAILED');
}
function dbWriteFailedError(err) {
    err = err || new Error('Write failed');
    return errCode__default['default'](err, 'ERR_DB_WRITE_FAILED');
}
function notFoundError(err) {
    err = err || new Error('Not Found');
    return errCode__default['default'](err, 'ERR_NOT_FOUND');
}
function abortedError(err) {
    err = err || new Error('Aborted');
    return errCode__default['default'](err, 'ERR_ABORTED');
}
exports.abortedError = abortedError;
exports.dbDeleteFailedError = dbDeleteFailedError;
exports.dbOpenFailedError = dbOpenFailedError;
exports.dbWriteFailedError = dbWriteFailedError;
exports.notFoundError = notFoundError;

},{"err-code":"eQvyh"}],"jnLxg":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var NanoDate = require('timestamp-nano');
var key1 = require('interface-datastore/key');
var crypto = require('libp2p-crypto');
var PeerId = require('peer-id');
var Digest = require('multiformats/hashes/digest');
var identity = require('multiformats/hashes/identity');
var errCode = require('err-code');
var base32 = require('multiformats/bases/base32');
var fromString = require('uint8arrays/from-string');
var toString = require('uint8arrays/to-string');
var concat = require('uint8arrays/concat');
var equals = require('uint8arrays/equals');
var cborg = require('cborg');
var Long = require('long');
var debug = require('debug');
var ipns = require('./pb/ipns.js');
var utils = require('./utils.js');
var errors = require('./errors.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n['default'] = e;
    return Object.freeze(n);
}
var NanoDate__default = /*#__PURE__*/ _interopDefaultLegacy(NanoDate);
var crypto__default = /*#__PURE__*/ _interopDefaultLegacy(crypto);
var PeerId__default = /*#__PURE__*/ _interopDefaultLegacy(PeerId);
var Digest__namespace = /*#__PURE__*/ _interopNamespace(Digest);
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
var cborg__namespace = /*#__PURE__*/ _interopNamespace(cborg);
var Long__default = /*#__PURE__*/ _interopDefaultLegacy(Long);
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
const log = Object.assign(debug__default['default']('jsipns'), {
    error: debug__default['default']('jsipns:error')
});
const ID_MULTIHASH_CODE = identity.identity.code;
const IPNS_PREFIX = fromString.fromString('/ipns/');
const namespace = '/ipns/';
const namespaceLength = namespace.length;
const create = (privateKey, value, seq, lifetime)=>{
    const expirationDate = new NanoDate__default['default'](Date.now() + Number(lifetime));
    const validityType = ipns.IpnsEntry.ValidityType.EOL;
    const [ms, ns] = lifetime.toString().split('.');
    const lifetimeNs = BigInt(ms) * BigInt(100000) + BigInt(ns || 0);
    return _create(privateKey, value, seq, validityType, expirationDate, lifetimeNs);
};
const createWithExpiration = (privateKey, value, seq, expiration)=>{
    const expirationDate = NanoDate__default['default'].fromString(expiration);
    const validityType = ipns.IpnsEntry.ValidityType.EOL;
    const ttlMs = expirationDate.toDate().getTime() - Date.now();
    const ttlNs = BigInt(ttlMs) * BigInt(100000) + BigInt(expirationDate.getNano());
    return _create(privateKey, value, seq, validityType, expirationDate, ttlNs);
};
const _create = async (privateKey, value, seq, validityType, expirationDate, ttl)=>{
    seq = BigInt(seq);
    const isoValidity = fromString.fromString(expirationDate.toString());
    const signatureV1 = await sign(privateKey, value, validityType, isoValidity);
    const data = createCborData(value, isoValidity, validityType, seq, ttl);
    const sigData = ipnsEntryDataForV2Sig(data);
    const signatureV2 = await privateKey.sign(sigData);
    const entry = {
        value,
        signature: signatureV1,
        validityType: validityType,
        validity: isoValidity,
        sequence: seq,
        ttl,
        signatureV2,
        data
    };
    log(`ipns entry for ${value} created`);
    return entry;
};
const createCborData = (value, validity, validityType, sequence, ttl)=>{
    const data = {
        Value: value,
        Validity: validity,
        ValidityType: validityType,
        Sequence: sequence,
        TTL: ttl
    };
    return cborg__namespace.encode(data);
};
const validate = async (publicKey, entry)=>{
    const { value , validityType , validity  } = entry;
    let dataForSignature;
    let signature;
    if (entry.signatureV2 && entry.data) {
        signature = entry.signatureV2;
        dataForSignature = ipnsEntryDataForV2Sig(entry.data);
        validateCborDataMatchesPbData(entry);
    } else {
        signature = entry.signature;
        dataForSignature = ipnsEntryDataForV1Sig(value, validityType, validity);
    }
    let isValid;
    try {
        isValid = await publicKey.verify(dataForSignature, signature);
    } catch (err) {
        isValid = false;
    }
    if (!isValid) {
        log.error('record signature verification failed');
        throw errCode__default['default'](new Error('record signature verification failed'), errors.ERR_SIGNATURE_VERIFICATION);
    }
    if (validityType === ipns.IpnsEntry.ValidityType.EOL) {
        let validityDate;
        try {
            validityDate = utils.parseRFC3339(toString.toString(validity));
        } catch (e) {
            log.error('unrecognized validity format (not an rfc3339 format)');
            throw errCode__default['default'](new Error('unrecognized validity format (not an rfc3339 format)'), errors.ERR_UNRECOGNIZED_FORMAT);
        }
        if (validityDate.getTime() < Date.now()) {
            log.error('record has expired');
            throw errCode__default['default'](new Error('record has expired'), errors.ERR_IPNS_EXPIRED_RECORD);
        }
    } else if (validityType) {
        log.error('unrecognized validity type');
        throw errCode__default['default'](new Error('unrecognized validity type'), errors.ERR_UNRECOGNIZED_VALIDITY);
    }
    log(`ipns entry for ${value} is valid`);
};
const validateCborDataMatchesPbData = (entry)=>{
    if (!entry.data) throw errCode__default['default'](new Error('Record data is missing'), errors.ERR_INVALID_RECORD_DATA);
    const data = cborg__namespace.decode(entry.data);
    if (Number.isInteger(data.Sequence)) data.Sequence = BigInt(data.Sequence);
    if (Number.isInteger(data.TTL)) data.TTL = BigInt(data.TTL);
    if (!equals.equals(data.Value, entry.value)) throw errCode__default['default'](new Error('Field "value" did not match between protobuf and CBOR'), errors.ERR_SIGNATURE_VERIFICATION);
    if (!equals.equals(data.Validity, entry.validity)) throw errCode__default['default'](new Error('Field "validity" did not match between protobuf and CBOR'), errors.ERR_SIGNATURE_VERIFICATION);
    if (data.ValidityType !== entry.validityType) throw errCode__default['default'](new Error('Field "validityType" did not match between protobuf and CBOR'), errors.ERR_SIGNATURE_VERIFICATION);
    if (data.Sequence !== entry.sequence) throw errCode__default['default'](new Error('Field "sequence" did not match between protobuf and CBOR'), errors.ERR_SIGNATURE_VERIFICATION);
    if (data.TTL !== entry.ttl) throw errCode__default['default'](new Error('Field "ttl" did not match between protobuf and CBOR'), errors.ERR_SIGNATURE_VERIFICATION);
};
const embedPublicKey = async (publicKey, entry)=>{
    if (!publicKey || !publicKey.bytes || !entry) {
        const error = new Error('one or more of the provided parameters are not defined');
        log.error(error);
        throw errCode__default['default'](error, errors.ERR_UNDEFINED_PARAMETER);
    }
    let peerId;
    try {
        peerId = await PeerId__default['default'].createFromPubKey(publicKey.bytes);
    } catch (err) {
        throw errCode__default['default'](err, errors.ERR_PEER_ID_FROM_PUBLIC_KEY);
    }
    let extractedPublicKey;
    try {
        extractedPublicKey = extractPublicKeyFromId(peerId);
    } catch (err1) {
        log.error(err1);
        throw errCode__default['default'](err1, errors.ERR_PUBLIC_KEY_FROM_ID);
    }
    if (extractedPublicKey) return null;
    try {
        entry.pubKey = crypto__default['default'].keys.marshalPublicKey(publicKey);
    } catch (err2) {
        log.error(err2);
        throw err2;
    }
    return entry;
};
const extractPublicKey = async (peerId, entry)=>{
    if (!entry || !peerId) {
        const error = new Error('one or more of the provided parameters are not defined');
        log.error(error);
        throw errCode__default['default'](error, errors.ERR_UNDEFINED_PARAMETER);
    }
    let pubKey;
    if (entry.pubKey) {
        try {
            pubKey = crypto__default['default'].keys.unmarshalPublicKey(entry.pubKey);
        } catch (err) {
            log.error(err);
            throw err;
        }
        const otherId = await PeerId__default['default'].createFromPubKey(entry.pubKey);
        if (!otherId.equals(peerId)) throw errCode__default['default'](new Error('Embedded public key did not match PeerID'), errors.ERR_INVALID_EMBEDDED_KEY);
    } else if (peerId.pubKey) pubKey = peerId.pubKey;
    if (pubKey) return pubKey;
    throw errCode__default['default'](new Error('no public key is available'), errors.ERR_UNDEFINED_PARAMETER);
};
const rawStdEncoding = (key)=>base32.base32upper.encode(key).slice(1)
;
const getLocalKey = (key$1)=>new key1.Key(`/ipns/${rawStdEncoding(key$1)}`)
;
const getIdKeys = (pid)=>{
    const pkBuffer = fromString.fromString('/pk/');
    const ipnsBuffer = fromString.fromString('/ipns/');
    return {
        routingPubKey: new key1.Key(concat.concat([
            pkBuffer,
            pid
        ]), false),
        pkKey: new key1.Key(rawStdEncoding(concat.concat([
            pkBuffer,
            pid
        ]))),
        routingKey: new key1.Key(concat.concat([
            ipnsBuffer,
            pid
        ]), false),
        ipnsKey: new key1.Key(rawStdEncoding(concat.concat([
            ipnsBuffer,
            pid
        ])))
    };
};
const sign = (privateKey, value, validityType, validity)=>{
    try {
        const dataForSignature = ipnsEntryDataForV1Sig(value, validityType, validity);
        return privateKey.sign(dataForSignature);
    } catch (error) {
        log.error('record signature creation failed');
        throw errCode__default['default'](new Error('record signature creation failed: ' + error.message), errors.ERR_SIGNATURE_CREATION);
    }
};
const getValidityType = (validityType)=>{
    if (validityType.toString() === '0') return 'EOL';
    const error = new Error(`unrecognized validity type ${validityType.toString()}`);
    log.error(error);
    throw errCode__default['default'](error, errors.ERR_UNRECOGNIZED_VALIDITY);
};
const ipnsEntryDataForV1Sig = (value, validityType, validity)=>{
    const validityTypeBuffer = fromString.fromString(getValidityType(validityType));
    return concat.concat([
        value,
        validity,
        validityTypeBuffer
    ]);
};
const ipnsEntryDataForV2Sig = (data)=>{
    const entryData = fromString.fromString('ipns-signature:');
    return concat.concat([
        entryData,
        data
    ]);
};
const extractPublicKeyFromId = (peerId)=>{
    const digest = Digest__namespace.decode(peerId.id);
    if (digest.code !== ID_MULTIHASH_CODE) return null;
    return crypto__default['default'].keys.unmarshalPublicKey(digest.digest);
};
const marshal = (obj)=>{
    return ipns.IpnsEntry.encode({
        ...obj,
        sequence: Long__default['default'].fromString(obj.sequence.toString()),
        ttl: obj.ttl == null ? undefined : Long__default['default'].fromString(obj.ttl.toString())
    }).finish();
};
const unmarshal = (buf)=>{
    const message = ipns.IpnsEntry.decode(buf);
    const object = ipns.IpnsEntry.toObject(message, {
        defaults: false,
        arrays: true,
        objects: false
    });
    return {
        value: object.value,
        signature: object.signature,
        validityType: object.validityType,
        validity: object.validity,
        sequence: Object.hasOwnProperty.call(object, 'sequence') ? BigInt(`${object.sequence}`) : 0,
        pubKey: object.pubKey,
        ttl: Object.hasOwnProperty.call(object, 'ttl') ? BigInt(`${object.ttl}`) : undefined,
        signatureV2: object.signatureV2,
        data: object.data
    };
};
const validator = {
    validate: async (marshalledData, key)=>{
        const receivedEntry = unmarshal(marshalledData);
        const bufferId = key.slice(IPNS_PREFIX.length);
        const peerId = PeerId__default['default'].createFromBytes(bufferId);
        const pubKey = await extractPublicKey(peerId, receivedEntry);
        await validate(pubKey, receivedEntry);
    },
    select: (dataA, dataB)=>{
        const entryA = unmarshal(dataA);
        const entryB = unmarshal(dataB);
        if (entryA.signatureV2 && !entryB.signatureV2) return 0;
        else if (entryB.signatureV2 && !entryA.signatureV2) return 1;
        if (entryA.sequence > entryB.sequence) return 0;
        else if (entryA.sequence < entryB.sequence) return 1;
        const entryAValidityDate = utils.parseRFC3339(toString.toString(entryA.validity));
        const entryBValidityDate = utils.parseRFC3339(toString.toString(entryB.validity));
        return entryBValidityDate.getTime() > entryAValidityDate.getTime() ? 1 : 0;
    }
};
exports.create = create;
exports.createWithExpiration = createWithExpiration;
exports.embedPublicKey = embedPublicKey;
exports.extractPublicKey = extractPublicKey;
exports.getIdKeys = getIdKeys;
exports.getLocalKey = getLocalKey;
exports.marshal = marshal;
exports.namespace = namespace;
exports.namespaceLength = namespaceLength;
exports.unmarshal = unmarshal;
exports.validate = validate;
exports.validator = validator;

},{"timestamp-nano":"ephAm","interface-datastore/key":"ccQWS","libp2p-crypto":"hsRcr","peer-id":"4VGWt","multiformats/hashes/digest":"fkA58","multiformats/hashes/identity":"7Cndu","err-code":"eQvyh","multiformats/bases/base32":"63xDB","uint8arrays/from-string":"lo45E","uint8arrays/to-string":"g3mCQ","uint8arrays/concat":"fLIrL","uint8arrays/equals":"fjLeN","cborg":"6ZYxo","long":"5EBlW","debug":"lWlU4","./pb/ipns.js":"kOLH3","./utils.js":"dTpAp","./errors.js":"habNi"}],"ephAm":[function(require,module,exports) {
/**
 * Timestamp for 64-bit time_t, nanosecond precision and strftime
 *
 * @author Yusuke Kawasaki
 * @license MIT
 * @see https://github.com/kawanet/timestamp-nano
 */ var Timestamp1 = function() {
    if ("undefined" !== typeof module) module.exports = Timestamp;
    var SEC_DAY = 86400; // seconds per day
    var YEAR_SLOT = 3200; // years per slot
    var DAY_SLOT = 146097 * YEAR_SLOT / 400; // days per slot
    var SEC_SLOT = SEC_DAY * DAY_SLOT; // seconds per slot
    var MSEC_SLOT = SEC_SLOT * 1000; // mseconds per slot
    // 15.9.1.1 Time Values and Time Range
    // The actual range of times supported by ECMAScript Date objects is
    // exactly –100,000,000 days to 100,000,000 days measured relative to
    // midnight at the beginning of 01 January, 1970 UTC.
    var MAX_MSEC = 100000000000 * SEC_DAY;
    var BIT24 = 16777216;
    var BIT32 = 4294967296;
    var DEC6 = 1000000;
    var DEC9 = 1000000000;
    var ZERO9 = "000000000";
    var trunc = Math.trunc || Math_trunc;
    var P = Timestamp.prototype;
    // static methods
    Timestamp.fromDate = fromDate;
    Timestamp.fromInt64BE = buildFromInt64(0, 1, 2, 3, 0, 4);
    Timestamp.fromInt64LE = buildFromInt64(3, 2, 1, 0, 4, 0);
    Timestamp.fromString = fromString;
    Timestamp.fromTimeT = fromTimeT;
    // private properties
    P.year = 0; // Offset number for year precision
    P.time = 0; // Milliseconds from epoch
    P.nano = 0; // Offset number for nanosecond precision
    // instance methods
    P.addNano = addNano;
    P.getNano = getNano;
    P.getTimeT = getTimeT;
    P.getYear = getYear;
    P.toDate = toDate;
    P.toJSON = toJSON;
    P.toString = toString;
    P.writeInt64BE = buildWriteInt64(0, 1, 2, 3, 0, 4);
    P.writeInt64LE = buildWriteInt64(3, 2, 1, 0, 4, 0);
    var FMT_JSON = "%Y-%m-%dT%H:%M:%S.%NZ";
    var FMT_MONTH = [
        "Jan",
        "Feb",
        "Mar",
        "Apr",
        "May",
        "Jun",
        "Jul",
        "Aug",
        "Sep",
        "Oct",
        "Nov",
        "Dec"
    ];
    var FMT_DAY = [
        "Sun",
        "Mon",
        "Tue",
        "Wed",
        "Thu",
        "Fri",
        "Sat"
    ];
    var FMT_STRING = {
        "%": "%",
        F: "%Y-%m-%d",
        n: "\n",
        R: "%H:%M",
        T: "%H:%M:%S",
        t: "\t",
        X: "%T",
        Z: "GMT",
        z: "+0000"
    };
    function Timestamp(time, nano, year) {
        var ts = this;
        if (!(ts instanceof Timestamp)) return new Timestamp(time, nano, year);
        ts.time = +time || 0;
        ts.nano = +nano || 0;
        ts.year = +year || 0;
        normalize(ts);
    }
    function getYear() {
        var year = this.toDate().getUTCFullYear();
        return year + this.year;
    }
    function normalize(ts) {
        var year = ts.year;
        var time = ts.time;
        var nano = ts.nano;
        var changed;
        var slot;
        // normalize nano
        if (nano < 0 || DEC6 <= nano) {
            var n = Math.floor(nano / DEC6);
            nano -= n * DEC6;
            time += n;
            changed = 1;
        }
        var y = year % YEAR_SLOT;
        if (time < -MAX_MSEC || MAX_MSEC < time || y) {
            // shrink time into the minimal slot
            slot = trunc(time / MSEC_SLOT);
            if (slot) {
                year += slot * YEAR_SLOT;
                time -= slot * MSEC_SLOT;
            }
            // add year offset smaller than a slot
            var dt = newDate(time);
            dt.setUTCFullYear(y + dt.getUTCFullYear());
            year -= y;
            time = +dt;
            // use full range of 100 million days.
            slot = trunc(year / YEAR_SLOT);
            var total = time + slot * MSEC_SLOT;
            if (slot && -MAX_MSEC <= total && total <= MAX_MSEC) {
                year -= slot * YEAR_SLOT;
                time = total;
            }
            changed = 1;
        }
        if (changed) {
            ts.year = year;
            ts.time = time;
            ts.nano = nano;
        }
        return ts;
    }
    function toDate() {
        var ts = normalize(this);
        return newDate(ts.time);
    }
    function newDate(time) {
        var dt = new Date(0);
        dt.setTime(time);
        return dt;
    }
    function addNano(nano) {
        this.nano += +nano || 0;
        return this;
    }
    function getNano() {
        var ts = normalize(this);
        return (ts.time % 1000 * DEC6 + +ts.nano + DEC9) % DEC9;
    }
    function fromString(string) {
        var time;
        var ts = new Timestamp();
        string += "";
        var array = string.replace(/^\s*[+\-]?\d+/, function(match) {
            var year = +match;
            // Use only years around 1970 to avoid Date's terrible behavior:
            // 15.9.4.3 Date.UTC
            // If y is not NaN and 0 <= y <= 99, then let yr be 1900+y
            var y = 1970 + (year - 1970) % 400;
            ts.year = year - y;
            return y;
        }).replace(/(?:Z|([+\-]\d{2}):?(\d{2}))$/, function(match, hour, min) {
            // time zone
            if (hour < 0) min *= -1;
            time = (+hour * 60 + +min) * 60000;
            return "";
        }).replace(/\.\d+$/, function(match) {
            // nanoseconds
            ts.nano = +(match + ZERO9).substr(1, 9);
            return "";
        }).split(/\D+/);
        if (array.length > 1) {
            array[1]--; // month starts from 0
        } else {
            array[1] = 0;
        }
        ts.time = time = Date.UTC.apply(Date, array) - (time || 0);
        if (isNaN(time)) {
            throw new TypeError("Invalid Date");
        }
        return normalize(ts);
    }
    function fromDate(date) {
        return new Timestamp(+date);
    }
    function fromTimeT(time) {
        return fromTime(time, 0);
    }
    function fromTime(low, high) {
        high |= 0;
        high *= BIT32;
        low = +low || 0;
        // slot count
        var slot = trunc(high / SEC_SLOT) + trunc(low / SEC_SLOT);
        // seconds within slot
        var second = high % SEC_SLOT + low % SEC_SLOT;
        // slot offset
        var offset = trunc(second / SEC_SLOT);
        if (offset) {
            slot += offset;
            second -= offset * SEC_SLOT;
        }
        return new Timestamp(second * 1000, 0, slot * YEAR_SLOT);
    }
    function getTimeT() {
        var ts = normalize(this);
        var time = Math.floor(ts.time / 1000);
        var year = ts.year;
        if (year) time += year * DAY_SLOT * SEC_DAY / YEAR_SLOT;
        // this may loose some bits over than 53 bit precision
        return time;
    }
    function toJSON() {
        return this.toString().replace(/0{1,6}Z$/, "Z");
    }
    function toString(format1) {
        var ts = this;
        var dt = ts.toDate();
        var map = {
            H: H,
            L: L,
            M: M,
            N: N,
            S: S,
            Y: Y,
            a: a,
            b: b,
            d: d,
            e: e,
            m: m
        };
        return strftime(format1 || FMT_JSON);
        function strftime(format) {
            return format.replace(/%./g, function(match) {
                var m = match[1];
                var c = FMT_STRING[m];
                var f = map[m];
                return c ? strftime(c) : f ? f() : match;
            });
        }
        function Y() {
            var year = ts.getYear();
            if (year > 999999) {
                return "+" + year;
            } else if (year > 9999) {
                return "+" + pad(year, 6);
            } else if (year >= 0) {
                return pad(year, 4);
            } else if (year >= -999999) {
                return "-" + pad(-year, 6);
            } else {
                return year;
            }
        }
        function m() {
            return pad2(dt.getUTCMonth() + 1);
        }
        function d() {
            return pad2(dt.getUTCDate());
        }
        function e() {
            return padS(dt.getUTCDate());
        }
        function H() {
            return pad2(dt.getUTCHours());
        }
        function M() {
            return pad2(dt.getUTCMinutes());
        }
        function S() {
            return pad2(dt.getUTCSeconds());
        }
        function L() {
            return pad(dt.getUTCMilliseconds(), 3);
        }
        function N() {
            return pad(ts.getNano(), 9);
        }
        function a() {
            return FMT_DAY[dt.getUTCDay()];
        }
        function b() {
            return FMT_MONTH[dt.getUTCMonth()];
        }
    }
    function buildWriteInt64(pos0, pos1, pos2, pos3, posH, posL) {
        return writeInt64;
        function writeInt64(buffer, offset) {
            var ts = normalize(this);
            if (!buffer) buffer = new Array(8);
            checkRange(buffer, offset |= 0);
            var second = Math.floor(ts.time / 1000);
            var day = ts.year * (DAY_SLOT * SEC_DAY / YEAR_SLOT);
            var high = trunc(day / BIT32) + trunc(second / BIT32);
            var low = day % BIT32 + second % BIT32;
            // slot offset
            var slot = Math.floor(low / BIT32);
            if (slot) {
                high += slot;
                low -= slot * BIT32;
            }
            writeUint32(buffer, offset + posH, high);
            writeUint32(buffer, offset + posL, low);
            return buffer;
        }
        function writeUint32(buffer, offset, value) {
            buffer[offset + pos0] = value >> 24 & 255;
            buffer[offset + pos1] = value >> 16 & 255;
            buffer[offset + pos2] = value >> 8 & 255;
            buffer[offset + pos3] = value & 255;
        }
    }
    function buildFromInt64(pos0, pos1, pos2, pos3, posH, posL) {
        return fromInt64;
        function fromInt64(buffer, offset) {
            checkRange(buffer, offset |= 0);
            var high = readUint32(buffer, offset + posH);
            var low = readUint32(buffer, offset + posL);
            return fromTime(low, high);
        }
        function readUint32(buffer, offset) {
            return buffer[offset + pos0] * BIT24 + (buffer[offset + pos1] << 16 | buffer[offset + pos2] << 8 | buffer[offset + pos3]);
        }
    }
    function checkRange(buffer, offset) {
        var last = buffer && buffer.length;
        if (last == null) throw new TypeError("Invalid Buffer");
        if (last < offset + 8) throw new RangeError("Out of range");
    }
    function Math_trunc(x) {
        var n = x - x % 1;
        return n === 0 && (x < 0 || x === 0 && 1 / x !== 1 / 0) ? -0 : n;
    }
    function padS(v) {
        return (v > 9 ? "" : " ") + (v | 0);
    }
    function pad2(v) {
        return (v > 9 ? "" : "0") + (v | 0);
    }
    function pad(v, len) {
        return (ZERO9 + (v | 0)).substr(-len);
    }
    return Timestamp;
}();

},{}],"hsRcr":[function(require,module,exports) {
'use strict';
const hmac = require('./hmac');
const aes = require('./aes');
const keys = require('./keys');
exports.aes = aes;
exports.hmac = hmac;
exports.keys = keys;
exports.randomBytes = require('./random-bytes');
exports.pbkdf2 = require('./pbkdf2');

},{"./hmac":"eZkFq","./aes":"4voe7","./keys":"Ore66","./random-bytes":"1G1Dz","./pbkdf2":"cfxLy"}],"4voe7":[function(require,module,exports) {
'use strict';
const ciphers = require('./ciphers');
const cipherMode = require('./cipher-mode');
exports.create = async function(key, iv) {
    const mode = cipherMode(key);
    const cipher = ciphers.createCipheriv(mode, key, iv);
    const decipher = ciphers.createDecipheriv(mode, key, iv);
    const res = {
        async encrypt (data) {
            return cipher.update(data);
        },
        async decrypt (data) {
            return decipher.update(data);
        }
    };
    return res;
};

},{"./ciphers":"1XrwC","./cipher-mode":"5Iu8s"}],"1XrwC":[function(require,module,exports) {
'use strict';
require('node-forge/lib/aes');
const forge = require('node-forge/lib/forge');
const { toString: uint8ArrayToString  } = require('uint8arrays/to-string');
const { fromString: uint8ArrayFromString  } = require('uint8arrays/from-string');
module.exports = {
    createCipheriv: (mode, key, iv)=>{
        const cipher2 = forge.cipher.createCipher('AES-CTR', uint8ArrayToString(key, 'ascii'));
        cipher2.start({
            iv: uint8ArrayToString(iv, 'ascii')
        });
        return {
            update: (data)=>{
                cipher2.update(forge.util.createBuffer(uint8ArrayToString(data, 'ascii')));
                return uint8ArrayFromString(cipher2.output.getBytes(), 'ascii');
            }
        };
    },
    createDecipheriv: (mode, key, iv)=>{
        const cipher2 = forge.cipher.createDecipher('AES-CTR', uint8ArrayToString(key, 'ascii'));
        cipher2.start({
            iv: uint8ArrayToString(iv, 'ascii')
        });
        return {
            update: (data)=>{
                cipher2.update(forge.util.createBuffer(uint8ArrayToString(data, 'ascii')));
                return uint8ArrayFromString(cipher2.output.getBytes(), 'ascii');
            }
        };
    }
};

},{"node-forge/lib/aes":"jgIby","node-forge/lib/forge":"7AnVp","uint8arrays/to-string":"g3mCQ","uint8arrays/from-string":"lo45E"}],"5Iu8s":[function(require,module,exports) {
'use strict';
const errcode = require('err-code');
const CIPHER_MODES = {
    16: 'aes-128-ctr',
    32: 'aes-256-ctr'
};
module.exports = function(key) {
    const mode = CIPHER_MODES[key.length];
    if (!mode) {
        const modes = Object.entries(CIPHER_MODES).map(([k, v])=>`${k} (${v})`
        ).join(' / ');
        throw errcode(new Error(`Invalid key length ${key.length} bytes. Must be ${modes}`), 'ERR_INVALID_KEY_LENGTH');
    }
    return mode;
};

},{"err-code":"eQvyh"}],"cfxLy":[function(require,module,exports) {
'use strict';
const forgePbkdf2 = require('node-forge/lib/pbkdf2');
const forgeUtil = require('node-forge/lib/util');
const errcode = require('err-code');
/**
 * Maps an IPFS hash name to its node-forge equivalent.
 *
 * See https://github.com/multiformats/multihash/blob/master/hashtable.csv
 *
 * @private
 */ const hashName = {
    sha1: 'sha1',
    'sha2-256': 'sha256',
    'sha2-512': 'sha512'
};
/**
 * Computes the Password-Based Key Derivation Function 2.
 *
 * @param {string} password
 * @param {string} salt
 * @param {number} iterations
 * @param {number} keySize - (in bytes)
 * @param {string} hash - The hash name ('sha1', 'sha2-512, ...)
 * @returns {string} - A new password
 */ function pbkdf2(password, salt, iterations, keySize, hash) {
    const hasher = hashName[hash];
    if (!hasher) {
        const types = Object.keys(hashName).join(' / ');
        throw errcode(new Error(`Hash '${hash}' is unknown or not supported. Must be ${types}`), 'ERR_UNSUPPORTED_HASH_TYPE');
    }
    const dek = forgePbkdf2(password, salt, iterations, keySize, hasher);
    return forgeUtil.encode64(dek);
}
module.exports = pbkdf2;

},{"node-forge/lib/pbkdf2":"j4d8T","node-forge/lib/util":"cHj6b","err-code":"eQvyh"}],"5EBlW":[function(require,module,exports) {
module.exports = Long;
/**
 * wasm optimizations, to do native i64 multiplication and divide
 */ var wasm = null;
try {
    wasm = new WebAssembly.Instance(new WebAssembly.Module(new Uint8Array([
        0,
        97,
        115,
        109,
        1,
        0,
        0,
        0,
        1,
        13,
        2,
        96,
        0,
        1,
        127,
        96,
        4,
        127,
        127,
        127,
        127,
        1,
        127,
        3,
        7,
        6,
        0,
        1,
        1,
        1,
        1,
        1,
        6,
        6,
        1,
        127,
        1,
        65,
        0,
        11,
        7,
        50,
        6,
        3,
        109,
        117,
        108,
        0,
        1,
        5,
        100,
        105,
        118,
        95,
        115,
        0,
        2,
        5,
        100,
        105,
        118,
        95,
        117,
        0,
        3,
        5,
        114,
        101,
        109,
        95,
        115,
        0,
        4,
        5,
        114,
        101,
        109,
        95,
        117,
        0,
        5,
        8,
        103,
        101,
        116,
        95,
        104,
        105,
        103,
        104,
        0,
        0,
        10,
        191,
        1,
        6,
        4,
        0,
        35,
        0,
        11,
        36,
        1,
        1,
        126,
        32,
        0,
        173,
        32,
        1,
        173,
        66,
        32,
        134,
        132,
        32,
        2,
        173,
        32,
        3,
        173,
        66,
        32,
        134,
        132,
        126,
        34,
        4,
        66,
        32,
        135,
        167,
        36,
        0,
        32,
        4,
        167,
        11,
        36,
        1,
        1,
        126,
        32,
        0,
        173,
        32,
        1,
        173,
        66,
        32,
        134,
        132,
        32,
        2,
        173,
        32,
        3,
        173,
        66,
        32,
        134,
        132,
        127,
        34,
        4,
        66,
        32,
        135,
        167,
        36,
        0,
        32,
        4,
        167,
        11,
        36,
        1,
        1,
        126,
        32,
        0,
        173,
        32,
        1,
        173,
        66,
        32,
        134,
        132,
        32,
        2,
        173,
        32,
        3,
        173,
        66,
        32,
        134,
        132,
        128,
        34,
        4,
        66,
        32,
        135,
        167,
        36,
        0,
        32,
        4,
        167,
        11,
        36,
        1,
        1,
        126,
        32,
        0,
        173,
        32,
        1,
        173,
        66,
        32,
        134,
        132,
        32,
        2,
        173,
        32,
        3,
        173,
        66,
        32,
        134,
        132,
        129,
        34,
        4,
        66,
        32,
        135,
        167,
        36,
        0,
        32,
        4,
        167,
        11,
        36,
        1,
        1,
        126,
        32,
        0,
        173,
        32,
        1,
        173,
        66,
        32,
        134,
        132,
        32,
        2,
        173,
        32,
        3,
        173,
        66,
        32,
        134,
        132,
        130,
        34,
        4,
        66,
        32,
        135,
        167,
        36,
        0,
        32,
        4,
        167,
        11
    ])), {
    }).exports;
} catch (e) {
// no wasm support :(
}
/**
 * Constructs a 64 bit two's-complement integer, given its low and high 32 bit values as *signed* integers.
 *  See the from* functions below for more convenient ways of constructing Longs.
 * @exports Long
 * @class A Long class for representing a 64 bit two's-complement integer value.
 * @param {number} low The low (signed) 32 bits of the long
 * @param {number} high The high (signed) 32 bits of the long
 * @param {boolean=} unsigned Whether unsigned or not, defaults to signed
 * @constructor
 */ function Long(low, high, unsigned) {
    /**
     * The low 32 bits as a signed value.
     * @type {number}
     */ this.low = low | 0;
    /**
     * The high 32 bits as a signed value.
     * @type {number}
     */ this.high = high | 0;
    /**
     * Whether unsigned or not.
     * @type {boolean}
     */ this.unsigned = !!unsigned;
}
// The internal representation of a long is the two given signed, 32-bit values.
// We use 32-bit pieces because these are the size of integers on which
// Javascript performs bit-operations.  For operations like addition and
// multiplication, we split each number into 16 bit pieces, which can easily be
// multiplied within Javascript's floating-point representation without overflow
// or change in sign.
//
// In the algorithms below, we frequently reduce the negative case to the
// positive case by negating the input(s) and then post-processing the result.
// Note that we must ALWAYS check specially whether those values are MIN_VALUE
// (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as
// a positive number, it overflows back into a negative).  Not handling this
// case would often result in infinite recursion.
//
// Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the from*
// methods on which they depend.
/**
 * An indicator used to reliably determine if an object is a Long or not.
 * @type {boolean}
 * @const
 * @private
 */ Long.prototype.__isLong__;
Object.defineProperty(Long.prototype, "__isLong__", {
    value: true
});
/**
 * @function
 * @param {*} obj Object
 * @returns {boolean}
 * @inner
 */ function isLong(obj) {
    return (obj && obj["__isLong__"]) === true;
}
/**
 * Tests if the specified object is a Long.
 * @function
 * @param {*} obj Object
 * @returns {boolean}
 */ Long.isLong = isLong;
/**
 * A cache of the Long representations of small integer values.
 * @type {!Object}
 * @inner
 */ var INT_CACHE = {
};
/**
 * A cache of the Long representations of small unsigned integer values.
 * @type {!Object}
 * @inner
 */ var UINT_CACHE = {
};
/**
 * @param {number} value
 * @param {boolean=} unsigned
 * @returns {!Long}
 * @inner
 */ function fromInt(value, unsigned) {
    var obj, cachedObj, cache;
    if (unsigned) {
        value >>>= 0;
        if (cache = 0 <= value && value < 256) {
            cachedObj = UINT_CACHE[value];
            if (cachedObj) return cachedObj;
        }
        obj = fromBits(value, (value | 0) < 0 ? -1 : 0, true);
        if (cache) UINT_CACHE[value] = obj;
        return obj;
    } else {
        value |= 0;
        if (cache = -128 <= value && value < 128) {
            cachedObj = INT_CACHE[value];
            if (cachedObj) return cachedObj;
        }
        obj = fromBits(value, value < 0 ? -1 : 0, false);
        if (cache) INT_CACHE[value] = obj;
        return obj;
    }
}
/**
 * Returns a Long representing the given 32 bit integer value.
 * @function
 * @param {number} value The 32 bit integer in question
 * @param {boolean=} unsigned Whether unsigned or not, defaults to signed
 * @returns {!Long} The corresponding Long value
 */ Long.fromInt = fromInt;
/**
 * @param {number} value
 * @param {boolean=} unsigned
 * @returns {!Long}
 * @inner
 */ function fromNumber(value, unsigned) {
    if (isNaN(value)) return unsigned ? UZERO : ZERO;
    if (unsigned) {
        if (value < 0) return UZERO;
        if (value >= TWO_PWR_64_DBL) return MAX_UNSIGNED_VALUE;
    } else {
        if (value <= -TWO_PWR_63_DBL) return MIN_VALUE;
        if (value + 1 >= TWO_PWR_63_DBL) return MAX_VALUE;
    }
    if (value < 0) return fromNumber(-value, unsigned).neg();
    return fromBits(value % TWO_PWR_32_DBL | 0, value / TWO_PWR_32_DBL | 0, unsigned);
}
/**
 * Returns a Long representing the given value, provided that it is a finite number. Otherwise, zero is returned.
 * @function
 * @param {number} value The number in question
 * @param {boolean=} unsigned Whether unsigned or not, defaults to signed
 * @returns {!Long} The corresponding Long value
 */ Long.fromNumber = fromNumber;
/**
 * @param {number} lowBits
 * @param {number} highBits
 * @param {boolean=} unsigned
 * @returns {!Long}
 * @inner
 */ function fromBits(lowBits, highBits, unsigned) {
    return new Long(lowBits, highBits, unsigned);
}
/**
 * Returns a Long representing the 64 bit integer that comes by concatenating the given low and high bits. Each is
 *  assumed to use 32 bits.
 * @function
 * @param {number} lowBits The low 32 bits
 * @param {number} highBits The high 32 bits
 * @param {boolean=} unsigned Whether unsigned or not, defaults to signed
 * @returns {!Long} The corresponding Long value
 */ Long.fromBits = fromBits;
/**
 * @function
 * @param {number} base
 * @param {number} exponent
 * @returns {number}
 * @inner
 */ var pow_dbl = Math.pow; // Used 4 times (4*8 to 15+4)
/**
 * @param {string} str
 * @param {(boolean|number)=} unsigned
 * @param {number=} radix
 * @returns {!Long}
 * @inner
 */ function fromString(str, unsigned, radix) {
    if (str.length === 0) throw Error('empty string');
    if (str === "NaN" || str === "Infinity" || str === "+Infinity" || str === "-Infinity") return ZERO;
    if (typeof unsigned === 'number') // For goog.math.long compatibility
    radix = unsigned, unsigned = false;
    else unsigned = !!unsigned;
    radix = radix || 10;
    if (radix < 2 || 36 < radix) throw RangeError('radix');
    var p;
    if ((p = str.indexOf('-')) > 0) throw Error('interior hyphen');
    else if (p === 0) return fromString(str.substring(1), unsigned, radix).neg();
    // Do several (8) digits each time through the loop, so as to
    // minimize the calls to the very expensive emulated div.
    var radixToPower = fromNumber(pow_dbl(radix, 8));
    var result = ZERO;
    for(var i = 0; i < str.length; i += 8){
        var size = Math.min(8, str.length - i), value = parseInt(str.substring(i, i + size), radix);
        if (size < 8) {
            var power = fromNumber(pow_dbl(radix, size));
            result = result.mul(power).add(fromNumber(value));
        } else {
            result = result.mul(radixToPower);
            result = result.add(fromNumber(value));
        }
    }
    result.unsigned = unsigned;
    return result;
}
/**
 * Returns a Long representation of the given string, written using the specified radix.
 * @function
 * @param {string} str The textual representation of the Long
 * @param {(boolean|number)=} unsigned Whether unsigned or not, defaults to signed
 * @param {number=} radix The radix in which the text is written (2-36), defaults to 10
 * @returns {!Long} The corresponding Long value
 */ Long.fromString = fromString;
/**
 * @function
 * @param {!Long|number|string|!{low: number, high: number, unsigned: boolean}} val
 * @param {boolean=} unsigned
 * @returns {!Long}
 * @inner
 */ function fromValue(val, unsigned) {
    if (typeof val === 'number') return fromNumber(val, unsigned);
    if (typeof val === 'string') return fromString(val, unsigned);
    // Throws for non-objects, converts non-instanceof Long:
    return fromBits(val.low, val.high, typeof unsigned === 'boolean' ? unsigned : val.unsigned);
}
/**
 * Converts the specified value to a Long using the appropriate from* function for its type.
 * @function
 * @param {!Long|number|string|!{low: number, high: number, unsigned: boolean}} val Value
 * @param {boolean=} unsigned Whether unsigned or not, defaults to signed
 * @returns {!Long}
 */ Long.fromValue = fromValue;
// NOTE: the compiler should inline these constant values below and then remove these variables, so there should be
// no runtime penalty for these.
/**
 * @type {number}
 * @const
 * @inner
 */ var TWO_PWR_16_DBL = 65536;
/**
 * @type {number}
 * @const
 * @inner
 */ var TWO_PWR_24_DBL = 16777216;
/**
 * @type {number}
 * @const
 * @inner
 */ var TWO_PWR_32_DBL = TWO_PWR_16_DBL * TWO_PWR_16_DBL;
/**
 * @type {number}
 * @const
 * @inner
 */ var TWO_PWR_64_DBL = TWO_PWR_32_DBL * TWO_PWR_32_DBL;
/**
 * @type {number}
 * @const
 * @inner
 */ var TWO_PWR_63_DBL = TWO_PWR_64_DBL / 2;
/**
 * @type {!Long}
 * @const
 * @inner
 */ var TWO_PWR_24 = fromInt(TWO_PWR_24_DBL);
/**
 * @type {!Long}
 * @inner
 */ var ZERO = fromInt(0);
/**
 * Signed zero.
 * @type {!Long}
 */ Long.ZERO = ZERO;
/**
 * @type {!Long}
 * @inner
 */ var UZERO = fromInt(0, true);
/**
 * Unsigned zero.
 * @type {!Long}
 */ Long.UZERO = UZERO;
/**
 * @type {!Long}
 * @inner
 */ var ONE = fromInt(1);
/**
 * Signed one.
 * @type {!Long}
 */ Long.ONE = ONE;
/**
 * @type {!Long}
 * @inner
 */ var UONE = fromInt(1, true);
/**
 * Unsigned one.
 * @type {!Long}
 */ Long.UONE = UONE;
/**
 * @type {!Long}
 * @inner
 */ var NEG_ONE = fromInt(-1);
/**
 * Signed negative one.
 * @type {!Long}
 */ Long.NEG_ONE = NEG_ONE;
/**
 * @type {!Long}
 * @inner
 */ var MAX_VALUE = fromBits(-1, 2147483647, false);
/**
 * Maximum signed value.
 * @type {!Long}
 */ Long.MAX_VALUE = MAX_VALUE;
/**
 * @type {!Long}
 * @inner
 */ var MAX_UNSIGNED_VALUE = fromBits(-1, -1, true);
/**
 * Maximum unsigned value.
 * @type {!Long}
 */ Long.MAX_UNSIGNED_VALUE = MAX_UNSIGNED_VALUE;
/**
 * @type {!Long}
 * @inner
 */ var MIN_VALUE = fromBits(0, -2147483648, false);
/**
 * Minimum signed value.
 * @type {!Long}
 */ Long.MIN_VALUE = MIN_VALUE;
/**
 * @alias Long.prototype
 * @inner
 */ var LongPrototype = Long.prototype;
/**
 * Converts the Long to a 32 bit integer, assuming it is a 32 bit integer.
 * @returns {number}
 */ LongPrototype.toInt = function toInt() {
    return this.unsigned ? this.low >>> 0 : this.low;
};
/**
 * Converts the Long to a the nearest floating-point representation of this value (double, 53 bit mantissa).
 * @returns {number}
 */ LongPrototype.toNumber = function toNumber() {
    if (this.unsigned) return (this.high >>> 0) * TWO_PWR_32_DBL + (this.low >>> 0);
    return this.high * TWO_PWR_32_DBL + (this.low >>> 0);
};
/**
 * Converts the Long to a string written in the specified radix.
 * @param {number=} radix Radix (2-36), defaults to 10
 * @returns {string}
 * @override
 * @throws {RangeError} If `radix` is out of range
 */ LongPrototype.toString = function toString(radix) {
    radix = radix || 10;
    if (radix < 2 || 36 < radix) throw RangeError('radix');
    if (this.isZero()) return '0';
    if (this.isNegative()) {
        if (this.eq(MIN_VALUE)) {
            // We need to change the Long value before it can be negated, so we remove
            // the bottom-most digit in this base and then recurse to do the rest.
            var radixLong = fromNumber(radix), div = this.div(radixLong), rem1 = div.mul(radixLong).sub(this);
            return div.toString(radix) + rem1.toInt().toString(radix);
        } else return '-' + this.neg().toString(radix);
    }
    // Do several (6) digits each time through the loop, so as to
    // minimize the calls to the very expensive emulated div.
    var radixToPower = fromNumber(pow_dbl(radix, 6), this.unsigned), rem = this;
    var result = '';
    while(true){
        var remDiv = rem.div(radixToPower), intval = rem.sub(remDiv.mul(radixToPower)).toInt() >>> 0, digits = intval.toString(radix);
        rem = remDiv;
        if (rem.isZero()) return digits + result;
        else {
            while(digits.length < 6)digits = '0' + digits;
            result = '' + digits + result;
        }
    }
};
/**
 * Gets the high 32 bits as a signed integer.
 * @returns {number} Signed high bits
 */ LongPrototype.getHighBits = function getHighBits() {
    return this.high;
};
/**
 * Gets the high 32 bits as an unsigned integer.
 * @returns {number} Unsigned high bits
 */ LongPrototype.getHighBitsUnsigned = function getHighBitsUnsigned() {
    return this.high >>> 0;
};
/**
 * Gets the low 32 bits as a signed integer.
 * @returns {number} Signed low bits
 */ LongPrototype.getLowBits = function getLowBits() {
    return this.low;
};
/**
 * Gets the low 32 bits as an unsigned integer.
 * @returns {number} Unsigned low bits
 */ LongPrototype.getLowBitsUnsigned = function getLowBitsUnsigned() {
    return this.low >>> 0;
};
/**
 * Gets the number of bits needed to represent the absolute value of this Long.
 * @returns {number}
 */ LongPrototype.getNumBitsAbs = function getNumBitsAbs() {
    if (this.isNegative()) return this.eq(MIN_VALUE) ? 64 : this.neg().getNumBitsAbs();
    var val = this.high != 0 ? this.high : this.low;
    for(var bit = 31; bit > 0; bit--)if ((val & 1 << bit) != 0) break;
    return this.high != 0 ? bit + 33 : bit + 1;
};
/**
 * Tests if this Long's value equals zero.
 * @returns {boolean}
 */ LongPrototype.isZero = function isZero() {
    return this.high === 0 && this.low === 0;
};
/**
 * Tests if this Long's value equals zero. This is an alias of {@link Long#isZero}.
 * @returns {boolean}
 */ LongPrototype.eqz = LongPrototype.isZero;
/**
 * Tests if this Long's value is negative.
 * @returns {boolean}
 */ LongPrototype.isNegative = function isNegative() {
    return !this.unsigned && this.high < 0;
};
/**
 * Tests if this Long's value is positive.
 * @returns {boolean}
 */ LongPrototype.isPositive = function isPositive() {
    return this.unsigned || this.high >= 0;
};
/**
 * Tests if this Long's value is odd.
 * @returns {boolean}
 */ LongPrototype.isOdd = function isOdd() {
    return (this.low & 1) === 1;
};
/**
 * Tests if this Long's value is even.
 * @returns {boolean}
 */ LongPrototype.isEven = function isEven() {
    return (this.low & 1) === 0;
};
/**
 * Tests if this Long's value equals the specified's.
 * @param {!Long|number|string} other Other value
 * @returns {boolean}
 */ LongPrototype.equals = function equals(other) {
    if (!isLong(other)) other = fromValue(other);
    if (this.unsigned !== other.unsigned && this.high >>> 31 === 1 && other.high >>> 31 === 1) return false;
    return this.high === other.high && this.low === other.low;
};
/**
 * Tests if this Long's value equals the specified's. This is an alias of {@link Long#equals}.
 * @function
 * @param {!Long|number|string} other Other value
 * @returns {boolean}
 */ LongPrototype.eq = LongPrototype.equals;
/**
 * Tests if this Long's value differs from the specified's.
 * @param {!Long|number|string} other Other value
 * @returns {boolean}
 */ LongPrototype.notEquals = function notEquals(other) {
    return !this.eq(/* validates */ other);
};
/**
 * Tests if this Long's value differs from the specified's. This is an alias of {@link Long#notEquals}.
 * @function
 * @param {!Long|number|string} other Other value
 * @returns {boolean}
 */ LongPrototype.neq = LongPrototype.notEquals;
/**
 * Tests if this Long's value differs from the specified's. This is an alias of {@link Long#notEquals}.
 * @function
 * @param {!Long|number|string} other Other value
 * @returns {boolean}
 */ LongPrototype.ne = LongPrototype.notEquals;
/**
 * Tests if this Long's value is less than the specified's.
 * @param {!Long|number|string} other Other value
 * @returns {boolean}
 */ LongPrototype.lessThan = function lessThan(other) {
    return this.comp(/* validates */ other) < 0;
};
/**
 * Tests if this Long's value is less than the specified's. This is an alias of {@link Long#lessThan}.
 * @function
 * @param {!Long|number|string} other Other value
 * @returns {boolean}
 */ LongPrototype.lt = LongPrototype.lessThan;
/**
 * Tests if this Long's value is less than or equal the specified's.
 * @param {!Long|number|string} other Other value
 * @returns {boolean}
 */ LongPrototype.lessThanOrEqual = function lessThanOrEqual(other) {
    return this.comp(/* validates */ other) <= 0;
};
/**
 * Tests if this Long's value is less than or equal the specified's. This is an alias of {@link Long#lessThanOrEqual}.
 * @function
 * @param {!Long|number|string} other Other value
 * @returns {boolean}
 */ LongPrototype.lte = LongPrototype.lessThanOrEqual;
/**
 * Tests if this Long's value is less than or equal the specified's. This is an alias of {@link Long#lessThanOrEqual}.
 * @function
 * @param {!Long|number|string} other Other value
 * @returns {boolean}
 */ LongPrototype.le = LongPrototype.lessThanOrEqual;
/**
 * Tests if this Long's value is greater than the specified's.
 * @param {!Long|number|string} other Other value
 * @returns {boolean}
 */ LongPrototype.greaterThan = function greaterThan(other) {
    return this.comp(/* validates */ other) > 0;
};
/**
 * Tests if this Long's value is greater than the specified's. This is an alias of {@link Long#greaterThan}.
 * @function
 * @param {!Long|number|string} other Other value
 * @returns {boolean}
 */ LongPrototype.gt = LongPrototype.greaterThan;
/**
 * Tests if this Long's value is greater than or equal the specified's.
 * @param {!Long|number|string} other Other value
 * @returns {boolean}
 */ LongPrototype.greaterThanOrEqual = function greaterThanOrEqual(other) {
    return this.comp(/* validates */ other) >= 0;
};
/**
 * Tests if this Long's value is greater than or equal the specified's. This is an alias of {@link Long#greaterThanOrEqual}.
 * @function
 * @param {!Long|number|string} other Other value
 * @returns {boolean}
 */ LongPrototype.gte = LongPrototype.greaterThanOrEqual;
/**
 * Tests if this Long's value is greater than or equal the specified's. This is an alias of {@link Long#greaterThanOrEqual}.
 * @function
 * @param {!Long|number|string} other Other value
 * @returns {boolean}
 */ LongPrototype.ge = LongPrototype.greaterThanOrEqual;
/**
 * Compares this Long's value with the specified's.
 * @param {!Long|number|string} other Other value
 * @returns {number} 0 if they are the same, 1 if the this is greater and -1
 *  if the given one is greater
 */ LongPrototype.compare = function compare(other) {
    if (!isLong(other)) other = fromValue(other);
    if (this.eq(other)) return 0;
    var thisNeg = this.isNegative(), otherNeg = other.isNegative();
    if (thisNeg && !otherNeg) return -1;
    if (!thisNeg && otherNeg) return 1;
    // At this point the sign bits are the same
    if (!this.unsigned) return this.sub(other).isNegative() ? -1 : 1;
    // Both are positive if at least one is unsigned
    return other.high >>> 0 > this.high >>> 0 || other.high === this.high && other.low >>> 0 > this.low >>> 0 ? -1 : 1;
};
/**
 * Compares this Long's value with the specified's. This is an alias of {@link Long#compare}.
 * @function
 * @param {!Long|number|string} other Other value
 * @returns {number} 0 if they are the same, 1 if the this is greater and -1
 *  if the given one is greater
 */ LongPrototype.comp = LongPrototype.compare;
/**
 * Negates this Long's value.
 * @returns {!Long} Negated Long
 */ LongPrototype.negate = function negate() {
    if (!this.unsigned && this.eq(MIN_VALUE)) return MIN_VALUE;
    return this.not().add(ONE);
};
/**
 * Negates this Long's value. This is an alias of {@link Long#negate}.
 * @function
 * @returns {!Long} Negated Long
 */ LongPrototype.neg = LongPrototype.negate;
/**
 * Returns the sum of this and the specified Long.
 * @param {!Long|number|string} addend Addend
 * @returns {!Long} Sum
 */ LongPrototype.add = function add(addend) {
    if (!isLong(addend)) addend = fromValue(addend);
    // Divide each number into 4 chunks of 16 bits, and then sum the chunks.
    var a48 = this.high >>> 16;
    var a32 = this.high & 65535;
    var a16 = this.low >>> 16;
    var a00 = this.low & 65535;
    var b48 = addend.high >>> 16;
    var b32 = addend.high & 65535;
    var b16 = addend.low >>> 16;
    var b00 = addend.low & 65535;
    var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
    c00 += a00 + b00;
    c16 += c00 >>> 16;
    c00 &= 65535;
    c16 += a16 + b16;
    c32 += c16 >>> 16;
    c16 &= 65535;
    c32 += a32 + b32;
    c48 += c32 >>> 16;
    c32 &= 65535;
    c48 += a48 + b48;
    c48 &= 65535;
    return fromBits(c16 << 16 | c00, c48 << 16 | c32, this.unsigned);
};
/**
 * Returns the difference of this and the specified Long.
 * @param {!Long|number|string} subtrahend Subtrahend
 * @returns {!Long} Difference
 */ LongPrototype.subtract = function subtract(subtrahend) {
    if (!isLong(subtrahend)) subtrahend = fromValue(subtrahend);
    return this.add(subtrahend.neg());
};
/**
 * Returns the difference of this and the specified Long. This is an alias of {@link Long#subtract}.
 * @function
 * @param {!Long|number|string} subtrahend Subtrahend
 * @returns {!Long} Difference
 */ LongPrototype.sub = LongPrototype.subtract;
/**
 * Returns the product of this and the specified Long.
 * @param {!Long|number|string} multiplier Multiplier
 * @returns {!Long} Product
 */ LongPrototype.multiply = function multiply(multiplier) {
    if (this.isZero()) return ZERO;
    if (!isLong(multiplier)) multiplier = fromValue(multiplier);
    // use wasm support if present
    if (wasm) {
        var low = wasm.mul(this.low, this.high, multiplier.low, multiplier.high);
        return fromBits(low, wasm.get_high(), this.unsigned);
    }
    if (multiplier.isZero()) return ZERO;
    if (this.eq(MIN_VALUE)) return multiplier.isOdd() ? MIN_VALUE : ZERO;
    if (multiplier.eq(MIN_VALUE)) return this.isOdd() ? MIN_VALUE : ZERO;
    if (this.isNegative()) {
        if (multiplier.isNegative()) return this.neg().mul(multiplier.neg());
        else return this.neg().mul(multiplier).neg();
    } else if (multiplier.isNegative()) return this.mul(multiplier.neg()).neg();
    // If both longs are small, use float multiplication
    if (this.lt(TWO_PWR_24) && multiplier.lt(TWO_PWR_24)) return fromNumber(this.toNumber() * multiplier.toNumber(), this.unsigned);
    // Divide each long into 4 chunks of 16 bits, and then add up 4x4 products.
    // We can skip products that would overflow.
    var a48 = this.high >>> 16;
    var a32 = this.high & 65535;
    var a16 = this.low >>> 16;
    var a00 = this.low & 65535;
    var b48 = multiplier.high >>> 16;
    var b32 = multiplier.high & 65535;
    var b16 = multiplier.low >>> 16;
    var b00 = multiplier.low & 65535;
    var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
    c00 += a00 * b00;
    c16 += c00 >>> 16;
    c00 &= 65535;
    c16 += a16 * b00;
    c32 += c16 >>> 16;
    c16 &= 65535;
    c16 += a00 * b16;
    c32 += c16 >>> 16;
    c16 &= 65535;
    c32 += a32 * b00;
    c48 += c32 >>> 16;
    c32 &= 65535;
    c32 += a16 * b16;
    c48 += c32 >>> 16;
    c32 &= 65535;
    c32 += a00 * b32;
    c48 += c32 >>> 16;
    c32 &= 65535;
    c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48;
    c48 &= 65535;
    return fromBits(c16 << 16 | c00, c48 << 16 | c32, this.unsigned);
};
/**
 * Returns the product of this and the specified Long. This is an alias of {@link Long#multiply}.
 * @function
 * @param {!Long|number|string} multiplier Multiplier
 * @returns {!Long} Product
 */ LongPrototype.mul = LongPrototype.multiply;
/**
 * Returns this Long divided by the specified. The result is signed if this Long is signed or
 *  unsigned if this Long is unsigned.
 * @param {!Long|number|string} divisor Divisor
 * @returns {!Long} Quotient
 */ LongPrototype.divide = function divide(divisor) {
    if (!isLong(divisor)) divisor = fromValue(divisor);
    if (divisor.isZero()) throw Error('division by zero');
    // use wasm support if present
    if (wasm) {
        // guard against signed division overflow: the largest
        // negative number / -1 would be 1 larger than the largest
        // positive number, due to two's complement.
        if (!this.unsigned && this.high === -2147483648 && divisor.low === -1 && divisor.high === -1) // be consistent with non-wasm code path
        return this;
        var low = (this.unsigned ? wasm.div_u : wasm.div_s)(this.low, this.high, divisor.low, divisor.high);
        return fromBits(low, wasm.get_high(), this.unsigned);
    }
    if (this.isZero()) return this.unsigned ? UZERO : ZERO;
    var approx, rem, res;
    if (!this.unsigned) {
        // This section is only relevant for signed longs and is derived from the
        // closure library as a whole.
        if (this.eq(MIN_VALUE)) {
            if (divisor.eq(ONE) || divisor.eq(NEG_ONE)) return MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE
            else if (divisor.eq(MIN_VALUE)) return ONE;
            else {
                // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|.
                var halfThis = this.shr(1);
                approx = halfThis.div(divisor).shl(1);
                if (approx.eq(ZERO)) return divisor.isNegative() ? ONE : NEG_ONE;
                else {
                    rem = this.sub(divisor.mul(approx));
                    res = approx.add(rem.div(divisor));
                    return res;
                }
            }
        } else if (divisor.eq(MIN_VALUE)) return this.unsigned ? UZERO : ZERO;
        if (this.isNegative()) {
            if (divisor.isNegative()) return this.neg().div(divisor.neg());
            return this.neg().div(divisor).neg();
        } else if (divisor.isNegative()) return this.div(divisor.neg()).neg();
        res = ZERO;
    } else {
        // The algorithm below has not been made for unsigned longs. It's therefore
        // required to take special care of the MSB prior to running it.
        if (!divisor.unsigned) divisor = divisor.toUnsigned();
        if (divisor.gt(this)) return UZERO;
        if (divisor.gt(this.shru(1))) return UONE;
        res = UZERO;
    }
    // Repeat the following until the remainder is less than other:  find a
    // floating-point that approximates remainder / other *from below*, add this
    // into the result, and subtract it from the remainder.  It is critical that
    // the approximate value is less than or equal to the real value so that the
    // remainder never becomes negative.
    rem = this;
    while(rem.gte(divisor)){
        // Approximate the result of division. This may be a little greater or
        // smaller than the actual value.
        approx = Math.max(1, Math.floor(rem.toNumber() / divisor.toNumber()));
        // We will tweak the approximate result by changing it in the 48-th digit or
        // the smallest non-fractional digit, whichever is larger.
        var log2 = Math.ceil(Math.log(approx) / Math.LN2), delta = log2 <= 48 ? 1 : pow_dbl(2, log2 - 48), // Decrease the approximation until it is smaller than the remainder.  Note
        // that if it is too large, the product overflows and is negative.
        approxRes = fromNumber(approx), approxRem = approxRes.mul(divisor);
        while(approxRem.isNegative() || approxRem.gt(rem)){
            approx -= delta;
            approxRes = fromNumber(approx, this.unsigned);
            approxRem = approxRes.mul(divisor);
        }
        // We know the answer can't be zero... and actually, zero would cause
        // infinite recursion since we would make no progress.
        if (approxRes.isZero()) approxRes = ONE;
        res = res.add(approxRes);
        rem = rem.sub(approxRem);
    }
    return res;
};
/**
 * Returns this Long divided by the specified. This is an alias of {@link Long#divide}.
 * @function
 * @param {!Long|number|string} divisor Divisor
 * @returns {!Long} Quotient
 */ LongPrototype.div = LongPrototype.divide;
/**
 * Returns this Long modulo the specified.
 * @param {!Long|number|string} divisor Divisor
 * @returns {!Long} Remainder
 */ LongPrototype.modulo = function modulo(divisor) {
    if (!isLong(divisor)) divisor = fromValue(divisor);
    // use wasm support if present
    if (wasm) {
        var low = (this.unsigned ? wasm.rem_u : wasm.rem_s)(this.low, this.high, divisor.low, divisor.high);
        return fromBits(low, wasm.get_high(), this.unsigned);
    }
    return this.sub(this.div(divisor).mul(divisor));
};
/**
 * Returns this Long modulo the specified. This is an alias of {@link Long#modulo}.
 * @function
 * @param {!Long|number|string} divisor Divisor
 * @returns {!Long} Remainder
 */ LongPrototype.mod = LongPrototype.modulo;
/**
 * Returns this Long modulo the specified. This is an alias of {@link Long#modulo}.
 * @function
 * @param {!Long|number|string} divisor Divisor
 * @returns {!Long} Remainder
 */ LongPrototype.rem = LongPrototype.modulo;
/**
 * Returns the bitwise NOT of this Long.
 * @returns {!Long}
 */ LongPrototype.not = function not() {
    return fromBits(~this.low, ~this.high, this.unsigned);
};
/**
 * Returns the bitwise AND of this Long and the specified.
 * @param {!Long|number|string} other Other Long
 * @returns {!Long}
 */ LongPrototype.and = function and(other) {
    if (!isLong(other)) other = fromValue(other);
    return fromBits(this.low & other.low, this.high & other.high, this.unsigned);
};
/**
 * Returns the bitwise OR of this Long and the specified.
 * @param {!Long|number|string} other Other Long
 * @returns {!Long}
 */ LongPrototype.or = function or(other) {
    if (!isLong(other)) other = fromValue(other);
    return fromBits(this.low | other.low, this.high | other.high, this.unsigned);
};
/**
 * Returns the bitwise XOR of this Long and the given one.
 * @param {!Long|number|string} other Other Long
 * @returns {!Long}
 */ LongPrototype.xor = function xor(other) {
    if (!isLong(other)) other = fromValue(other);
    return fromBits(this.low ^ other.low, this.high ^ other.high, this.unsigned);
};
/**
 * Returns this Long with bits shifted to the left by the given amount.
 * @param {number|!Long} numBits Number of bits
 * @returns {!Long} Shifted Long
 */ LongPrototype.shiftLeft = function shiftLeft(numBits) {
    if (isLong(numBits)) numBits = numBits.toInt();
    if ((numBits &= 63) === 0) return this;
    else if (numBits < 32) return fromBits(this.low << numBits, this.high << numBits | this.low >>> 32 - numBits, this.unsigned);
    else return fromBits(0, this.low << numBits - 32, this.unsigned);
};
/**
 * Returns this Long with bits shifted to the left by the given amount. This is an alias of {@link Long#shiftLeft}.
 * @function
 * @param {number|!Long} numBits Number of bits
 * @returns {!Long} Shifted Long
 */ LongPrototype.shl = LongPrototype.shiftLeft;
/**
 * Returns this Long with bits arithmetically shifted to the right by the given amount.
 * @param {number|!Long} numBits Number of bits
 * @returns {!Long} Shifted Long
 */ LongPrototype.shiftRight = function shiftRight(numBits) {
    if (isLong(numBits)) numBits = numBits.toInt();
    if ((numBits &= 63) === 0) return this;
    else if (numBits < 32) return fromBits(this.low >>> numBits | this.high << 32 - numBits, this.high >> numBits, this.unsigned);
    else return fromBits(this.high >> numBits - 32, this.high >= 0 ? 0 : -1, this.unsigned);
};
/**
 * Returns this Long with bits arithmetically shifted to the right by the given amount. This is an alias of {@link Long#shiftRight}.
 * @function
 * @param {number|!Long} numBits Number of bits
 * @returns {!Long} Shifted Long
 */ LongPrototype.shr = LongPrototype.shiftRight;
/**
 * Returns this Long with bits logically shifted to the right by the given amount.
 * @param {number|!Long} numBits Number of bits
 * @returns {!Long} Shifted Long
 */ LongPrototype.shiftRightUnsigned = function shiftRightUnsigned(numBits) {
    if (isLong(numBits)) numBits = numBits.toInt();
    numBits &= 63;
    if (numBits === 0) return this;
    else {
        var high = this.high;
        if (numBits < 32) {
            var low = this.low;
            return fromBits(low >>> numBits | high << 32 - numBits, high >>> numBits, this.unsigned);
        } else if (numBits === 32) return fromBits(high, 0, this.unsigned);
        else return fromBits(high >>> numBits - 32, 0, this.unsigned);
    }
};
/**
 * Returns this Long with bits logically shifted to the right by the given amount. This is an alias of {@link Long#shiftRightUnsigned}.
 * @function
 * @param {number|!Long} numBits Number of bits
 * @returns {!Long} Shifted Long
 */ LongPrototype.shru = LongPrototype.shiftRightUnsigned;
/**
 * Returns this Long with bits logically shifted to the right by the given amount. This is an alias of {@link Long#shiftRightUnsigned}.
 * @function
 * @param {number|!Long} numBits Number of bits
 * @returns {!Long} Shifted Long
 */ LongPrototype.shr_u = LongPrototype.shiftRightUnsigned;
/**
 * Converts this Long to signed.
 * @returns {!Long} Signed long
 */ LongPrototype.toSigned = function toSigned() {
    if (!this.unsigned) return this;
    return fromBits(this.low, this.high, false);
};
/**
 * Converts this Long to unsigned.
 * @returns {!Long} Unsigned long
 */ LongPrototype.toUnsigned = function toUnsigned() {
    if (this.unsigned) return this;
    return fromBits(this.low, this.high, true);
};
/**
 * Converts this Long to its byte representation.
 * @param {boolean=} le Whether little or big endian, defaults to big endian
 * @returns {!Array.<number>} Byte representation
 */ LongPrototype.toBytes = function toBytes(le) {
    return le ? this.toBytesLE() : this.toBytesBE();
};
/**
 * Converts this Long to its little endian byte representation.
 * @returns {!Array.<number>} Little endian byte representation
 */ LongPrototype.toBytesLE = function toBytesLE() {
    var hi = this.high, lo = this.low;
    return [
        lo & 255,
        lo >>> 8 & 255,
        lo >>> 16 & 255,
        lo >>> 24,
        hi & 255,
        hi >>> 8 & 255,
        hi >>> 16 & 255,
        hi >>> 24
    ];
};
/**
 * Converts this Long to its big endian byte representation.
 * @returns {!Array.<number>} Big endian byte representation
 */ LongPrototype.toBytesBE = function toBytesBE() {
    var hi = this.high, lo = this.low;
    return [
        hi >>> 24,
        hi >>> 16 & 255,
        hi >>> 8 & 255,
        hi & 255,
        lo >>> 24,
        lo >>> 16 & 255,
        lo >>> 8 & 255,
        lo & 255
    ];
};
/**
 * Creates a Long from its byte representation.
 * @param {!Array.<number>} bytes Byte representation
 * @param {boolean=} unsigned Whether unsigned or not, defaults to signed
 * @param {boolean=} le Whether little or big endian, defaults to big endian
 * @returns {Long} The corresponding Long value
 */ Long.fromBytes = function fromBytes(bytes, unsigned, le) {
    return le ? Long.fromBytesLE(bytes, unsigned) : Long.fromBytesBE(bytes, unsigned);
};
/**
 * Creates a Long from its little endian byte representation.
 * @param {!Array.<number>} bytes Little endian byte representation
 * @param {boolean=} unsigned Whether unsigned or not, defaults to signed
 * @returns {Long} The corresponding Long value
 */ Long.fromBytesLE = function fromBytesLE(bytes, unsigned) {
    return new Long(bytes[0] | bytes[1] << 8 | bytes[2] << 16 | bytes[3] << 24, bytes[4] | bytes[5] << 8 | bytes[6] << 16 | bytes[7] << 24, unsigned);
};
/**
 * Creates a Long from its big endian byte representation.
 * @param {!Array.<number>} bytes Big endian byte representation
 * @param {boolean=} unsigned Whether unsigned or not, defaults to signed
 * @returns {Long} The corresponding Long value
 */ Long.fromBytesBE = function fromBytesBE(bytes, unsigned) {
    return new Long(bytes[4] << 24 | bytes[5] << 16 | bytes[6] << 8 | bytes[7], bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3], unsigned);
};

},{}],"kOLH3":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var $protobuf = require('protobufjs/minimal.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var $protobuf__default = /*#__PURE__*/ _interopDefaultLegacy($protobuf);
const $Reader = $protobuf__default['default'].Reader, $Writer = $protobuf__default['default'].Writer, $util = $protobuf__default['default'].util;
const $root = $protobuf__default['default'].roots['ipfs-ipns'] || ($protobuf__default['default'].roots['ipfs-ipns'] = {
});
const IpnsEntry1 = $root.IpnsEntry = (()=>{
    function IpnsEntry(p) {
        if (p) {
            for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
        }
    }
    IpnsEntry.prototype.value = $util.newBuffer([]);
    IpnsEntry.prototype.signature = $util.newBuffer([]);
    IpnsEntry.prototype.validityType = 0;
    IpnsEntry.prototype.validity = $util.newBuffer([]);
    IpnsEntry.prototype.sequence = $util.Long ? $util.Long.fromBits(0, 0, true) : 0;
    IpnsEntry.prototype.ttl = $util.Long ? $util.Long.fromBits(0, 0, true) : 0;
    IpnsEntry.prototype.pubKey = $util.newBuffer([]);
    IpnsEntry.prototype.signatureV2 = $util.newBuffer([]);
    IpnsEntry.prototype.data = $util.newBuffer([]);
    IpnsEntry.encode = function encode(m, w) {
        if (!w) w = $Writer.create();
        if (m.value != null && Object.hasOwnProperty.call(m, 'value')) w.uint32(10).bytes(m.value);
        if (m.signature != null && Object.hasOwnProperty.call(m, 'signature')) w.uint32(18).bytes(m.signature);
        if (m.validityType != null && Object.hasOwnProperty.call(m, 'validityType')) w.uint32(24).int32(m.validityType);
        if (m.validity != null && Object.hasOwnProperty.call(m, 'validity')) w.uint32(34).bytes(m.validity);
        if (m.sequence != null && Object.hasOwnProperty.call(m, 'sequence')) w.uint32(40).uint64(m.sequence);
        if (m.ttl != null && Object.hasOwnProperty.call(m, 'ttl')) w.uint32(48).uint64(m.ttl);
        if (m.pubKey != null && Object.hasOwnProperty.call(m, 'pubKey')) w.uint32(58).bytes(m.pubKey);
        if (m.signatureV2 != null && Object.hasOwnProperty.call(m, 'signatureV2')) w.uint32(66).bytes(m.signatureV2);
        if (m.data != null && Object.hasOwnProperty.call(m, 'data')) w.uint32(74).bytes(m.data);
        return w;
    };
    IpnsEntry.decode = function decode(r, l) {
        if (!(r instanceof $Reader)) r = $Reader.create(r);
        var c = l === undefined ? r.len : r.pos + l, m = new $root.IpnsEntry();
        while(r.pos < c){
            var t = r.uint32();
            switch(t >>> 3){
                case 1:
                    m.value = r.bytes();
                    break;
                case 2:
                    m.signature = r.bytes();
                    break;
                case 3:
                    m.validityType = r.int32();
                    break;
                case 4:
                    m.validity = r.bytes();
                    break;
                case 5:
                    m.sequence = r.uint64();
                    break;
                case 6:
                    m.ttl = r.uint64();
                    break;
                case 7:
                    m.pubKey = r.bytes();
                    break;
                case 8:
                    m.signatureV2 = r.bytes();
                    break;
                case 9:
                    m.data = r.bytes();
                    break;
                default:
                    r.skipType(t & 7);
                    break;
            }
        }
        return m;
    };
    IpnsEntry.fromObject = function fromObject(d) {
        if (d instanceof $root.IpnsEntry) return d;
        var m = new $root.IpnsEntry();
        if (d.value != null) {
            if (typeof d.value === 'string') $util.base64.decode(d.value, m.value = $util.newBuffer($util.base64.length(d.value)), 0);
            else if (d.value.length) m.value = d.value;
        }
        if (d.signature != null) {
            if (typeof d.signature === 'string') $util.base64.decode(d.signature, m.signature = $util.newBuffer($util.base64.length(d.signature)), 0);
            else if (d.signature.length) m.signature = d.signature;
        }
        switch(d.validityType){
            case 'EOL':
            case 0:
                m.validityType = 0;
                break;
        }
        if (d.validity != null) {
            if (typeof d.validity === 'string') $util.base64.decode(d.validity, m.validity = $util.newBuffer($util.base64.length(d.validity)), 0);
            else if (d.validity.length) m.validity = d.validity;
        }
        if (d.sequence != null) {
            if ($util.Long) (m.sequence = $util.Long.fromValue(d.sequence)).unsigned = true;
            else if (typeof d.sequence === 'string') m.sequence = parseInt(d.sequence, 10);
            else if (typeof d.sequence === 'number') m.sequence = d.sequence;
            else if (typeof d.sequence === 'object') m.sequence = new $util.LongBits(d.sequence.low >>> 0, d.sequence.high >>> 0).toNumber(true);
        }
        if (d.ttl != null) {
            if ($util.Long) (m.ttl = $util.Long.fromValue(d.ttl)).unsigned = true;
            else if (typeof d.ttl === 'string') m.ttl = parseInt(d.ttl, 10);
            else if (typeof d.ttl === 'number') m.ttl = d.ttl;
            else if (typeof d.ttl === 'object') m.ttl = new $util.LongBits(d.ttl.low >>> 0, d.ttl.high >>> 0).toNumber(true);
        }
        if (d.pubKey != null) {
            if (typeof d.pubKey === 'string') $util.base64.decode(d.pubKey, m.pubKey = $util.newBuffer($util.base64.length(d.pubKey)), 0);
            else if (d.pubKey.length) m.pubKey = d.pubKey;
        }
        if (d.signatureV2 != null) {
            if (typeof d.signatureV2 === 'string') $util.base64.decode(d.signatureV2, m.signatureV2 = $util.newBuffer($util.base64.length(d.signatureV2)), 0);
            else if (d.signatureV2.length) m.signatureV2 = d.signatureV2;
        }
        if (d.data != null) {
            if (typeof d.data === 'string') $util.base64.decode(d.data, m.data = $util.newBuffer($util.base64.length(d.data)), 0);
            else if (d.data.length) m.data = d.data;
        }
        return m;
    };
    IpnsEntry.toObject = function toObject(m, o) {
        if (!o) o = {
        };
        var d = {
        };
        if (o.defaults) {
            if (o.bytes === String) d.value = '';
            else {
                d.value = [];
                if (o.bytes !== Array) d.value = $util.newBuffer(d.value);
            }
            if (o.bytes === String) d.signature = '';
            else {
                d.signature = [];
                if (o.bytes !== Array) d.signature = $util.newBuffer(d.signature);
            }
            d.validityType = o.enums === String ? 'EOL' : 0;
            if (o.bytes === String) d.validity = '';
            else {
                d.validity = [];
                if (o.bytes !== Array) d.validity = $util.newBuffer(d.validity);
            }
            if ($util.Long) {
                var n = new $util.Long(0, 0, true);
                d.sequence = o.longs === String ? n.toString() : o.longs === Number ? n.toNumber() : n;
            } else d.sequence = o.longs === String ? '0' : 0;
            if ($util.Long) {
                var n = new $util.Long(0, 0, true);
                d.ttl = o.longs === String ? n.toString() : o.longs === Number ? n.toNumber() : n;
            } else d.ttl = o.longs === String ? '0' : 0;
            if (o.bytes === String) d.pubKey = '';
            else {
                d.pubKey = [];
                if (o.bytes !== Array) d.pubKey = $util.newBuffer(d.pubKey);
            }
            if (o.bytes === String) d.signatureV2 = '';
            else {
                d.signatureV2 = [];
                if (o.bytes !== Array) d.signatureV2 = $util.newBuffer(d.signatureV2);
            }
            if (o.bytes === String) d.data = '';
            else {
                d.data = [];
                if (o.bytes !== Array) d.data = $util.newBuffer(d.data);
            }
        }
        if (m.value != null && m.hasOwnProperty('value')) d.value = o.bytes === String ? $util.base64.encode(m.value, 0, m.value.length) : o.bytes === Array ? Array.prototype.slice.call(m.value) : m.value;
        if (m.signature != null && m.hasOwnProperty('signature')) d.signature = o.bytes === String ? $util.base64.encode(m.signature, 0, m.signature.length) : o.bytes === Array ? Array.prototype.slice.call(m.signature) : m.signature;
        if (m.validityType != null && m.hasOwnProperty('validityType')) d.validityType = o.enums === String ? $root.IpnsEntry.ValidityType[m.validityType] : m.validityType;
        if (m.validity != null && m.hasOwnProperty('validity')) d.validity = o.bytes === String ? $util.base64.encode(m.validity, 0, m.validity.length) : o.bytes === Array ? Array.prototype.slice.call(m.validity) : m.validity;
        if (m.sequence != null && m.hasOwnProperty('sequence')) {
            if (typeof m.sequence === 'number') d.sequence = o.longs === String ? String(m.sequence) : m.sequence;
            else d.sequence = o.longs === String ? $util.Long.prototype.toString.call(m.sequence) : o.longs === Number ? new $util.LongBits(m.sequence.low >>> 0, m.sequence.high >>> 0).toNumber(true) : m.sequence;
        }
        if (m.ttl != null && m.hasOwnProperty('ttl')) {
            if (typeof m.ttl === 'number') d.ttl = o.longs === String ? String(m.ttl) : m.ttl;
            else d.ttl = o.longs === String ? $util.Long.prototype.toString.call(m.ttl) : o.longs === Number ? new $util.LongBits(m.ttl.low >>> 0, m.ttl.high >>> 0).toNumber(true) : m.ttl;
        }
        if (m.pubKey != null && m.hasOwnProperty('pubKey')) d.pubKey = o.bytes === String ? $util.base64.encode(m.pubKey, 0, m.pubKey.length) : o.bytes === Array ? Array.prototype.slice.call(m.pubKey) : m.pubKey;
        if (m.signatureV2 != null && m.hasOwnProperty('signatureV2')) d.signatureV2 = o.bytes === String ? $util.base64.encode(m.signatureV2, 0, m.signatureV2.length) : o.bytes === Array ? Array.prototype.slice.call(m.signatureV2) : m.signatureV2;
        if (m.data != null && m.hasOwnProperty('data')) d.data = o.bytes === String ? $util.base64.encode(m.data, 0, m.data.length) : o.bytes === Array ? Array.prototype.slice.call(m.data) : m.data;
        return d;
    };
    IpnsEntry.prototype.toJSON = function toJSON() {
        return this.constructor.toObject(this, $protobuf__default['default'].util.toJSONOptions);
    };
    IpnsEntry.ValidityType = (function() {
        const valuesById = {
        }, values = Object.create(valuesById);
        values[valuesById[0] = 'EOL'] = 0;
        return values;
    })();
    return IpnsEntry;
})();
exports.IpnsEntry = IpnsEntry1;
exports['default'] = $root;

},{"protobufjs/minimal.js":"9Jmso"}],"dTpAp":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
function toRFC3339(time) {
    const year = time.getUTCFullYear();
    const month = String(time.getUTCMonth() + 1).padStart(2, '0');
    const day = String(time.getUTCDate()).padStart(2, '0');
    const hour = String(time.getUTCHours()).padStart(2, '0');
    const minute = String(time.getUTCMinutes()).padStart(2, '0');
    const seconds = String(time.getUTCSeconds()).padStart(2, '0');
    const milliseconds = time.getUTCMilliseconds();
    const nanoseconds = milliseconds * 1000000;
    return `${year}-${month}-${day}T${hour}:${minute}:${seconds}.${nanoseconds}Z`;
}
function parseRFC3339(time) {
    const rfc3339Matcher = new RegExp("(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})\\.(\\d+)Z");
    const m = String(time).trim().match(rfc3339Matcher);
    if (!m) throw new Error('Invalid format');
    const year = parseInt(m[1], 10);
    const month = parseInt(m[2], 10) - 1;
    const date = parseInt(m[3], 10);
    const hour = parseInt(m[4], 10);
    const minute = parseInt(m[5], 10);
    const second = parseInt(m[6], 10);
    const millisecond = parseInt(m[7].slice(0, -6), 10);
    return new Date(Date.UTC(year, month, date, hour, minute, second, millisecond));
}
exports.parseRFC3339 = parseRFC3339;
exports.toRFC3339 = toRFC3339;

},{}],"habNi":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
const ERR_IPNS_EXPIRED_RECORD = 'ERR_IPNS_EXPIRED_RECORD';
const ERR_UNRECOGNIZED_VALIDITY = 'ERR_UNRECOGNIZED_VALIDITY';
const ERR_SIGNATURE_CREATION = 'ERR_SIGNATURE_CREATION';
const ERR_SIGNATURE_VERIFICATION = 'ERR_SIGNATURE_VERIFICATION';
const ERR_UNRECOGNIZED_FORMAT = 'ERR_UNRECOGNIZED_FORMAT';
const ERR_PEER_ID_FROM_PUBLIC_KEY = 'ERR_PEER_ID_FROM_PUBLIC_KEY';
const ERR_PUBLIC_KEY_FROM_ID = 'ERR_PUBLIC_KEY_FROM_ID';
const ERR_UNDEFINED_PARAMETER = 'ERR_UNDEFINED_PARAMETER';
const ERR_INVALID_RECORD_DATA = 'ERR_INVALID_RECORD_DATA';
const ERR_INVALID_EMBEDDED_KEY = 'ERR_INVALID_EMBEDDED_KEY';
exports.ERR_INVALID_EMBEDDED_KEY = ERR_INVALID_EMBEDDED_KEY;
exports.ERR_INVALID_RECORD_DATA = ERR_INVALID_RECORD_DATA;
exports.ERR_IPNS_EXPIRED_RECORD = ERR_IPNS_EXPIRED_RECORD;
exports.ERR_PEER_ID_FROM_PUBLIC_KEY = ERR_PEER_ID_FROM_PUBLIC_KEY;
exports.ERR_PUBLIC_KEY_FROM_ID = ERR_PUBLIC_KEY_FROM_ID;
exports.ERR_SIGNATURE_CREATION = ERR_SIGNATURE_CREATION;
exports.ERR_SIGNATURE_VERIFICATION = ERR_SIGNATURE_VERIFICATION;
exports.ERR_UNDEFINED_PARAMETER = ERR_UNDEFINED_PARAMETER;
exports.ERR_UNRECOGNIZED_FORMAT = ERR_UNRECOGNIZED_FORMAT;
exports.ERR_UNRECOGNIZED_VALIDITY = ERR_UNRECOGNIZED_VALIDITY;

},{}],"dbOMZ":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var ipns = require('ipns');
var crypto = require('libp2p-crypto');
var PeerId = require('peer-id');
var errCode = require('err-code');
var debug = require('debug');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n['default'] = e;
    return Object.freeze(n);
}
var ipns__namespace = /*#__PURE__*/ _interopNamespace(ipns);
var crypto__default = /*#__PURE__*/ _interopDefaultLegacy(crypto);
var PeerId__default = /*#__PURE__*/ _interopDefaultLegacy(PeerId);
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
const log = Object.assign(debug__default['default']('ipfs:ipns:republisher'), {
    error: debug__default['default']('ipfs:ipns:republisher:error')
});
const minute = 60000;
const hour = 60 * minute;
const defaultBroadcastInterval = 4 * hour;
const defaultRecordLifetime = 24 * hour;
class IpnsRepublisher {
    constructor(publisher, datastore, peerId, keychain, options = {
        pass: ''
    }){
        this._publisher = publisher;
        this._datastore = datastore;
        this._peerId = peerId;
        this._keychain = keychain;
        this._options = options;
        this._republishHandle = null;
    }
    async start() {
        if (this._republishHandle) throw errCode__default['default'](new Error('republisher is already running'), 'ERR_REPUBLISH_ALREADY_RUNNING');
        const republishHandle = {
            _task: null,
            _inflightTask: null,
            _timeoutId: null,
            runPeriodically: (period)=>{
                republishHandle._timeoutId = setTimeout(async ()=>{
                    republishHandle._timeoutId = null;
                    try {
                        republishHandle._inflightTask = republishHandle._task();
                        await republishHandle._inflightTask;
                        if (republishHandle._task) republishHandle.runPeriodically(period);
                    } catch (err) {
                        log.error(err);
                    }
                }, period());
            },
            cancel: async ()=>{
                if (republishHandle._timeoutId != null) clearTimeout(republishHandle._timeoutId);
                republishHandle._task = null;
                await republishHandle._inflightTask;
            }
        };
        const { privKey  } = this._peerId;
        const { pass  } = this._options;
        let firstRun = true;
        republishHandle._task = ()=>this._republishEntries(privKey, pass)
        ;
        republishHandle.runPeriodically(()=>{
            if (firstRun) {
                firstRun = false;
                return this._options.initialBroadcastInterval || minute;
            }
            return this._options.broadcastInterval || defaultBroadcastInterval;
        });
        this._republishHandle = republishHandle;
    }
    async stop() {
        const republishHandle = this._republishHandle;
        if (!republishHandle) throw errCode__default['default'](new Error('republisher is not running'), 'ERR_REPUBLISH_NOT_RUNNING');
        this._republishHandle = null;
        await republishHandle.cancel();
    }
    async _republishEntries(privateKey, pass) {
        try {
            await this._republishEntry(privateKey);
        } catch (err) {
            const errMsg = 'cannot republish entry for the node\'s private key';
            log.error(errMsg);
            return;
        }
        if (pass) try {
            const keys = await this._keychain.listKeys();
            for (const key of keys){
                if (key.name === 'self') continue;
                const pem = await this._keychain.exportKey(key.name, pass);
                const privKey = await crypto__default['default'].keys.import(pem, pass);
                await this._republishEntry(privKey);
            }
        } catch (err1) {
            log.error(err1);
        }
    }
    async _republishEntry(privateKey1) {
        if (!privateKey1 || !privateKey1.bytes) throw errCode__default['default'](new Error('invalid private key'), 'ERR_INVALID_PRIVATE_KEY');
        try {
            const peerId = await PeerId__default['default'].createFromPrivKey(privateKey1.bytes);
            const value = await this._getPreviousValue(peerId);
            await this._publisher.publishWithEOL(privateKey1, value, defaultRecordLifetime);
        } catch (err) {
            if (err.code === 'ERR_NO_ENTRY_FOUND') return;
            throw err;
        }
    }
    async _getPreviousValue(peerId1) {
        if (!PeerId__default['default'].isPeerId(peerId1)) throw errCode__default['default'](new Error('invalid peer ID'), 'ERR_INVALID_PEER_ID');
        try {
            const dsVal = await this._datastore.get(ipns__namespace.getLocalKey(peerId1.id));
            if (!(dsVal instanceof Uint8Array)) throw errCode__default['default'](new Error('found ipns record that we couldn\'t process'), 'ERR_INVALID_IPNS_RECORD');
            try {
                const record = ipns__namespace.unmarshal(dsVal);
                return record.value;
            } catch (err) {
                log.error(err);
                throw errCode__default['default'](new Error('found ipns record that we couldn\'t convert to a value'), 'ERR_INVALID_IPNS_RECORD');
            }
        } catch (err) {
            if (err && err.notFound) throw errCode__default['default'](new Error(`no previous entry for record with id: ${peerId1.id}`), 'ERR_NO_ENTRY_FOUND');
            throw err;
        }
    }
}
exports.IpnsRepublisher = IpnsRepublisher;

},{"ipns":"jnLxg","libp2p-crypto":"hsRcr","peer-id":"4VGWt","err-code":"eQvyh","debug":"lWlU4"}],"jaAWZ":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var ipns = require('ipns');
var PeerId = require('peer-id');
var errCode = require('err-code');
var debug = require('debug');
var toString = require('uint8arrays/to-string');
var Errors = require('datastore-core/errors');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n['default'] = e;
    return Object.freeze(n);
}
var ipns__namespace = /*#__PURE__*/ _interopNamespace(ipns);
var PeerId__default = /*#__PURE__*/ _interopDefaultLegacy(PeerId);
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
var Errors__namespace = /*#__PURE__*/ _interopNamespace(Errors);
const log = Object.assign(debug__default['default']('ipfs:ipns:resolver'), {
    error: debug__default['default']('ipfs:ipns:resolver:error')
});
const ERR_NOT_FOUND = Errors__namespace.notFoundError().code;
const defaultMaximumRecursiveDepth = 32;
class IpnsResolver {
    constructor(routing){
        this._routing = routing;
    }
    async resolve(name, options = {
    }) {
        if (typeof name !== 'string') throw errCode__default['default'](new Error('invalid name'), 'ERR_INVALID_NAME');
        const recursive = options.recursive && options.recursive.toString() === 'true';
        const nameSegments = name.split('/');
        if (nameSegments.length !== 3 || nameSegments[0] !== '') throw errCode__default['default'](new Error('invalid name'), 'ERR_INVALID_NAME');
        const key = nameSegments[2];
        let depth = Infinity;
        if (recursive) depth = defaultMaximumRecursiveDepth;
        const res = await this.resolver(key, depth);
        log(`${name} was locally resolved correctly`);
        return res;
    }
    async resolver(name1, depth) {
        if (depth === 0) {
            const errMsg = `could not resolve name (recursion limit of ${defaultMaximumRecursiveDepth} exceeded)`;
            log.error(errMsg);
            throw errCode__default['default'](new Error(errMsg), 'ERR_RESOLVE_RECURSION_LIMIT');
        }
        const res = await this._resolveName(name1);
        const nameSegments = res.split('/');
        if (nameSegments[1] === 'ipfs' || !depth) return res;
        return this.resolver(nameSegments[2], depth - 1);
    }
    async _resolveName(name2) {
        const peerId = PeerId__default['default'].parse(name2);
        const { routingKey  } = ipns__namespace.getIdKeys(peerId.toBytes());
        let record;
        try {
            record = await this._routing.get(routingKey.uint8Array());
        } catch (err) {
            log.error('could not get record from routing', err);
            if (err.code === ERR_NOT_FOUND) throw errCode__default['default'](new Error(`record requested for ${name2} was not found in the network`), 'ERR_NO_RECORD_FOUND');
            throw errCode__default['default'](new Error(`unexpected error getting the ipns record ${peerId.toString()}`), 'ERR_UNEXPECTED_ERROR_GETTING_RECORD');
        }
        let ipnsEntry;
        try {
            ipnsEntry = ipns__namespace.unmarshal(record);
        } catch (err1) {
            log.error('could not unmarshal record', err1);
            throw errCode__default['default'](new Error('found ipns record that we couldn\'t convert to a value'), 'ERR_INVALID_RECORD_RECEIVED');
        }
        return this._validateRecord(peerId, ipnsEntry);
    }
    async _validateRecord(peerId, ipnsEntry) {
        const pubKey = await ipns__namespace.extractPublicKey(peerId, ipnsEntry);
        await ipns__namespace.validate(pubKey, ipnsEntry);
        return toString.toString(ipnsEntry.value);
    }
}
exports.IpnsResolver = IpnsResolver;

},{"ipns":"jnLxg","peer-id":"4VGWt","err-code":"eQvyh","debug":"lWlU4","uint8arrays/to-string":"g3mCQ","datastore-core/errors":"hKmom"}],"4Epuc":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var hashlru = require('hashlru');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var hashlru__default = /*#__PURE__*/ _interopDefaultLegacy(hashlru);
class TLRU {
    constructor(maxSize){
        this.lru = hashlru__default['default'](maxSize);
    }
    get(key) {
        const value = this.lru.get(key);
        if (value) {
            if (value.expire && value.expire < Date.now()) {
                this.lru.remove(key);
                return undefined;
            }
            return value.value;
        }
        return undefined;
    }
    set(key1, value, ttl) {
        this.lru.set(key1, {
            value,
            expire: Date.now() + ttl
        });
    }
    has(key2) {
        const value = this.get(key2);
        if (value) return true;
        return false;
    }
    remove(key3) {
        this.lru.remove(key3);
    }
    clear() {
        this.lru.clear();
    }
}
exports.TLRU = TLRU;

},{"hashlru":"fzwAb"}],"eKm5u":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var tiered = require('datastore-core/tiered');
var get = require('dlv');
var pubsubDatastore = require('./pubsub-datastore.js');
var offlineDatastore = require('./offline-datastore.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var get__default = /*#__PURE__*/ _interopDefaultLegacy(get);
function createRouting({ libp2p , repo , peerId , options  }) {
    const ipnsStores = [];
    let pubsubDs;
    if (get__default['default'](options, 'EXPERIMENTAL.ipnsPubsub', false)) {
        const pubsub = libp2p.pubsub;
        const localDatastore = repo.datastore;
        pubsubDs = new pubsubDatastore.IpnsPubsubDatastore(pubsub, localDatastore, peerId);
        ipnsStores.push(pubsubDs);
    }
    if (get__default['default'](options, 'offline') || !get__default['default'](options, 'libp2p.config.dht.enabled', false)) {
        const offlineDatastore$1 = new offlineDatastore.OfflineDatastore(repo);
        ipnsStores.push(offlineDatastore$1);
    } else ipnsStores.push(libp2p._dht);
    return new tiered.TieredDatastore(ipnsStores);
}
exports.createRouting = createRouting;

},{"datastore-core/tiered":"kzZfd","dlv":"3eBmB","./pubsub-datastore.js":"fXbYO","./offline-datastore.js":"jVUnq"}],"kzZfd":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var base = require('./base.js');
var errors = require('./errors.js');
var debug = require('debug');
var pushable = require('it-pushable');
var drain = require('it-drain');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
var pushable__default = /*#__PURE__*/ _interopDefaultLegacy(pushable);
var drain__default = /*#__PURE__*/ _interopDefaultLegacy(drain);
const log = debug__default['default']('datastore:core:tiered');
class TieredDatastore extends base.BaseDatastore {
    constructor(stores){
        super();
        this.stores = stores.slice();
    }
    async open() {
        try {
            await Promise.all(this.stores.map((store)=>store.open()
            ));
        } catch (err) {
            throw errors.dbOpenFailedError();
        }
    }
    async put(key4, value1) {
        try {
            await Promise.all(this.stores.map((store)=>store.put(key4, value1)
            ));
        } catch (err) {
            throw errors.dbWriteFailedError();
        }
    }
    async get(key1, options5) {
        for (const store of this.stores)try {
            const res = await store.get(key1, options5);
            if (res) return res;
        } catch (err) {
            log(err);
        }
        throw errors.notFoundError();
    }
    async has(key2, options1) {
        for (const s of this.stores){
            if (await s.has(key2, options1)) return true;
        }
        return false;
    }
    async delete(key3, options2) {
        try {
            await Promise.all(this.stores.map((store)=>store.delete(key3, options2)
            ));
        } catch (err) {
            throw errors.dbDeleteFailedError();
        }
    }
    async *putMany(source1, options3 = {
    }) {
        let error;
        const pushables = this.stores.map((store)=>{
            const source = pushable__default['default']();
            drain__default['default'](store.putMany(source, options3)).catch((err)=>{
                error = err;
            });
            return source;
        });
        try {
            for await (const pair of source1){
                if (error) throw error;
                pushables.forEach((p)=>p.push(pair)
                );
                yield pair;
            }
        } finally{
            pushables.forEach((p)=>p.end()
            );
        }
    }
    async *deleteMany(source2, options4 = {
    }) {
        let error;
        const pushables = this.stores.map((store)=>{
            const source = pushable__default['default']();
            drain__default['default'](store.deleteMany(source, options4)).catch((err)=>{
                error = err;
            });
            return source;
        });
        try {
            for await (const key of source2){
                if (error) throw error;
                pushables.forEach((p)=>p.push(key)
                );
                yield key;
            }
        } finally{
            pushables.forEach((p)=>p.end()
            );
        }
    }
    async close() {
        await Promise.all(this.stores.map((store)=>store.close()
        ));
    }
    batch() {
        const batches = this.stores.map((store)=>store.batch()
        );
        return {
            put: (key, value)=>{
                batches.forEach((b)=>b.put(key, value)
                );
            },
            delete: (key)=>{
                batches.forEach((b)=>b.delete(key)
                );
            },
            commit: async (options)=>{
                for (const batch of batches)await batch.commit(options);
            }
        };
    }
    query(q, options) {
        return this.stores[this.stores.length - 1].query(q, options);
    }
    queryKeys(q1, options6) {
        return this.stores[this.stores.length - 1].queryKeys(q1, options6);
    }
}
exports.TieredDatastore = TieredDatastore;

},{"./base.js":"9zoeM","./errors.js":"hKmom","debug":"lWlU4","it-pushable":"hRi4l","it-drain":"h63K2"}],"9zoeM":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var utils = require('./utils.js');
var drain = require('it-drain');
var filter = require('it-filter');
var take = require('it-take');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var drain__default = /*#__PURE__*/ _interopDefaultLegacy(drain);
var filter__default = /*#__PURE__*/ _interopDefaultLegacy(filter);
var take__default = /*#__PURE__*/ _interopDefaultLegacy(take);
class BaseDatastore {
    open() {
        return Promise.reject(new Error('.open is not implemented'));
    }
    close() {
        return Promise.reject(new Error('.close is not implemented'));
    }
    put(key4, val, options7) {
        return Promise.reject(new Error('.put is not implemented'));
    }
    get(key1, options1) {
        return Promise.reject(new Error('.get is not implemented'));
    }
    has(key2, options2) {
        return Promise.reject(new Error('.has is not implemented'));
    }
    delete(key3, options3) {
        return Promise.reject(new Error('.delete is not implemented'));
    }
    async *putMany(source, options4 = {
    }) {
        for await (const { key , value  } of source){
            await this.put(key, value, options4);
            yield {
                key,
                value
            };
        }
    }
    async *getMany(source1, options5 = {
    }) {
        for await (const key of source1)yield this.get(key, options5);
    }
    async *deleteMany(source2, options6 = {
    }) {
        for await (const key of source2){
            await this.delete(key, options6);
            yield key;
        }
    }
    batch() {
        let puts = [];
        let dels = [];
        return {
            put (key, value) {
                puts.push({
                    key,
                    value
                });
            },
            delete (key) {
                dels.push(key);
            },
            commit: async (options)=>{
                await drain__default['default'](this.putMany(puts, options));
                puts = [];
                await drain__default['default'](this.deleteMany(dels, options));
                dels = [];
            }
        };
    }
    async *_all(q, options) {
        throw new Error('._all is not implemented');
    }
    async *_allKeys(q1, options8) {
        throw new Error('._allKeys is not implemented');
    }
    query(q2, options9) {
        let it1 = this._all(q2, options9);
        if (q2.prefix != null) it1 = filter__default['default'](it1, (e)=>e.key.toString().startsWith(q2.prefix)
        );
        if (Array.isArray(q2.filters)) it1 = q2.filters.reduce((it, f)=>filter__default['default'](it, f)
        , it1);
        if (Array.isArray(q2.orders)) it1 = q2.orders.reduce((it, f)=>utils.sortAll(it, f)
        , it1);
        if (q2.offset != null) {
            let i = 0;
            it1 = filter__default['default'](it1, ()=>(i++) >= q2.offset
            );
        }
        if (q2.limit != null) it1 = take__default['default'](it1, q2.limit);
        return it1;
    }
    queryKeys(q3, options10) {
        let it2 = this._allKeys(q3, options10);
        if (q3.prefix != null) it2 = filter__default['default'](it2, (key)=>key.toString().startsWith(q3.prefix)
        );
        if (Array.isArray(q3.filters)) it2 = q3.filters.reduce((it, f)=>filter__default['default'](it, f)
        , it2);
        if (Array.isArray(q3.orders)) it2 = q3.orders.reduce((it, f)=>utils.sortAll(it, f)
        , it2);
        if (q3.offset != null) {
            let i = 0;
            it2 = filter__default['default'](it2, ()=>(i++) >= q3.offset
            );
        }
        if (q3.limit != null) it2 = take__default['default'](it2, q3.limit);
        return it2;
    }
}
exports.BaseDatastore = BaseDatastore;

},{"./utils.js":"dTW1j","it-drain":"h63K2","it-filter":"7NtwB","it-take":"8hPk7"}],"dTW1j":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var all = require('it-all');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var all__default = /*#__PURE__*/ _interopDefaultLegacy(all);
const sortAll = (iterable, sorter)=>{
    return (async function*() {
        const values = await all__default['default'](iterable);
        yield* values.sort(sorter);
    })();
};
const replaceStartWith = (s, r)=>{
    const matcher = new RegExp('^' + r);
    return s.replace(matcher, '');
};
exports.replaceStartWith = replaceStartWith;
exports.sortAll = sortAll;

},{"it-all":"hynpN"}],"hynpN":[function(require,module,exports) {
'use strict';
/**
 * Collects all values from an (async) iterable into an array and returns it.
 *
 * @template T
 * @param {AsyncIterable<T>|Iterable<T>} source
 */ const all = async (source)=>{
    const arr = [];
    for await (const entry of source)arr.push(entry);
    return arr;
};
module.exports = all;

},{}],"h63K2":[function(require,module,exports) {
'use strict';
/**
 * Drains an (async) iterable discarding its' content and does not return
 * anything.
 *
 * @template T
 * @param {AsyncIterable<T>|Iterable<T>} source
 * @returns {Promise<void>}
 */ const drain = async (source)=>{
    for await (const _ of source); // eslint-disable-line no-unused-vars,no-empty
};
module.exports = drain;

},{}],"7NtwB":[function(require,module,exports) {
'use strict';
/**
 * Filters the passed (async) iterable by using the filter function
 *
 * @template T
 * @param {AsyncIterable<T>|Iterable<T>} source
 * @param {function(T):boolean|Promise<boolean>} fn
 */ const filter = async function*(source, fn) {
    for await (const entry of source)if (await fn(entry)) yield entry;
};
module.exports = filter;

},{}],"8hPk7":[function(require,module,exports) {
'use strict';
/**
 * Stop iteration after n items have been received.
 *
 * @template T
 * @param {AsyncIterable<T>|Iterable<T>} source
 * @param {number} limit
 * @returns {AsyncIterable<T>}
 */ const take = async function*(source, limit) {
    let items = 0;
    if (limit < 1) return;
    for await (const entry of source){
        yield entry;
        items++;
        if (items === limit) return;
    }
};
module.exports = take;

},{}],"hRi4l":[function(require,module,exports) {
const FIFO = require('fast-fifo');
module.exports = (options)=>{
    options = options || {
    };
    let onEnd;
    if (typeof options === 'function') {
        onEnd = options;
        options = {
        };
    } else onEnd = options.onEnd;
    let buffer = new FIFO();
    let pushable, onNext, ended;
    const waitNext = ()=>{
        if (!buffer.isEmpty()) {
            if (options.writev) {
                let next;
                const values = [];
                while(!buffer.isEmpty()){
                    next = buffer.shift();
                    if (next.error) throw next.error;
                    values.push(next.value);
                }
                return {
                    done: next.done,
                    value: values
                };
            }
            const next = buffer.shift();
            if (next.error) throw next.error;
            return next;
        }
        if (ended) return {
            done: true
        };
        return new Promise((resolve, reject)=>{
            onNext = (next)=>{
                onNext = null;
                if (next.error) reject(next.error);
                else if (options.writev && !next.done) resolve({
                    done: next.done,
                    value: [
                        next.value
                    ]
                });
                else resolve(next);
                return pushable;
            };
        });
    };
    const bufferNext = (next)=>{
        if (onNext) return onNext(next);
        buffer.push(next);
        return pushable;
    };
    const bufferError = (err)=>{
        buffer = new FIFO();
        if (onNext) return onNext({
            error: err
        });
        buffer.push({
            error: err
        });
        return pushable;
    };
    const push = (value)=>{
        if (ended) return pushable;
        return bufferNext({
            done: false,
            value
        });
    };
    const end = (err)=>{
        if (ended) return pushable;
        ended = true;
        return err ? bufferError(err) : bufferNext({
            done: true
        });
    };
    const _return = ()=>{
        buffer = new FIFO();
        end();
        return {
            done: true
        };
    };
    const _throw = (err)=>{
        end(err);
        return {
            done: true
        };
    };
    pushable = {
        [Symbol.asyncIterator] () {
            return this;
        },
        next: waitNext,
        return: _return,
        throw: _throw,
        push,
        end
    };
    if (!onEnd) return pushable;
    const _pushable = pushable;
    pushable = {
        [Symbol.asyncIterator] () {
            return this;
        },
        next () {
            return _pushable.next();
        },
        throw (err) {
            _pushable.throw(err);
            if (onEnd) {
                onEnd(err);
                onEnd = null;
            }
            return {
                done: true
            };
        },
        return () {
            _pushable.return();
            if (onEnd) {
                onEnd();
                onEnd = null;
            }
            return {
                done: true
            };
        },
        push,
        end (err) {
            _pushable.end(err);
            if (onEnd) {
                onEnd(err);
                onEnd = null;
            }
            return pushable;
        }
    };
    return pushable;
};

},{"fast-fifo":"21SLI"}],"21SLI":[function(require,module,exports) {
const FixedFIFO = require('./fixed-size');
module.exports = class FastFIFO {
    constructor(hwm){
        this.hwm = hwm || 16;
        this.head = new FixedFIFO(this.hwm);
        this.tail = this.head;
    }
    push(val) {
        if (!this.head.push(val)) {
            const prev = this.head;
            this.head = prev.next = new FixedFIFO(2 * this.head.buffer.length);
            this.head.push(val);
        }
    }
    shift() {
        const val = this.tail.shift();
        if (val === undefined && this.tail.next) {
            const next = this.tail.next;
            this.tail.next = null;
            this.tail = next;
            return this.tail.shift();
        }
        return val;
    }
    isEmpty() {
        return this.head.isEmpty();
    }
};

},{"./fixed-size":"ifqXX"}],"ifqXX":[function(require,module,exports) {
module.exports = class FixedFIFO {
    constructor(hwm){
        if (!(hwm > 0) || (hwm - 1 & hwm) !== 0) throw new Error('Max size for a FixedFIFO should be a power of two');
        this.buffer = new Array(hwm);
        this.mask = hwm - 1;
        this.top = 0;
        this.btm = 0;
        this.next = null;
    }
    push(data) {
        if (this.buffer[this.top] !== undefined) return false;
        this.buffer[this.top] = data;
        this.top = this.top + 1 & this.mask;
        return true;
    }
    shift() {
        const last = this.buffer[this.btm];
        if (last === undefined) return undefined;
        this.buffer[this.btm] = undefined;
        this.btm = this.btm + 1 & this.mask;
        return last;
    }
    isEmpty() {
        return this.buffer[this.btm] === undefined;
    }
};

},{}],"3eBmB":[function(require,module,exports) {
!function(t1, n1) {
    "object" == typeof exports && "undefined" != typeof module ? module.exports = function(t, n, e, i, o) {
        for(n = n.split ? n.split(".") : n, i = 0; i < n.length; i++)t = t ? t[n[i]] : o;
        return t === o ? e : t;
    } : "function" == typeof define && define.amd ? define(function() {
        return function(t, n, e, i, o) {
            for(n = n.split ? n.split(".") : n, i = 0; i < n.length; i++)t = t ? t[n[i]] : o;
            return t === o ? e : t;
        };
    }) : t1.dlv = function(t, n, e, i, o) {
        for(n = n.split ? n.split(".") : n, i = 0; i < n.length; i++)t = t ? t[n[i]] : o;
        return t === o ? e : t;
    };
}(this);

},{}],"fXbYO":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var ipns = require('ipns');
var base58 = require('multiformats/bases/base58');
var datastorePubsub = require('datastore-pubsub');
var fromString = require('uint8arrays/from-string');
var toString = require('uint8arrays/to-string');
var errCode = require('err-code');
var debug = require('debug');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n['default'] = e;
    return Object.freeze(n);
}
var ipns__namespace = /*#__PURE__*/ _interopNamespace(ipns);
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
const log = Object.assign(debug__default['default']('ipfs:ipns:pubsub'), {
    error: debug__default['default']('ipfs:ipns:pubsub:error')
});
class IpnsPubsubDatastore {
    constructor(pubsub, localDatastore, peerId){
        this._subscriptions = {
        };
        this._handleSubscriptionKey = this._handleSubscriptionKey.bind(this);
        this._pubsubDs = new datastorePubsub.PubsubDatastore(pubsub, localDatastore, peerId, ipns__namespace.validator, this._handleSubscriptionKey);
    }
    put(key, value) {
        return this._pubsubDs.put(key, value);
    }
    async get(key1) {
        let res;
        let err;
        try {
            res = await this._pubsubDs.get(key1);
        } catch (e) {
            err = e;
        }
        const ns = key1.slice(0, ipns__namespace.namespaceLength);
        if (toString.toString(ns) === ipns__namespace.namespace) {
            const stringifiedTopic = base58.base58btc.encode(key1).substring(1);
            const id = base58.base58btc.encode(key1.slice(ipns__namespace.namespaceLength)).substring(1);
            this._subscriptions[stringifiedTopic] = id;
            log(`subscribed to pubsub topic ${stringifiedTopic}, id ${id}`);
        }
        if (err) throw err;
        return res;
    }
    _handleSubscriptionKey(key2) {
        if (key2 instanceof Uint8Array) key2 = toString.toString(key2, 'base58btc');
        const subscriber = this._subscriptions[key2];
        if (!subscriber) throw errCode__default['default'](new Error(`key ${key2} does not correspond to a subscription`), 'ERR_INVALID_KEY');
        let keys;
        try {
            keys = ipns__namespace.getIdKeys(fromString.fromString(subscriber, 'base58btc'));
        } catch (err) {
            log.error(err);
            throw err;
        }
        return keys.routingKey.uint8Array();
    }
    getSubscriptions() {
        const subscriptions = Object.values(this._subscriptions).filter(Boolean);
        return subscriptions.map((sub)=>`${ipns__namespace.namespace}${sub}`
        );
    }
    async cancel(name) {
        if (typeof name !== 'string') throw errCode__default['default'](new Error('invalid subscription name'), 'ERR_INVALID_SUBSCRIPTION_NAME');
        if (name.startsWith(ipns__namespace.namespace)) name = name.substring(ipns__namespace.namespaceLength);
        const stringifiedTopic = Object.keys(this._subscriptions).find((key)=>this._subscriptions[key] === name
        );
        if (!stringifiedTopic) return {
            canceled: false
        };
        const bufTopic = fromString.fromString(stringifiedTopic);
        this._pubsubDs.unsubscribe(bufTopic);
        delete this._subscriptions[stringifiedTopic];
        log(`unsubscribed pubsub ${stringifiedTopic}: ${name}`);
        return {
            canceled: true
        };
    }
}
exports.IpnsPubsubDatastore = IpnsPubsubDatastore;

},{"ipns":"jnLxg","multiformats/bases/base58":"6Rnqi","datastore-pubsub":"cMtHu","uint8arrays/from-string":"lo45E","uint8arrays/to-string":"g3mCQ","err-code":"eQvyh","debug":"lWlU4"}],"cMtHu":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var interfaceDatastore = require('interface-datastore');
var datastoreCore = require('datastore-core');
var utils = require('./utils.js');
var equals = require('uint8arrays/equals');
var errcode = require('err-code');
var debug = require('debug');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var errcode__default = /*#__PURE__*/ _interopDefaultLegacy(errcode);
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
const log = Object.assign(debug__default['default']('datastore-pubsub:publisher'), {
    error: debug__default['default']('datastore-pubsub:publisher:error')
});
class PubsubDatastore extends datastoreCore.BaseDatastore {
    constructor(pubsub, datastore, peerId, validator, subscriptionKeyFn){
        super();
        if (!validator) throw errcode__default['default'](new TypeError('missing validator'), 'ERR_INVALID_PARAMETERS');
        if (typeof validator.validate !== 'function') throw errcode__default['default'](new TypeError('missing validate function'), 'ERR_INVALID_PARAMETERS');
        if (typeof validator.select !== 'function') throw errcode__default['default'](new TypeError('missing select function'), 'ERR_INVALID_PARAMETERS');
        if (subscriptionKeyFn && typeof subscriptionKeyFn !== 'function') throw errcode__default['default'](new TypeError('invalid subscriptionKeyFn received'), 'ERR_INVALID_PARAMETERS');
        this._pubsub = pubsub;
        this._datastore = datastore;
        this._peerId = peerId;
        this._validator = validator;
        this._handleSubscriptionKeyFn = subscriptionKeyFn;
        this._onMessage = this._onMessage.bind(this);
    }
    async put(key, val) {
        if (!(key instanceof Uint8Array)) {
            const errMsg = 'datastore key does not have a valid format';
            log.error(errMsg);
            throw errcode__default['default'](new Error(errMsg), 'ERR_INVALID_DATASTORE_KEY');
        }
        if (!(val instanceof Uint8Array)) {
            const errMsg = 'received value is not a Uint8Array';
            log.error(errMsg);
            throw errcode__default['default'](new Error(errMsg), 'ERR_INVALID_VALUE_RECEIVED');
        }
        const stringifiedTopic = utils.keyToTopic(key);
        log(`publish value for topic ${stringifiedTopic}`);
        await this._pubsub.publish(stringifiedTopic, val);
    }
    async get(key1) {
        if (!(key1 instanceof Uint8Array)) {
            const errMsg = 'datastore key does not have a valid format';
            log.error(errMsg);
            throw errcode__default['default'](new Error(errMsg), 'ERR_INVALID_DATASTORE_KEY');
        }
        const stringifiedTopic = utils.keyToTopic(key1);
        const subscriptions = await this._pubsub.getTopics();
        if (subscriptions && Array.isArray(subscriptions) && subscriptions.indexOf(stringifiedTopic) > -1) return this._getLocal(key1);
        try {
            this._pubsub.on(stringifiedTopic, this._onMessage);
            await this._pubsub.subscribe(stringifiedTopic);
        } catch (err) {
            const errMsg = `cannot subscribe topic ${stringifiedTopic}`;
            log.error(errMsg);
            throw errcode__default['default'](new Error(errMsg), 'ERR_SUBSCRIBING_TOPIC');
        }
        log(`subscribed values for key ${stringifiedTopic}`);
        return this._getLocal(key1);
    }
    unsubscribe(key2) {
        const stringifiedTopic = utils.keyToTopic(key2);
        this._pubsub.removeListener(stringifiedTopic, this._onMessage);
        return this._pubsub.unsubscribe(stringifiedTopic);
    }
    async _getLocal(key3) {
        const routingKey = new interfaceDatastore.Key('/' + utils.encodeBase32(key3), false);
        let dsVal;
        try {
            dsVal = await this._datastore.get(routingKey);
        } catch (err) {
            if (err.code !== 'ERR_NOT_FOUND') {
                const errMsg = `unexpected error getting the ipns record for ${routingKey.toString()}`;
                log.error(errMsg);
                throw errcode__default['default'](new Error(errMsg), 'ERR_UNEXPECTED_ERROR_GETTING_RECORD');
            }
            const errMsg = `local record requested was not found for ${routingKey.toString()}`;
            log.error(errMsg);
            throw errcode__default['default'](new Error(errMsg), 'ERR_NOT_FOUND');
        }
        if (!(dsVal instanceof Uint8Array)) {
            const errMsg = 'found record that we couldn\'t convert to a value';
            log.error(errMsg);
            throw errcode__default['default'](new Error(errMsg), 'ERR_INVALID_RECORD_RECEIVED');
        }
        return dsVal;
    }
    async _onMessage(msg) {
        const { data , from , topicIDs  } = msg;
        let key;
        try {
            key = utils.topicToKey(topicIDs[0]);
        } catch (err) {
            log.error(err);
            return;
        }
        log(`message received for topic ${topicIDs[0]}`);
        if (from === this._peerId.toB58String()) {
            log('message discarded as it is from the same peer');
            return;
        }
        if (this._handleSubscriptionKeyFn) {
            let res;
            try {
                res = await this._handleSubscriptionKeyFn(key);
            } catch (err) {
                log.error('message discarded by the subscriptionKeyFn');
                return;
            }
            key = res;
        }
        try {
            await this._storeIfSubscriptionIsBetter(key, data);
        } catch (err1) {
            log.error(err1);
        }
    }
    async _storeIfSubscriptionIsBetter(key4, data) {
        let isBetter = false;
        try {
            isBetter = await this._isBetter(key4, data);
        } catch (err) {
            if (err.code !== 'ERR_NOT_VALID_RECORD') throw err;
        }
        if (isBetter) await this._storeRecord(key4, data);
    }
    async _validateRecord(value, peerId1) {
        return this._validator.validate(value, peerId1);
    }
    async _selectRecord(key5, records) {
        const res = await this._validator.select(key5, records);
        return res === 0;
    }
    async _isBetter(key6, val1) {
        try {
            await this._validateRecord(val1, key6);
        } catch (err) {
            const errMsg = 'record received through pubsub is not valid';
            log.error(errMsg);
            throw errcode__default['default'](new Error(errMsg), 'ERR_NOT_VALID_RECORD');
        }
        const dsKey = new interfaceDatastore.Key(key6);
        let currentRecord;
        try {
            currentRecord = await this._getLocal(dsKey.uint8Array());
        } catch (err2) {
            return true;
        }
        if (equals.equals(currentRecord, val1)) return false;
        return this._selectRecord(key6, [
            currentRecord,
            val1
        ]);
    }
    async _storeRecord(key7, data1) {
        const routingKey = new interfaceDatastore.Key('/' + utils.encodeBase32(key7), false);
        await this._datastore.put(routingKey, data1);
        log(`record for ${utils.keyToTopic(key7)} was stored in the datastore`);
    }
}
exports.PubsubDatastore = PubsubDatastore;

},{"interface-datastore":"9B36y","datastore-core":"8BFN9","./utils.js":"7pK61","uint8arrays/equals":"fjLeN","err-code":"eQvyh","debug":"lWlU4"}],"9B36y":[function(require,module,exports) {
module.exports = require('./cjs/src/index.js');

},{"./cjs/src/index.js":"7M116"}],"7M116":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var key = require('./key.js');
exports.Key = key.Key;

},{"./key.js":"ccQWS"}],"8BFN9":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var errors = require('./errors.js');
var shard$1 = require('./shard.js');
var base = require('./base.js');
var memory = require('./memory.js');
var keytransform = require('./keytransform.js');
var sharding = require('./sharding.js');
var mount = require('./mount.js');
var tiered = require('./tiered.js');
var namespace = require('./namespace.js');
const Errors = {
    ...errors
};
const shard = {
    ...shard$1
};
exports.BaseDatastore = base.BaseDatastore;
exports.MemoryDatastore = memory.MemoryDatastore;
exports.KeyTransformDatastore = keytransform.KeyTransformDatastore;
exports.ShardingDatastore = sharding.ShardingDatastore;
exports.MountDatastore = mount.MountDatastore;
exports.TieredDatastore = tiered.TieredDatastore;
exports.NamespaceDatastore = namespace.NamespaceDatastore;
exports.Errors = Errors;
exports.shard = shard;

},{"./errors.js":"hKmom","./shard.js":"4CvOK","./base.js":"9zoeM","./memory.js":"8Qezj","./keytransform.js":"6eC4W","./sharding.js":"hesfc","./mount.js":"7EkGR","./tiered.js":"kzZfd","./namespace.js":"elmZb"}],"4CvOK":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var key = require('interface-datastore/key');
var shardReadme = require('./shard-readme.js');
const PREFIX = '/repo/flatfs/shard/';
const SHARDING_FN = 'SHARDING';
const README_FN = '_README';
class ShardBase {
    constructor(param1){
        this.param = param1;
        this.name = 'base';
        this._padding = '';
    }
    fun(s) {
        return 'implement me';
    }
    toString() {
        return `${PREFIX}v1/${this.name}/${this.param}`;
    }
}
class Prefix extends ShardBase {
    constructor(prefixLen){
        super(prefixLen);
        this._padding = ''.padStart(prefixLen, '_');
        this.name = 'prefix';
    }
    fun(noslash) {
        return (noslash + this._padding).slice(0, this.param);
    }
}
class Suffix extends ShardBase {
    constructor(suffixLen){
        super(suffixLen);
        this._padding = ''.padStart(suffixLen, '_');
        this.name = 'suffix';
    }
    fun(noslash1) {
        const s = this._padding + noslash1;
        return s.slice(s.length - this.param);
    }
}
class NextToLast extends ShardBase {
    constructor(suffixLen1){
        super(suffixLen1);
        this._padding = ''.padStart(suffixLen1 + 1, '_');
        this.name = 'next-to-last';
    }
    fun(noslash2) {
        const s = this._padding + noslash2;
        const offset = s.length - this.param - 1;
        return s.slice(offset, offset + this.param);
    }
}
function parseShardFun(str) {
    str = str.trim();
    if (str.length === 0) throw new Error('empty shard string');
    if (!str.startsWith(PREFIX)) throw new Error(`invalid or no path prefix: ${str}`);
    const parts = str.slice(PREFIX.length).split('/');
    const version = parts[0];
    if (version !== 'v1') throw new Error(`expect 'v1' version, got '${version}'`);
    const name = parts[1];
    if (!parts[2]) throw new Error('missing param');
    const param = parseInt(parts[2], 10);
    switch(name){
        case 'prefix':
            return new Prefix(param);
        case 'suffix':
            return new Suffix(param);
        case 'next-to-last':
            return new NextToLast(param);
        default:
            throw new Error(`unkown sharding function: ${name}`);
    }
}
const readShardFun = async (path, store)=>{
    const key$1 = new key.Key(path).child(new key.Key(SHARDING_FN));
    const get = typeof store.getRaw === 'function' ? store.getRaw.bind(store) : store.get.bind(store);
    const res = await get(key$1);
    return parseShardFun(new TextDecoder().decode(res || '').trim());
};
exports.readme = shardReadme;
exports.NextToLast = NextToLast;
exports.PREFIX = PREFIX;
exports.Prefix = Prefix;
exports.README_FN = README_FN;
exports.SHARDING_FN = SHARDING_FN;
exports.ShardBase = ShardBase;
exports.Suffix = Suffix;
exports.parseShardFun = parseShardFun;
exports.readShardFun = readShardFun;

},{"interface-datastore/key":"ccQWS","./shard-readme.js":"cOmrV"}],"cOmrV":[function(require,module,exports) {
'use strict';
var readme = `This is a repository of IPLD objects. Each IPLD object is in a single file,
named <base32 encoding of cid>.data. Where <base32 encoding of cid> is the
"base32" encoding of the CID (as specified in
https://github.com/multiformats/multibase) without the 'B' prefix.
All the object files are placed in a tree of directories, based on a
function of the CID. This is a form of sharding similar to
the objects directory in git repositories. Previously, we used
prefixes, we now use the next-to-last two charters.
    func NextToLast(base32cid string) {
      nextToLastLen := 2
      offset := len(base32cid) - nextToLastLen - 1
      return str[offset : offset+nextToLastLen]
    }
For example, an object with a base58 CIDv1 of
    zb2rhYSxw4ZjuzgCnWSt19Q94ERaeFhu9uSqRgjSdx9bsgM6f
has a base32 CIDv1 of
    BAFKREIA22FLID5AJ2KU7URG47MDLROZIH6YF2KALU2PWEFPVI37YLKRSCA
and will be placed at
    SC/AFKREIA22FLID5AJ2KU7URG47MDLROZIH6YF2KALU2PWEFPVI37YLKRSCA.data
with 'SC' being the last-to-next two characters and the 'B' at the
beginning of the CIDv1 string is the multibase prefix that is not
stored in the filename.
`;
module.exports = readme;

},{}],"8Qezj":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var base = require('./base.js');
var key = require('interface-datastore/key');
var errors = require('./errors.js');
class MemoryDatastore extends base.BaseDatastore {
    constructor(){
        super();
        this.data = {
        };
    }
    open() {
        return Promise.resolve();
    }
    close() {
        return Promise.resolve();
    }
    async put(key1, val) {
        this.data[key1.toString()] = val;
    }
    async get(key2) {
        const exists = await this.has(key2);
        if (!exists) throw errors.notFoundError();
        return this.data[key2.toString()];
    }
    async has(key3) {
        return this.data[key3.toString()] !== undefined;
    }
    async delete(key4) {
        delete this.data[key4.toString()];
    }
    async *_all() {
        yield* Object.entries(this.data).map(([key$1, value])=>({
                key: new key.Key(key$1),
                value
            })
        );
    }
    async *_allKeys() {
        yield* Object.entries(this.data).map(([key$1])=>new key.Key(key$1)
        );
    }
}
exports.MemoryDatastore = MemoryDatastore;

},{"./base.js":"9zoeM","interface-datastore/key":"ccQWS","./errors.js":"hKmom"}],"6eC4W":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var base = require('./base.js');
var map = require('it-map');
var itPipe = require('it-pipe');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var map__default = /*#__PURE__*/ _interopDefaultLegacy(map);
class KeyTransformDatastore extends base.BaseDatastore {
    constructor(child, transform){
        super();
        this.child = child;
        this.transform = transform;
    }
    open() {
        return this.child.open();
    }
    put(key4, val, options7) {
        return this.child.put(this.transform.convert(key4), val, options7);
    }
    get(key1, options1) {
        return this.child.get(this.transform.convert(key1), options1);
    }
    has(key2, options2) {
        return this.child.has(this.transform.convert(key2), options2);
    }
    delete(key3, options3) {
        return this.child.delete(this.transform.convert(key3), options3);
    }
    async *putMany(source1, options4 = {
    }) {
        const transform = this.transform;
        const child = this.child;
        yield* itPipe.pipe(source1, async function*(source) {
            yield* map__default['default'](source, ({ key , value  })=>({
                    key: transform.convert(key),
                    value
                })
            );
        }, async function*(source) {
            yield* child.putMany(source, options4);
        }, async function*(source) {
            yield* map__default['default'](source, ({ key , value  })=>({
                    key: transform.invert(key),
                    value
                })
            );
        });
    }
    async *getMany(source2, options5 = {
    }) {
        const transform = this.transform;
        const child = this.child;
        yield* itPipe.pipe(source2, async function*(source) {
            yield* map__default['default'](source, (key)=>transform.convert(key)
            );
        }, async function*(source) {
            yield* child.getMany(source, options5);
        });
    }
    async *deleteMany(source3, options6 = {
    }) {
        const transform = this.transform;
        const child = this.child;
        yield* itPipe.pipe(source3, async function*(source) {
            yield* map__default['default'](source, (key)=>transform.convert(key)
            );
        }, async function*(source) {
            yield* child.deleteMany(source, options6);
        }, async function*(source) {
            yield* map__default['default'](source, (key)=>transform.invert(key)
            );
        });
    }
    batch() {
        const b = this.child.batch();
        return {
            put: (key, value)=>{
                b.put(this.transform.convert(key), value);
            },
            delete: (key)=>{
                b.delete(this.transform.convert(key));
            },
            commit: (options)=>{
                return b.commit(options);
            }
        };
    }
    query(q, options) {
        return map__default['default'](this.child.query(q, options), ({ key , value  })=>{
            return {
                key: this.transform.invert(key),
                value
            };
        });
    }
    queryKeys(q1, options8) {
        return map__default['default'](this.child.queryKeys(q1, options8), (key)=>{
            return this.transform.invert(key);
        });
    }
    close() {
        return this.child.close();
    }
}
exports.KeyTransformDatastore = KeyTransformDatastore;

},{"./base.js":"9zoeM","it-map":"dOmp3","it-pipe":"4jukm"}],"dOmp3":[function(require,module,exports) {
'use strict';
/**
 * Takes an (async) iterable and returns one with each item mapped by the passed
 * function.
 *
 * @template I,O
 * @param {AsyncIterable<I>|Iterable<I>} source
 * @param {function(I):O|Promise<O>} func
 * @returns {AsyncIterable<O>}
 */ const map = async function*(source, func) {
    for await (const val of source)yield func(val);
};
module.exports = map;

},{}],"4jukm":[function(require,module,exports) {
const rawPipe = (...fns)=>{
    let res;
    while(fns.length)res = fns.shift()(res);
    return res;
};
const isIterable = (obj)=>obj && (typeof obj[Symbol.asyncIterator] === 'function' || typeof obj[Symbol.iterator] === 'function' || typeof obj.next === 'function' // Probably, right?
    )
;
const isDuplex = (obj)=>obj && typeof obj.sink === 'function' && isIterable(obj.source)
;
const duplexPipelineFn = (duplex)=>(source)=>{
        duplex.sink(source) // TODO: error on sink side is unhandled rejection - this is the same as pull streams
        ;
        return duplex.source;
    }
;
const pipe = (...fns)=>{
    // Duplex at start: wrap in function and return duplex source
    if (isDuplex(fns[0])) {
        const duplex = fns[0];
        fns[0] = ()=>duplex.source
        ;
    // Iterable at start: wrap in function
    } else if (isIterable(fns[0])) {
        const source = fns[0];
        fns[0] = ()=>source
        ;
    }
    if (fns.length > 1) // Duplex at end: use duplex sink
    {
        if (isDuplex(fns[fns.length - 1])) fns[fns.length - 1] = fns[fns.length - 1].sink;
    }
    if (fns.length > 2) {
        // Duplex in the middle, consume source with duplex sink and return duplex source
        for(let i = 1; i < fns.length - 1; i++)if (isDuplex(fns[i])) fns[i] = duplexPipelineFn(fns[i]);
    }
    return rawPipe(...fns);
};
module.exports = pipe;
module.exports.pipe = pipe;
module.exports.rawPipe = rawPipe;
module.exports.isIterable = isIterable;
module.exports.isDuplex = isDuplex;

},{}],"hesfc":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var interfaceDatastore = require('interface-datastore');
var shard = require('./shard.js');
var base = require('./base.js');
var keytransform = require('./keytransform.js');
var errors = require('./errors.js');
var shardReadme = require('./shard-readme.js');
const shardKey = new interfaceDatastore.Key(shard.SHARDING_FN);
const shardReadmeKey = new interfaceDatastore.Key(shard.README_FN);
class ShardingDatastore extends base.BaseDatastore {
    constructor(store, shard1){
        super();
        this.child = new keytransform.KeyTransformDatastore(store, {
            convert: this._convertKey.bind(this),
            invert: this._invertKey.bind(this)
        });
        this.shard = shard1;
    }
    async open() {
        await this.child.open();
        this.shard = await ShardingDatastore.create(this.child, this.shard);
    }
    _convertKey(key6) {
        const s = key6.toString();
        if (s === shardKey.toString() || s === shardReadmeKey.toString()) return key6;
        const parent = new interfaceDatastore.Key(this.shard.fun(s));
        return parent.child(key6);
    }
    _invertKey(key1) {
        const s = key1.toString();
        if (s === shardKey.toString() || s === shardReadmeKey.toString()) return key1;
        return interfaceDatastore.Key.withNamespaces(key1.list().slice(1));
    }
    static async createOrOpen(store1, shard2) {
        try {
            await ShardingDatastore.create(store1, shard2);
        } catch (err) {
            if (err && err.message !== 'datastore exists') throw err;
        }
        return ShardingDatastore.open(store1);
    }
    static async open(store2) {
        const shard$1 = await shard.readShardFun('/', store2);
        return new ShardingDatastore(store2, shard$1);
    }
    static async create(store3, shard$1) {
        const hasShard = await store3.has(shardKey);
        if (!hasShard && !shard$1) throw errors.dbOpenFailedError(Error('Shard is required when datastore doesn\'t have a shard key already.'));
        if (!hasShard) {
            const put = typeof store3.putRaw === 'function' ? store3.putRaw.bind(store3) : store3.put.bind(store3);
            await Promise.all([
                put(shardKey, new TextEncoder().encode(shard$1.toString() + '\n')),
                put(shardReadmeKey, new TextEncoder().encode(shardReadme))
            ]);
            return shard$1;
        }
        const diskShard = await shard.readShardFun('/', store3);
        const a = (diskShard || '').toString();
        const b = shard$1.toString();
        if (a !== b) throw new Error(`specified fun ${b} does not match repo shard fun ${a}`);
        return diskShard;
    }
    put(key2, val, options) {
        return this.child.put(key2, val, options);
    }
    get(key3, options1) {
        return this.child.get(key3, options1);
    }
    has(key4, options2) {
        return this.child.has(key4, options2);
    }
    delete(key5, options3) {
        return this.child.delete(key5, options3);
    }
    async *putMany(source, options4 = {
    }) {
        yield* this.child.putMany(source, options4);
    }
    async *getMany(source1, options5 = {
    }) {
        yield* this.child.getMany(source1, options5);
    }
    async *deleteMany(source2, options6 = {
    }) {
        yield* this.child.deleteMany(source2, options6);
    }
    batch() {
        return this.child.batch();
    }
    query(q, options7) {
        const tq = {
            offset: q.offset,
            limit: q.limit,
            orders: [],
            filters: [
                (e)=>e.key.toString() !== shardKey.toString()
                ,
                (e)=>e.key.toString() !== shardReadmeKey.toString()
            ]
        };
        const { prefix  } = q;
        if (prefix != null) tq.filters.push((e)=>{
            return this._invertKey(e.key).toString().startsWith(prefix);
        });
        if (q.filters != null) {
            const filters = q.filters.map((f)=>{
                const filter = ({ key , value  })=>{
                    return f({
                        key: this._invertKey(key),
                        value
                    });
                };
                return filter;
            });
            tq.filters = tq.filters.concat(filters);
        }
        if (q.orders != null) tq.orders = q.orders.map((o)=>{
            const order = (a, b)=>{
                return o({
                    key: this._invertKey(a.key),
                    value: a.value
                }, {
                    key: this._invertKey(b.key),
                    value: b.value
                });
            };
            return order;
        });
        return this.child.query(tq, options7);
    }
    queryKeys(q1, options8) {
        const tq = {
            offset: q1.offset,
            limit: q1.limit,
            orders: [],
            filters: [
                (key)=>key.toString() !== shardKey.toString()
                ,
                (key)=>key.toString() !== shardReadmeKey.toString()
            ]
        };
        const { prefix  } = q1;
        if (prefix != null) tq.filters.push((key)=>{
            return this._invertKey(key).toString().startsWith(prefix);
        });
        if (q1.filters != null) {
            const filters = q1.filters.map((f)=>{
                const filter = (key)=>{
                    return f(this._invertKey(key));
                };
                return filter;
            });
            tq.filters = tq.filters.concat(filters);
        }
        if (q1.orders != null) tq.orders = q1.orders.map((o)=>{
            const order = (a, b)=>o(this._invertKey(a), this._invertKey(b))
            ;
            return order;
        });
        return this.child.queryKeys(tq, options8);
    }
    close() {
        return this.child.close();
    }
}
exports.ShardingDatastore = ShardingDatastore;

},{"interface-datastore":"9B36y","./shard.js":"4CvOK","./base.js":"9zoeM","./keytransform.js":"6eC4W","./errors.js":"hKmom","./shard-readme.js":"cOmrV"}],"7EkGR":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var filter = require('it-filter');
var take = require('it-take');
var merge = require('it-merge');
var base = require('./base.js');
var keytransform = require('./keytransform.js');
var errors = require('./errors.js');
var utils = require('./utils.js');
var key5 = require('interface-datastore/key');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var filter__default = /*#__PURE__*/ _interopDefaultLegacy(filter);
var take__default = /*#__PURE__*/ _interopDefaultLegacy(take);
var merge__default = /*#__PURE__*/ _interopDefaultLegacy(merge);
class MountDatastore extends base.BaseDatastore {
    constructor(mounts){
        super();
        this.mounts = mounts.slice();
    }
    async open() {
        await Promise.all(this.mounts.map((m)=>m.datastore.open()
        ));
    }
    _lookup(key$1) {
        for (const mount of this.mounts)if (mount.prefix.toString() === key$1.toString() || mount.prefix.isAncestorOf(key$1)) {
            const s = utils.replaceStartWith(key$1.toString(), mount.prefix.toString());
            return {
                datastore: mount.datastore,
                mountpoint: mount.prefix,
                rest: new key5.Key(s)
            };
        }
    }
    put(key1, value1, options4) {
        const match = this._lookup(key1);
        if (match == null) throw errors.dbWriteFailedError(new Error('No datastore mounted for this key'));
        return match.datastore.put(match.rest, value1, options4);
    }
    get(key2, options1) {
        const match = this._lookup(key2);
        if (match == null) throw errors.notFoundError(new Error('No datastore mounted for this key'));
        return match.datastore.get(match.rest, options1);
    }
    has(key3, options2) {
        const match = this._lookup(key3);
        if (match == null) return Promise.resolve(false);
        return match.datastore.has(match.rest, options2);
    }
    delete(key4, options3) {
        const match = this._lookup(key4);
        if (match == null) throw errors.dbDeleteFailedError(new Error('No datastore mounted for this key'));
        return match.datastore.delete(match.rest, options3);
    }
    async close() {
        await Promise.all(this.mounts.map((m)=>{
            return m.datastore.close();
        }));
    }
    batch() {
        const batchMounts = {
        };
        const lookup = (key)=>{
            const match = this._lookup(key);
            if (match == null) throw new Error('No datastore mounted for this key');
            const m = match.mountpoint.toString();
            if (batchMounts[m] == null) batchMounts[m] = match.datastore.batch();
            return {
                batch: batchMounts[m],
                rest: match.rest
            };
        };
        return {
            put: (key, value)=>{
                const match = lookup(key);
                match.batch.put(match.rest, value);
            },
            delete: (key)=>{
                const match = lookup(key);
                match.batch.delete(match.rest);
            },
            commit: async (options)=>{
                await Promise.all(Object.keys(batchMounts).map((p)=>batchMounts[p].commit(options)
                ));
            }
        };
    }
    query(q, options) {
        const qs = this.mounts.map((m)=>{
            const ks = new keytransform.KeyTransformDatastore(m.datastore, {
                convert: (key)=>{
                    throw new Error('should never be called');
                },
                invert: (key)=>{
                    return m.prefix.child(key);
                }
            });
            let prefix;
            if (q.prefix != null) prefix = utils.replaceStartWith(q.prefix, m.prefix.toString());
            return ks.query({
                prefix: prefix,
                filters: q.filters
            }, options);
        });
        let it = merge__default['default'](...qs);
        if (q.filters) q.filters.forEach((f)=>{
            it = filter__default['default'](it, f);
        });
        if (q.orders) q.orders.forEach((o)=>{
            it = utils.sortAll(it, o);
        });
        if (q.offset != null) {
            let i = 0;
            it = filter__default['default'](it, ()=>(i++) >= q.offset
            );
        }
        if (q.limit != null) it = take__default['default'](it, q.limit);
        return it;
    }
    queryKeys(q1, options5) {
        const qs = this.mounts.map((m)=>{
            const ks = new keytransform.KeyTransformDatastore(m.datastore, {
                convert: (key)=>{
                    throw new Error('should never be called');
                },
                invert: (key)=>{
                    return m.prefix.child(key);
                }
            });
            let prefix;
            if (q1.prefix != null) prefix = utils.replaceStartWith(q1.prefix, m.prefix.toString());
            return ks.queryKeys({
                prefix: prefix,
                filters: q1.filters
            }, options5);
        });
        let it = merge__default['default'](...qs);
        if (q1.filters) q1.filters.forEach((f)=>{
            it = filter__default['default'](it, f);
        });
        if (q1.orders) q1.orders.forEach((o)=>{
            it = utils.sortAll(it, o);
        });
        if (q1.offset != null) {
            let i = 0;
            it = filter__default['default'](it, ()=>(i++) >= q1.offset
            );
        }
        if (q1.limit != null) it = take__default['default'](it, q1.limit);
        return it;
    }
}
exports.MountDatastore = MountDatastore;

},{"it-filter":"7NtwB","it-take":"8hPk7","it-merge":"7iKAo","./base.js":"9zoeM","./keytransform.js":"6eC4W","./errors.js":"hKmom","./utils.js":"dTW1j","interface-datastore/key":"ccQWS"}],"7iKAo":[function(require,module,exports) {
'use strict';
const pushable = require('it-pushable');
/**
 * Treat one or more iterables as a single iterable.
 *
 * Nb. sources are iterated over in parallel so the
 * order of emitted items is not guaranteed.
 *
 * @template T
 * @param {...AsyncIterable<T>|Iterable<T>} sources
 * @returns {AsyncIterable<T>}
 */ const merge = async function*(...sources) {
    const output = pushable();
    setTimeout(async ()=>{
        try {
            await Promise.all(sources.map(async (source)=>{
                for await (const item of source)output.push(item);
            }));
            output.end();
        } catch (/** @type {any} */ err) {
            output.end(err);
        }
    }, 0);
    yield* output;
};
module.exports = merge;

},{"it-pushable":"hRi4l"}],"elmZb":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var interfaceDatastore = require('interface-datastore');
var keytransform = require('./keytransform.js');
class NamespaceDatastore extends keytransform.KeyTransformDatastore {
    constructor(child, prefix){
        super(child, {
            convert (key) {
                return prefix.child(key);
            },
            invert (key) {
                if (prefix.toString() === '/') return key;
                if (!prefix.isAncestorOf(key)) throw new Error(`Expected prefix: (${prefix.toString()}) in key: ${key.toString()}`);
                return new interfaceDatastore.Key(key.toString().slice(prefix.toString().length), false);
            }
        });
        this.prefix = prefix;
    }
    query(q, options) {
        if (q.prefix && this.prefix.toString() !== '/') return super.query(Object.assign({
        }, q, {
            prefix: this.prefix.child(new interfaceDatastore.Key(q.prefix)).toString()
        }));
        return super.query(q, options);
    }
    queryKeys(q1, options1) {
        if (q1.prefix && this.prefix.toString() !== '/') return super.queryKeys(Object.assign({
        }, q1, {
            prefix: this.prefix.child(new interfaceDatastore.Key(q1.prefix)).toString()
        }));
        return super.queryKeys(q1, options1);
    }
}
exports.NamespaceDatastore = NamespaceDatastore;

},{"interface-datastore":"9B36y","./keytransform.js":"6eC4W"}],"7pK61":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var errcode = require('err-code');
var toString = require('uint8arrays/to-string');
var fromString = require('uint8arrays/from-string');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var errcode__default = /*#__PURE__*/ _interopDefaultLegacy(errcode);
const namespace = '/record/';
function encodeBase32(buf) {
    return toString.toString(buf, 'base32');
}
function keyToTopic(key) {
    if (typeof key === 'string' || key instanceof String) key = fromString.fromString(key.toString());
    const b64url = toString.toString(key, 'base64url');
    return `${namespace}${b64url}`;
}
function topicToKey(topic) {
    if (topic.substring(0, namespace.length) !== namespace) throw errcode__default['default'](new Error('topic received is not from a record'), 'ERR_TOPIC_IS_NOT_FROM_RECORD_NAMESPACE');
    const key = topic.substring(namespace.length);
    return fromString.fromString(key, 'base64url');
}
exports.encodeBase32 = encodeBase32;
exports.keyToTopic = keyToTopic;
exports.topicToKey = topicToKey;

},{"err-code":"eQvyh","uint8arrays/to-string":"g3mCQ","uint8arrays/from-string":"lo45E"}],"jVUnq":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var key = require('interface-datastore/key');
var libp2pRecord = require('libp2p-record');
var errCode = require('err-code');
var debug = require('debug');
var toString = require('uint8arrays/to-string');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
const log = Object.assign(debug__default['default']('ipfs:ipns:offline-datastore'), {
    error: debug__default['default']('ipfs:ipns:offline-datastore:error')
});
class OfflineDatastore {
    constructor(repo){
        this._repo = repo;
        this.stores = [];
    }
    async put(key1, value) {
        if (!(key1 instanceof Uint8Array)) throw errCode__default['default'](new Error('Offline datastore key must be a Uint8Array'), 'ERR_INVALID_KEY');
        if (!(value instanceof Uint8Array)) throw errCode__default['default'](new Error('Offline datastore value must be a Uint8Array'), 'ERR_INVALID_VALUE');
        let routingKey;
        try {
            routingKey = this._routingKey(key1);
        } catch (err) {
            log.error(err);
            throw errCode__default['default'](new Error('Not possible to generate the routing key'), 'ERR_GENERATING_ROUTING_KEY');
        }
        const record = new libp2pRecord.Record(key1, value);
        return this._repo.datastore.put(routingKey, record.serialize());
    }
    async get(key2) {
        if (!(key2 instanceof Uint8Array)) throw errCode__default['default'](new Error('Offline datastore key must be a Uint8Array'), 'ERR_INVALID_KEY');
        let routingKey;
        try {
            routingKey = this._routingKey(key2);
        } catch (err) {
            log.error(err);
            throw errCode__default['default'](new Error('Not possible to generate the routing key'), 'ERR_GENERATING_ROUTING_KEY');
        }
        const res = await this._repo.datastore.get(routingKey);
        let record;
        try {
            record = libp2pRecord.Record.deserialize(res);
        } catch (err1) {
            log.error(err1);
            throw err1;
        }
        return record.value;
    }
    _routingKey(key$1) {
        return new key.Key('/' + toString.toString(key$1, 'base32upper'), false);
    }
}
exports.OfflineDatastore = OfflineDatastore;

},{"interface-datastore/key":"ccQWS","libp2p-record":"4hkIr","err-code":"eQvyh","debug":"lWlU4","uint8arrays/to-string":"g3mCQ"}],"4hkIr":[function(require,module,exports) {
'use strict';
module.exports = {
    Record: require('./record'),
    validator: require('./validator'),
    selection: require('./selection')
};

},{"./record":"lxXwn","./validator":"7fUE7","./selection":"d75WG"}],"lxXwn":[function(require,module,exports) {
'use strict';
const { Record: PBRecord  } = require('./record');
const utils = require('../utils');
/**
 * @typedef {{ key: Uint8Array, value: Uint8Array, timeReceived: string }} ProtobufRecord
 */ class Record {
    /**
   * @param {Uint8Array} [key]
   * @param {Uint8Array} [value]
   * @param {Date} [timeReceived]
   */ constructor(key, value, timeReceived){
        if (!(key instanceof Uint8Array)) throw new Error('key must be a Uint8Array');
        if (!(value instanceof Uint8Array)) throw new Error('value must be a Uint8Array');
        this.key = key;
        this.value = value;
        this.timeReceived = timeReceived;
    }
    serialize() {
        return PBRecord.encode(this.prepareSerialize()).finish();
    }
    /**
   * Return the object format ready to be given to the protobuf library.
   */ prepareSerialize() {
        return {
            key: this.key,
            value: this.value,
            timeReceived: this.timeReceived && utils.toRFC3339(this.timeReceived)
        };
    }
    /**
   * Decode a protobuf encoded record.
   *
   * @param {Uint8Array} raw
   */ static deserialize(raw) {
        const message = PBRecord.decode(raw);
        return Record.fromDeserialized(PBRecord.toObject(message, {
            defaults: false,
            arrays: true,
            longs: Number,
            objects: false
        }));
    }
    /**
   * Create a record from the raw object returned from the protobuf library.
   *
   * @param {{ [k: string]: any }} obj
   */ static fromDeserialized(obj) {
        let recvtime;
        if (obj.timeReceived) recvtime = utils.parseRFC3339(obj.timeReceived);
        const rec = new Record(obj.key, obj.value, recvtime);
        return rec;
    }
}
module.exports = Record;

},{"./record":"63Mf6","../utils":"79y6r"}],"63Mf6":[function(require,module,exports) {
/*eslint-disable*/ "use strict";
var $protobuf = require("protobufjs/minimal");
// Common aliases
var $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util;
// Exported root namespace
var $root = $protobuf.roots["libp2p-record"] || ($protobuf.roots["libp2p-record"] = {
});
$root.Record = (function() {
    /**
     * Properties of a Record.
     * @exports IRecord
     * @interface IRecord
     * @property {Uint8Array|null} [key] Record key
     * @property {Uint8Array|null} [value] Record value
     * @property {string|null} [timeReceived] Record timeReceived
     */ /**
     * Constructs a new Record.
     * @exports Record
     * @classdesc Represents a Record.
     * @implements IRecord
     * @constructor
     * @param {IRecord=} [p] Properties to set
     */ function Record(p) {
        if (p) {
            for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
        }
    }
    /**
     * Record key.
     * @member {Uint8Array} key
     * @memberof Record
     * @instance
     */ Record.prototype.key = $util.newBuffer([]);
    /**
     * Record value.
     * @member {Uint8Array} value
     * @memberof Record
     * @instance
     */ Record.prototype.value = $util.newBuffer([]);
    /**
     * Record timeReceived.
     * @member {string} timeReceived
     * @memberof Record
     * @instance
     */ Record.prototype.timeReceived = "";
    /**
     * Encodes the specified Record message. Does not implicitly {@link Record.verify|verify} messages.
     * @function encode
     * @memberof Record
     * @static
     * @param {IRecord} m Record message or plain object to encode
     * @param {$protobuf.Writer} [w] Writer to encode to
     * @returns {$protobuf.Writer} Writer
     */ Record.encode = function encode(m, w) {
        if (!w) w = $Writer.create();
        if (m.key != null && Object.hasOwnProperty.call(m, "key")) w.uint32(10).bytes(m.key);
        if (m.value != null && Object.hasOwnProperty.call(m, "value")) w.uint32(18).bytes(m.value);
        if (m.timeReceived != null && Object.hasOwnProperty.call(m, "timeReceived")) w.uint32(42).string(m.timeReceived);
        return w;
    };
    /**
     * Decodes a Record message from the specified reader or buffer.
     * @function decode
     * @memberof Record
     * @static
     * @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
     * @param {number} [l] Message length if known beforehand
     * @returns {Record} Record
     * @throws {Error} If the payload is not a reader or valid buffer
     * @throws {$protobuf.util.ProtocolError} If required fields are missing
     */ Record.decode = function decode(r, l) {
        if (!(r instanceof $Reader)) r = $Reader.create(r);
        var c = l === undefined ? r.len : r.pos + l, m = new $root.Record();
        while(r.pos < c){
            var t = r.uint32();
            switch(t >>> 3){
                case 1:
                    m.key = r.bytes();
                    break;
                case 2:
                    m.value = r.bytes();
                    break;
                case 5:
                    m.timeReceived = r.string();
                    break;
                default:
                    r.skipType(t & 7);
                    break;
            }
        }
        return m;
    };
    /**
     * Creates a Record message from a plain object. Also converts values to their respective internal types.
     * @function fromObject
     * @memberof Record
     * @static
     * @param {Object.<string,*>} d Plain object
     * @returns {Record} Record
     */ Record.fromObject = function fromObject(d) {
        if (d instanceof $root.Record) return d;
        var m = new $root.Record();
        if (d.key != null) {
            if (typeof d.key === "string") $util.base64.decode(d.key, m.key = $util.newBuffer($util.base64.length(d.key)), 0);
            else if (d.key.length) m.key = d.key;
        }
        if (d.value != null) {
            if (typeof d.value === "string") $util.base64.decode(d.value, m.value = $util.newBuffer($util.base64.length(d.value)), 0);
            else if (d.value.length) m.value = d.value;
        }
        if (d.timeReceived != null) m.timeReceived = String(d.timeReceived);
        return m;
    };
    /**
     * Creates a plain object from a Record message. Also converts values to other types if specified.
     * @function toObject
     * @memberof Record
     * @static
     * @param {Record} m Record
     * @param {$protobuf.IConversionOptions} [o] Conversion options
     * @returns {Object.<string,*>} Plain object
     */ Record.toObject = function toObject(m, o) {
        if (!o) o = {
        };
        var d = {
        };
        if (o.defaults) {
            if (o.bytes === String) d.key = "";
            else {
                d.key = [];
                if (o.bytes !== Array) d.key = $util.newBuffer(d.key);
            }
            if (o.bytes === String) d.value = "";
            else {
                d.value = [];
                if (o.bytes !== Array) d.value = $util.newBuffer(d.value);
            }
            d.timeReceived = "";
        }
        if (m.key != null && m.hasOwnProperty("key")) d.key = o.bytes === String ? $util.base64.encode(m.key, 0, m.key.length) : o.bytes === Array ? Array.prototype.slice.call(m.key) : m.key;
        if (m.value != null && m.hasOwnProperty("value")) d.value = o.bytes === String ? $util.base64.encode(m.value, 0, m.value.length) : o.bytes === Array ? Array.prototype.slice.call(m.value) : m.value;
        if (m.timeReceived != null && m.hasOwnProperty("timeReceived")) d.timeReceived = m.timeReceived;
        return d;
    };
    /**
     * Converts this Record to JSON.
     * @function toJSON
     * @memberof Record
     * @instance
     * @returns {Object.<string,*>} JSON object
     */ Record.prototype.toJSON = function toJSON() {
        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
    };
    return Record;
})();
module.exports = $root;

},{"protobufjs/minimal":"9Jmso"}],"79y6r":[function(require,module,exports) {
'use strict';
/**
 * Convert a JavaScript date into an `RFC3339Nano` formatted
 * string.
 *
 * @param {Date} time
 */ module.exports.toRFC3339 = (time)=>{
    const year = time.getUTCFullYear();
    const month = String(time.getUTCMonth() + 1).padStart(2, '0');
    const day = String(time.getUTCDate()).padStart(2, '0');
    const hour = String(time.getUTCHours()).padStart(2, '0');
    const minute = String(time.getUTCMinutes()).padStart(2, '0');
    const seconds = String(time.getUTCSeconds()).padStart(2, '0');
    const milliseconds = time.getUTCMilliseconds();
    const nanoseconds = milliseconds * 1000000;
    return `${year}-${month}-${day}T${hour}:${minute}:${seconds}.${nanoseconds}Z`;
};
/**
 * Parses a date string formatted as `RFC3339Nano` into a
 * JavaScript Date object.
 *
 * @param {string} time
 */ module.exports.parseRFC3339 = (time)=>{
    const rfc3339Matcher = new RegExp(// 2006-01-02T
    "(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})\\.(\\d+)Z");
    const m = String(time).trim().match(rfc3339Matcher);
    if (!m) throw new Error('Invalid format');
    const year = parseInt(m[1], 10);
    const month = parseInt(m[2], 10) - 1;
    const date = parseInt(m[3], 10);
    const hour = parseInt(m[4], 10);
    const minute = parseInt(m[5], 10);
    const second = parseInt(m[6], 10);
    const millisecond = parseInt(m[7].slice(0, -6), 10);
    return new Date(Date.UTC(year, month, date, hour, minute, second, millisecond));
};

},{}],"7fUE7":[function(require,module,exports) {
'use strict';
const errcode = require('err-code');
const { toString: uint8ArrayToString  } = require('uint8arrays/to-string');
/**
 * @typedef {import('./record')} Record
 */ /**
 * Checks a record and ensures it is still valid.
 * It runs the needed validators.
 * If verification fails the returned Promise will reject with the error.
 *
 * @param {import('libp2p-interfaces/src/types').DhtValidators} validators
 * @param {Record} record
 */ const verifyRecord = (validators, record)=>{
    const key = record.key;
    const keyString = uint8ArrayToString(key);
    const parts = keyString.split('/');
    if (parts.length < 3) // No validator available
    return;
    const validator = validators[parts[1].toString()];
    if (!validator) {
        const errMsg = 'Invalid record keytype';
        throw errcode(new Error(errMsg), 'ERR_INVALID_RECORD_KEY_TYPE');
    }
    return validator.func(key, record.value);
};
module.exports = {
    verifyRecord: verifyRecord,
    validators: require('./validators')
};

},{"err-code":"eQvyh","uint8arrays/to-string":"g3mCQ","./validators":"dsJ8Z"}],"dsJ8Z":[function(require,module,exports) {
'use strict';
module.exports = {
    pk: require('./public-key')
};

},{"./public-key":"ko33F"}],"ko33F":[function(require,module,exports) {
'use strict';
const { sha256  } = require('multiformats/hashes/sha2');
const errcode = require('err-code');
const { toString: uint8ArrayToString  } = require('uint8arrays/to-string');
const { equals: uint8ArrayEquals  } = require('uint8arrays/equals');
/**
 * Validator for public key records.
 * Verifies that the passed in record value is the PublicKey
 * that matches the passed in key.
 * If validation fails the returned Promise will reject with the error.
 *
 * @param {Uint8Array} key - A valid key is of the form `'/pk/<keymultihash>'`
 * @param {Uint8Array} publicKey - The public key to validate against (protobuf encoded).
 */ const validatePublicKeyRecord = async (key, publicKey)=>{
    if (!(key instanceof Uint8Array)) throw errcode(new Error('"key" must be a Uint8Array'), 'ERR_INVALID_RECORD_KEY_NOT_BUFFER');
    if (key.byteLength < 5) throw errcode(new Error('invalid public key record'), 'ERR_INVALID_RECORD_KEY_TOO_SHORT');
    const prefix = uint8ArrayToString(key.subarray(0, 4));
    if (prefix !== '/pk/') throw errcode(new Error('key was not prefixed with /pk/'), 'ERR_INVALID_RECORD_KEY_BAD_PREFIX');
    const keyhash = key.slice(4);
    const publicKeyHash = await sha256.digest(publicKey);
    if (!uint8ArrayEquals(keyhash, publicKeyHash.bytes)) throw errcode(new Error('public key does not match passed in key'), 'ERR_INVALID_RECORD_HASH_MISMATCH');
};
module.exports = {
    func: validatePublicKeyRecord,
    sign: false
};

},{"multiformats/hashes/sha2":"i8JnP","err-code":"eQvyh","uint8arrays/to-string":"g3mCQ","uint8arrays/equals":"fjLeN"}],"d75WG":[function(require,module,exports) {
'use strict';
const errcode = require('err-code');
const { toString: uint8ArrayToString  } = require('uint8arrays/to-string');
/**
 * Select the best record out of the given records.
 *
 * @param {import('libp2p-interfaces/src/types').DhtSelectors} selectors
 * @param {Uint8Array} k
 * @param {Array<Uint8Array>} records
 */ const bestRecord = (selectors, k, records)=>{
    if (records.length === 0) {
        const errMsg = 'No records given';
        throw errcode(new Error(errMsg), 'ERR_NO_RECORDS_RECEIVED');
    }
    const kStr = uint8ArrayToString(k);
    const parts = kStr.split('/');
    if (parts.length < 3) {
        const errMsg = 'Record key does not have a selector function';
        throw errcode(new Error(errMsg), 'ERR_NO_SELECTOR_FUNCTION_FOR_RECORD_KEY');
    }
    const selector = selectors[parts[1].toString()];
    if (!selector) {
        const errMsg = `Unrecognized key prefix: ${parts[1]}`;
        throw errcode(new Error(errMsg), 'ERR_UNRECOGNIZED_KEY_PREFIX');
    }
    if (records.length === 1) return 0;
    return selector(k, records);
};
module.exports = {
    bestRecord: bestRecord,
    selectors: require('./selectors')
};

},{"err-code":"eQvyh","uint8arrays/to-string":"g3mCQ","./selectors":"3KD9o"}],"3KD9o":[function(require,module,exports) {
'use strict';
module.exports = {
    pk: require('./public-key')
};

},{"./public-key":"88D8n"}],"88D8n":[function(require,module,exports) {
'use strict';
/**
 * Best record selector, for public key records.
 * Simply returns the first record, as all valid public key
 * records are equal.
 *
 * @param {Uint8Array} k
 * @param {Array<Uint8Array>} records
 */ const publicKeySelector = (k, records)=>{
    return 0;
};
module.exports = publicKeySelector;

},{}],"deZ7j":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var publish = require('./publish.js');
var resolve = require('./resolve.js');
var index = require('./pubsub/index.js');
class NameAPI {
    constructor({ dns , ipns , repo , codecs , peerId , isOnline , keychain , options  }){
        this.publish = publish.createPublish({
            ipns,
            repo,
            codecs,
            peerId,
            isOnline,
            keychain
        });
        this.resolve = resolve.createResolve({
            dns,
            ipns,
            peerId,
            isOnline,
            options
        });
        this.pubsub = new index.PubSubAPI({
            ipns,
            options
        });
    }
}
exports.NameAPI = NameAPI;

},{"./publish.js":"1R80K","./resolve.js":"jaA2T","./pubsub/index.js":"aw8tE"}],"1R80K":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var debug = require('debug');
var parseDuration = require('parse-duration');
var crypto = require('libp2p-crypto');
var errCode = require('err-code');
var fromString = require('uint8arrays/from-string');
var toString = require('uint8arrays/to-string');
var utils = require('../../utils.js');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
var utils$1 = require('./utils.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
var parseDuration__default = /*#__PURE__*/ _interopDefaultLegacy(parseDuration);
var crypto__default = /*#__PURE__*/ _interopDefaultLegacy(crypto);
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
const log = Object.assign(debug__default['default']('ipfs:name:publish'), {
    error: debug__default['default']('ipfs:name:publish:error')
});
function createPublish({ ipns , repo , codecs , peerId , isOnline , keychain  }) {
    const lookupKey = async (keyName)=>{
        if (keyName === 'self') return peerId.privKey;
        try {
            const pem = await keychain.exportKey(keyName, 'temp');
            const privateKey = await crypto__default['default'].keys.import(pem, 'temp');
            return privateKey;
        } catch (err) {
            log.error(err);
            throw errCode__default['default'](err, 'ERR_CANNOT_GET_KEY');
        }
    };
    async function publish(value, options = {
    }) {
        const resolve = !(options.resolve === false);
        const lifetime = options.lifetime || '24h';
        const key = options.key || 'self';
        if (!isOnline()) throw errCode__default['default'](new Error(utils.OFFLINE_ERROR), 'OFFLINE_ERROR');
        try {
            value = utils.normalizePath(value);
        } catch (err) {
            log.error(err);
            throw err;
        }
        let pubLifetime = 0;
        try {
            pubLifetime = parseDuration__default['default'](lifetime) || 0;
            pubLifetime = parseFloat(pubLifetime.toFixed(6));
        } catch (err1) {
            log.error(err1);
            throw err1;
        }
        const results = await Promise.all([
            lookupKey(key),
            resolve ? utils$1.resolvePath({
                ipns,
                repo,
                codecs
            }, value) : Promise.resolve()
        ]);
        const bytes = fromString.fromString(value);
        const result = await ipns.publish(results[0], bytes, pubLifetime);
        return {
            name: result.name,
            value: toString.toString(result.value)
        };
    }
    return withTimeoutOption.withTimeoutOption(publish);
}
exports.createPublish = createPublish;

},{"debug":"lWlU4","parse-duration":"2Fbu7","libp2p-crypto":"hsRcr","err-code":"eQvyh","uint8arrays/from-string":"lo45E","uint8arrays/to-string":"g3mCQ","../../utils.js":"4LLx8","ipfs-core-utils/with-timeout-option":"5AiVw","./utils.js":"1UwNQ"}],"1UwNQ":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var isIpfs = require('is-ipfs');
var toCidAndPath = require('ipfs-core-utils/to-cid-and-path');
var drain = require('it-drain');
var utils = require('../../utils.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var isIpfs__default = /*#__PURE__*/ _interopDefaultLegacy(isIpfs);
var drain__default = /*#__PURE__*/ _interopDefaultLegacy(drain);
async function resolvePath({ ipns , repo , codecs  }, name, options) {
    if (isIpfs__default['default'].ipnsPath(name)) return ipns.resolve(name);
    const { cid , path  } = toCidAndPath.toCidAndPath(name);
    await drain__default['default'](utils.resolve(cid, path || '', codecs, repo, options));
}
exports.resolvePath = resolvePath;

},{"is-ipfs":"2Nskw","ipfs-core-utils/to-cid-and-path":"5zZPz","it-drain":"h63K2","../../utils.js":"4LLx8"}],"jaA2T":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var debug = require('debug');
var errCode = require('err-code');
var mergeOpts = require('merge-options');
var cid = require('multiformats/cid');
var PeerId = require('peer-id');
var isDomain = require('is-domain-name');
var toString = require('uint8arrays/to-string');
var utils = require('../../utils.js');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
var mergeOpts__default = /*#__PURE__*/ _interopDefaultLegacy(mergeOpts);
var PeerId__default = /*#__PURE__*/ _interopDefaultLegacy(PeerId);
var isDomain__default = /*#__PURE__*/ _interopDefaultLegacy(isDomain);
const mergeOptions = mergeOpts__default['default'].bind({
    ignoreUndefined: true
});
const log = Object.assign(debug__default['default']('ipfs:name:resolve'), {
    error: debug__default['default']('ipfs:name:resolve:error')
});
const appendRemainder = (result, remainder)=>remainder.length > 0 ? result + '/' + remainder.join('/') : result
;
function createResolve({ dns , ipns , peerId , isOnline , options: { offline  }  }) {
    async function* resolve(name, options = {
    }) {
        options = mergeOptions({
            nocache: false,
            recursive: true
        }, options);
        if (offline && options && options.nocache) throw errCode__default['default'](new Error('cannot specify both offline and nocache'), 'ERR_NOCACHE_AND_OFFLINE');
        if (!name) name = peerId.toB58String();
        if (!name.startsWith('/ipns/')) name = `/ipns/${name}`;
        const [namespace, hash, ...remainder] = name.slice(1).split('/');
        try {
            if (hash.substring(0, 1) === '1') PeerId__default['default'].parse(hash);
            else cid.CID.parse(hash);
        } catch (err) {
            if (isDomain__default['default'](hash)) {
                yield appendRemainder(await dns(hash, options), remainder);
                return;
            }
            log.error(err);
            throw errCode__default['default'](new Error('Invalid IPNS name'), 'ERR_IPNS_INVALID_NAME');
        }
        if (!isOnline() && !offline) throw errCode__default['default'](new Error(utils.OFFLINE_ERROR), 'OFFLINE_ERROR');
        const value = await ipns.resolve(`/${namespace}/${hash}`, options);
        yield appendRemainder(value instanceof Uint8Array ? toString.toString(value) : value, remainder);
    }
    return withTimeoutOption.withTimeoutOption(resolve);
}
exports.createResolve = createResolve;

},{"debug":"lWlU4","err-code":"eQvyh","merge-options":"8VjFj","multiformats/cid":"fJJnW","peer-id":"4VGWt","is-domain-name":"9eNw9","uint8arrays/to-string":"g3mCQ","../../utils.js":"4LLx8","ipfs-core-utils/with-timeout-option":"5AiVw"}],"9eNw9":[function(require,module,exports) {
'use strict';
// Adapted from RFC 2181 (See section 11)
//
// The RFC defines a Domain Name to be at most 255 chars including seperators
// between labels.
// Subdomains are labels plus a seperator. A label is a string starting and
// ending with an alphanum, with dashes allowed in the middle. It is between 1 and 63 chars.
//
// We make some assumptions below that go beyond the RFC. We assume the TLD
// to be at least 2 chars. The regex also allows domains longer than 255 chars,
// but allows at most 127 subdomains, as assuming a lower-bound of one char per
// subdomain will yield 252, and adding a TLD of 2 chars sums to 254.
/*
(?:                   // Group 1: This is for subdomain, which is composed of a label and a seperator (length = [1, 63] + 1)
  [a-z0-9]
  (?:
    [a-z0-9\-]{0,61} // Limited to 61 chars as we have at least two chars if we reach this group (61 + 2 = 63 which is the limit)
    [a-z0-9]
  )?
  \.                  // Label seperator
){0,126}             // If we assume the lower-bound of 1 char labels, we can at most have 126 groups before approaching the total limit of 255 chars
(?:                   // Group 2: Assume that the TLD is at least 2 chars (for sanity)
  [a-z0-9]
  [a-z0-9\-]{0,61}
  [a-z0-9]
)
\.?                   // Some consider a trailing dot to be considered valid as it signifies the root of the domain tree
 */ var domainNameRegex = /^(?:[a-z0-9](?:[a-z0-9\-]{0,61}[a-z0-9])?\.){0,126}(?:[a-z0-9](?:[a-z0-9\-]{0,61}[a-z0-9]))\.?$/i;
/**
 * Test whether a string is a valid domain name, optionally checking for a root dot as well
 * @param  {String}  domainName
 * @param  {Boolean} rootDot    Check for a root dot eg. 'example.com.'. Defaults to false
 * @return {Boolean}
 */ module.exports = function isDomainName(domainName, rootDot) {
    if (rootDot == null) rootDot = false;
    if (domainName.length < 2) return false;
    if (domainName.length > 255) return false;
    var lastChar = domainName[domainName.length - 1];
    if (rootDot) {
        if (lastChar !== '.') return false;
    } else {
        if (lastChar === '.') return false;
    }
    return domainNameRegex.test(domainName);
};

},{}],"aw8tE":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cancel = require('./cancel.js');
var state = require('./state.js');
var subs = require('./subs.js');
class PubSubAPI {
    constructor({ ipns , options  }){
        this.cancel = cancel.createCancel({
            ipns,
            options
        });
        this.state = state.createState({
            ipns,
            options
        });
        this.subs = subs.createSubs({
            ipns,
            options
        });
    }
}
exports.PubSubAPI = PubSubAPI;

},{"./cancel.js":"gcLR1","./state.js":"5ouuo","./subs.js":"ibqdF"}],"gcLR1":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var utils = require('./utils.js');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function createCancel({ ipns , options: options1  }) {
    const experimental = options1.EXPERIMENTAL;
    async function cancel(name, options = {
    }) {
        const pubsub = utils.getPubsubRouting(ipns, experimental);
        return pubsub.cancel(name, options);
    }
    return withTimeoutOption.withTimeoutOption(cancel);
}
exports.createCancel = createCancel;

},{"./utils.js":"8QmAA","ipfs-core-utils/with-timeout-option":"5AiVw"}],"8QmAA":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var pubsubDatastore = require('../../../ipns/routing/pubsub-datastore.js');
var errCode = require('err-code');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
function getPubsubRouting(ipns, options) {
    if (!ipns || !(options && options.ipnsPubsub)) throw errCode__default['default'](new Error('IPNS pubsub subsystem is not enabled'), 'ERR_IPNS_PUBSUB_NOT_ENABLED');
    if (ipns.routing instanceof pubsubDatastore.IpnsPubsubDatastore) return ipns.routing;
    const pubsub = (ipns.routing.stores || []).find((s)=>s instanceof pubsubDatastore.IpnsPubsubDatastore
    );
    if (!pubsub) throw errCode__default['default'](new Error('IPNS pubsub datastore not found'), 'ERR_PUBSUB_DATASTORE_NOT_FOUND');
    return pubsub;
}
exports.getPubsubRouting = getPubsubRouting;

},{"../../../ipns/routing/pubsub-datastore.js":"fXbYO","err-code":"eQvyh"}],"5ouuo":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var utils = require('./utils.js');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function createState({ ipns , options  }) {
    const experimental = options.EXPERIMENTAL;
    async function state(_options = {
    }) {
        try {
            return {
                enabled: Boolean(utils.getPubsubRouting(ipns, experimental))
            };
        } catch (err) {
            return {
                enabled: false
            };
        }
    }
    return withTimeoutOption.withTimeoutOption(state);
}
exports.createState = createState;

},{"./utils.js":"8QmAA","ipfs-core-utils/with-timeout-option":"5AiVw"}],"ibqdF":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var utils = require('./utils.js');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function createSubs({ ipns , options: options1  }) {
    const experimental = options1.EXPERIMENTAL;
    async function subs(options = {
    }) {
        const pubsub = utils.getPubsubRouting(ipns, experimental);
        return pubsub.getSubscriptions(options);
    }
    return withTimeoutOption.withTimeoutOption(subs);
}
exports.createSubs = createSubs;

},{"./utils.js":"8QmAA","ipfs-core-utils/with-timeout-option":"5AiVw"}],"baWA4":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var dagPB = require('@ipld/dag-pb');
var Errors = require('datastore-core/errors');
var toCidAndPath = require('ipfs-core-utils/to-cid-and-path');
var cid1 = require('multiformats/cid');
var TimeoutController = require('timeout-abort-controller');
var anySignal = require('any-signal');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n['default'] = e;
    return Object.freeze(n);
}
var dagPB__namespace = /*#__PURE__*/ _interopNamespace(dagPB);
var TimeoutController__default = /*#__PURE__*/ _interopDefaultLegacy(TimeoutController);
const ERR_NOT_FOUND = Errors.notFoundError().code;
const Format = {
    default: '<dst>',
    edges: '<src> -> <dst>'
};
function createRefs({ repo , codecs , resolve , preload  }) {
    async function* refs(ipfsPath, options = {
    }) {
        if (options.maxDepth === 0) return;
        if (options.edges && options.format && options.format !== Format.default) throw new Error('Cannot set edges to true and also specify format');
        options.format = options.edges ? Format.edges : options.format;
        if (typeof options.maxDepth !== 'number') options.maxDepth = options.recursive ? Infinity : 1;
        if (options.timeout) {
            const controller = new TimeoutController__default['default'](options.timeout);
            options.signal = anySignal.anySignal([
                options.signal,
                controller.signal
            ]);
        }
        const rawPaths = Array.isArray(ipfsPath) ? ipfsPath : [
            ipfsPath
        ];
        const paths = rawPaths.map((p)=>getFullPath(preload, p, options)
        );
        for (const path of paths)try {
            yield* refsStream(resolve, repo, codecs, path, options);
        } catch (err) {
            yield {
                ref: '',
                err: err.message
            };
        }
    }
    return refs;
}
function getFullPath(preload, ipfsPath, options) {
    const { cid , path  } = toCidAndPath.toCidAndPath(ipfsPath);
    if (options.preload !== false) preload(cid);
    return `/ipfs/${cid}${path || ''}`;
}
async function* refsStream(resolve, repo, codecs, path, options) {
    const resPath = await resolve(path, options);
    const { cid  } = toCidAndPath.toCidAndPath(resPath);
    const maxDepth = options.maxDepth != null ? options.maxDepth : Infinity;
    const unique = options.unique || false;
    for await (const obj of objectStream(repo, codecs, cid, maxDepth, unique, options)){
        if (!obj.parent) continue;
        if (obj.isDuplicate) continue;
        yield {
            ref: formatLink(obj.parent.cid, obj.node.cid, obj.node.name, options.format)
        };
    }
}
function formatLink(srcCid, dstCid, linkName = '', format = Format.default) {
    let out = format.replace(/<src>/g, srcCid.toString());
    out = out.replace(/<dst>/g, dstCid.toString());
    out = out.replace(/<linkname>/g, linkName);
    return out;
}
async function* objectStream(repo, codecs, rootCid, maxDepth, uniqueOnly, options) {
    const seen = new Set();
    async function* traverseLevel(parent, depth) {
        const nextLevelDepth = depth + 1;
        if (nextLevelDepth > maxDepth) return;
        try {
            for await (const link of getLinks(repo, codecs, parent.cid, options)){
                yield {
                    parent: parent,
                    node: link,
                    isDuplicate: uniqueOnly && seen.has(link.cid.toString())
                };
                if (uniqueOnly) seen.add(link.cid.toString());
                yield* traverseLevel(link, nextLevelDepth);
            }
        } catch (err) {
            if (err.code === ERR_NOT_FOUND) err.message = `Could not find object with CID: ${parent.cid}`;
            throw err;
        }
    }
    yield* traverseLevel({
        cid: rootCid
    }, 0);
}
async function* getLinks(repo, codecs, cid, options) {
    const block = await repo.blocks.get(cid, options);
    const codec = await codecs.getCodec(cid.code);
    const value = codec.decode(block);
    const isDagPb = cid.code === dagPB__namespace.code;
    const base = [];
    for (const [name, cid2] of links(value, base)){
        if (isDagPb) {
            const match = name.match(/^Links\/(\d+)\/Hash$/);
            if (match) {
                const index = Number(match[1]);
                if (index < value.Links.length) {
                    yield {
                        name: value.Links[index].Name,
                        cid: cid2
                    };
                    continue;
                }
            }
        }
        yield {
            name,
            cid: cid2
        };
    }
}
const links = function*(source, base) {
    if (source == null) return;
    if (source instanceof Uint8Array) return;
    for (const [key, value] of Object.entries(source)){
        const path = [
            ...base,
            key
        ];
        if (value != null && typeof value === 'object') {
            if (Array.isArray(value)) for (const [index, element] of value.entries()){
                const elementPath = [
                    ...path,
                    index
                ];
                const cid$1 = cid1.CID.asCID(element);
                if (cid$1) yield [
                    elementPath.join('/'),
                    cid$1
                ];
                else if (typeof element === 'object') yield* links(element, elementPath);
            }
            else {
                const cid$1 = cid1.CID.asCID(value);
                if (cid$1) yield [
                    path.join('/'),
                    cid$1
                ];
                else yield* links(value, path);
            }
        }
    }
    return [];
};
exports.Format = Format;
exports.createRefs = createRefs;

},{"@ipld/dag-pb":"e9gy2","datastore-core/errors":"hKmom","ipfs-core-utils/to-cid-and-path":"5zZPz","multiformats/cid":"fJJnW","timeout-abort-controller":"gYeUY","any-signal":"1586s"}],"dlxkt":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function createLocal({ repo  }) {
    async function* refsLocal(options = {
    }) {
        for await (const cid of repo.blocks.queryKeys({
        }, {
            signal: options.signal
        }))yield {
            ref: cid.toString()
        };
    }
    return withTimeoutOption.withTimeoutOption(refsLocal);
}
exports.createLocal = createLocal;

},{"ipfs-core-utils/with-timeout-option":"5AiVw"}],"8MrnJ":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var wantlist = require('./wantlist.js');
var wantlistForPeer = require('./wantlist-for-peer.js');
var unwant = require('./unwant.js');
var stat = require('./stat.js');
class BitswapAPI {
    constructor({ network  }){
        this.wantlist = wantlist.createWantlist({
            network
        });
        this.wantlistForPeer = wantlistForPeer.createWantlistForPeer({
            network
        });
        this.unwant = unwant.createUnwant({
            network
        });
        this.stat = stat.createStat({
            network
        });
    }
}
exports.BitswapAPI = BitswapAPI;

},{"./wantlist.js":"fAnRn","./wantlist-for-peer.js":"csffS","./unwant.js":"dDba9","./stat.js":"6sOnY"}],"fAnRn":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function createWantlist({ network  }) {
    async function wantlist(options = {
    }) {
        const { bitswap  } = await network.use(options);
        const list = bitswap.getWantlist();
        return Array.from(list).map((e)=>e[1].cid
        );
    }
    return withTimeoutOption.withTimeoutOption(wantlist);
}
exports.createWantlist = createWantlist;

},{"ipfs-core-utils/with-timeout-option":"5AiVw"}],"csffS":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var PeerId = require('peer-id');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var PeerId__default = /*#__PURE__*/ _interopDefaultLegacy(PeerId);
function createWantlistForPeer({ network  }) {
    async function wantlistForPeer(peerId, options = {
    }) {
        const { bitswap  } = await network.use(options);
        const list = bitswap.wantlistForPeer(PeerId__default['default'].createFromB58String(peerId));
        return Array.from(list).map((e)=>e[1].cid
        );
    }
    return withTimeoutOption.withTimeoutOption(wantlistForPeer);
}
exports.createWantlistForPeer = createWantlistForPeer;

},{"peer-id":"4VGWt","ipfs-core-utils/with-timeout-option":"5AiVw"}],"dDba9":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function createUnwant({ network  }) {
    async function unwant(cids, options = {
    }) {
        const { bitswap  } = await network.use(options);
        if (!Array.isArray(cids)) cids = [
            cids
        ];
        return bitswap.unwant(cids);
    }
    return withTimeoutOption.withTimeoutOption(unwant);
}
exports.createUnwant = createUnwant;

},{"ipfs-core-utils/with-timeout-option":"5AiVw"}],"6sOnY":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function createStat({ network  }) {
    async function stat(options = {
    }) {
        const bitswap = (await network.use(options)).bitswap;
        const snapshot = bitswap.stat().snapshot;
        return {
            provideBufLen: parseInt(snapshot.providesBufferLength.toString()),
            blocksReceived: BigInt(snapshot.blocksReceived.toString()),
            wantlist: Array.from(bitswap.getWantlist()).map((e)=>e[1].cid
            ),
            peers: bitswap.peers().map((id)=>id.toB58String()
            ),
            dupBlksReceived: BigInt(snapshot.dupBlksReceived.toString()),
            dupDataReceived: BigInt(snapshot.dupDataReceived.toString()),
            dataReceived: BigInt(snapshot.dataReceived.toString()),
            blocksSent: BigInt(snapshot.blocksSent.toString()),
            dataSent: BigInt(snapshot.dataSent.toString())
        };
    }
    return withTimeoutOption.withTimeoutOption(stat);
}
exports.createStat = createStat;

},{"ipfs-core-utils/with-timeout-option":"5AiVw"}],"dqIZu":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var add = require('./add.js');
var clear = require('./clear.js');
var list = require('./list.js');
var reset = require('./reset.js');
var rm = require('./rm.js');
class BootstrapAPI {
    constructor({ repo  }){
        this.add = add.createAdd({
            repo
        });
        this.list = list.createList({
            repo
        });
        this.rm = rm.createRm({
            repo
        });
        this.clear = clear.createClear({
            repo
        });
        this.reset = reset.createReset({
            repo
        });
    }
}
exports.BootstrapAPI = BootstrapAPI;

},{"./add.js":"7K5Z2","./clear.js":"8rQz0","./list.js":"9cNKp","./reset.js":"ghTPg","./rm.js":"4yJWd"}],"7K5Z2":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var utils = require('./utils.js');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function createAdd({ repo  }) {
    async function add(multiaddr, options = {
    }) {
        if (!utils.isValidMultiaddr(multiaddr)) throw new Error(`${multiaddr} is not a valid Multiaddr`);
        const config = await repo.config.getAll(options);
        const boostrappers = config.Bootstrap || [];
        boostrappers.push(multiaddr.toString());
        config.Bootstrap = Array.from(new Set(boostrappers)).sort((a, b)=>a.localeCompare(b)
        );
        await repo.config.replace(config);
        return {
            Peers: [
                multiaddr
            ]
        };
    }
    return withTimeoutOption.withTimeoutOption(add);
}
exports.createAdd = createAdd;

},{"./utils.js":"eZnuK","ipfs-core-utils/with-timeout-option":"5AiVw"}],"eZnuK":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var mafmt = require('mafmt');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var mafmt__default = /*#__PURE__*/ _interopDefaultLegacy(mafmt);
function isValidMultiaddr(ma) {
    try {
        return mafmt__default['default'].IPFS.matches(ma);
    } catch (err) {
        return false;
    }
}
exports.isValidMultiaddr = isValidMultiaddr;

},{"mafmt":"hdtcj"}],"8rQz0":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
var multiaddr = require('multiaddr');
function createClear({ repo  }) {
    async function clear(options = {
    }) {
        const config = await repo.config.getAll(options);
        const removed = config.Bootstrap || [];
        config.Bootstrap = [];
        await repo.config.replace(config);
        return {
            Peers: removed.map((ma)=>new multiaddr.Multiaddr(ma)
            )
        };
    }
    return withTimeoutOption.withTimeoutOption(clear);
}
exports.createClear = createClear;

},{"ipfs-core-utils/with-timeout-option":"5AiVw","multiaddr":"kOPrF"}],"9cNKp":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
var multiaddr = require('multiaddr');
function createList({ repo  }) {
    async function list(options = {
    }) {
        const peers = await repo.config.get('Bootstrap', options);
        return {
            Peers: (peers || []).map((ma)=>new multiaddr.Multiaddr(ma)
            )
        };
    }
    return withTimeoutOption.withTimeoutOption(list);
}
exports.createList = createList;

},{"ipfs-core-utils/with-timeout-option":"5AiVw","multiaddr":"kOPrF"}],"ghTPg":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var getDefaultConfig = require('ipfs-core-config/config');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
var multiaddr = require('multiaddr');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var getDefaultConfig__default = /*#__PURE__*/ _interopDefaultLegacy(getDefaultConfig);
function createReset({ repo  }) {
    async function reset(options = {
    }) {
        const config = await repo.config.getAll(options);
        config.Bootstrap = getDefaultConfig__default['default']().Bootstrap;
        await repo.config.replace(config);
        return {
            Peers: getDefaultConfig__default['default']().Bootstrap.map((ma)=>new multiaddr.Multiaddr(ma)
            )
        };
    }
    return withTimeoutOption.withTimeoutOption(reset);
}
exports.createReset = createReset;

},{"ipfs-core-config/config":"i1esH","ipfs-core-utils/with-timeout-option":"5AiVw","multiaddr":"kOPrF"}],"i1esH":[function(require,module,exports) {
'use strict';
var config_browser = ()=>({
        Addresses: {
            Swarm: [],
            Announce: [],
            NoAnnounce: [],
            API: '',
            Gateway: '',
            RPC: '',
            Delegates: [
                '/dns4/node0.delegate.ipfs.io/tcp/443/https',
                '/dns4/node1.delegate.ipfs.io/tcp/443/https',
                '/dns4/node2.delegate.ipfs.io/tcp/443/https',
                '/dns4/node3.delegate.ipfs.io/tcp/443/https'
            ]
        },
        Discovery: {
            MDNS: {
                Enabled: false,
                Interval: 10
            },
            webRTCStar: {
                Enabled: true
            }
        },
        Bootstrap: [
            '/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN',
            '/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb',
            '/dnsaddr/bootstrap.libp2p.io/p2p/QmZa1sAxajnQjVM8WjWXoMbmPd7NsWhfKsPkErzpm9wGkp',
            '/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa',
            '/dnsaddr/bootstrap.libp2p.io/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt',
            '/dns4/node0.preload.ipfs.io/tcp/443/wss/p2p/QmZMxNdpMkewiVZLMRxaNxUeZpDUb34pWjZ1kZvsd16Zic',
            '/dns4/node1.preload.ipfs.io/tcp/443/wss/p2p/Qmbut9Ywz9YEDrz8ySBSgWyJk41Uvm2QJPhwDJzJyGFsD6',
            '/dns4/node2.preload.ipfs.io/tcp/443/wss/p2p/QmV7gnbW5VTcJ3oyM2Xk1rdFBJ3kTkvxc87UFGsun29STS',
            '/dns4/node3.preload.ipfs.io/tcp/443/wss/p2p/QmY7JB6MQXhxHvq7dBDh4HpbH29v4yE9JRadAVpndvzySN'
        ],
        Pubsub: {
            Enabled: true
        },
        Swarm: {
            ConnMgr: {
                LowWater: 200,
                HighWater: 500
            },
            DisableNatPortMap: true
        },
        Routing: {
            Type: 'none'
        }
    })
;
module.exports = config_browser;

},{}],"4yJWd":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var utils = require('./utils.js');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function createRm({ repo  }) {
    async function rm(multiaddr, options = {
    }) {
        if (!utils.isValidMultiaddr(multiaddr)) throw new Error(`${multiaddr} is not a valid Multiaddr`);
        const config = await repo.config.getAll(options);
        config.Bootstrap = (config.Bootstrap || []).filter((ma)=>ma.toString() !== multiaddr.toString()
        );
        await repo.config.replace(config);
        return {
            Peers: [
                multiaddr
            ]
        };
    }
    return withTimeoutOption.withTimeoutOption(rm);
}
exports.createRm = createRm;

},{"./utils.js":"eZnuK","ipfs-core-utils/with-timeout-option":"5AiVw"}],"3VMpM":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var get = require('./get.js');
var put = require('./put.js');
var rm = require('./rm.js');
var stat = require('./stat.js');
class BlockAPI {
    constructor({ codecs , hashers , preload , repo  }){
        this.get = get.createGet({
            preload,
            repo
        });
        this.put = put.createPut({
            codecs,
            hashers,
            preload,
            repo
        });
        this.rm = rm.createRm({
            repo
        });
        this.stat = stat.createStat({
            preload,
            repo
        });
    }
}
exports.BlockAPI = BlockAPI;

},{"./get.js":"bftMK","./put.js":"73a3i","./rm.js":"gIFZ7","./stat.js":"lCezQ"}],"bftMK":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function createGet({ preload , repo  }) {
    async function get(cid, options = {
    }) {
        if (options.preload !== false) preload(cid);
        return repo.blocks.get(cid, options);
    }
    return withTimeoutOption.withTimeoutOption(get);
}
exports.createGet = createGet;

},{"ipfs-core-utils/with-timeout-option":"5AiVw"}],"73a3i":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function createPut({ codecs , hashers , repo , preload  }) {
    async function put(block, options = {
    }) {
        const release = options.pin ? await repo.gcLock.readLock() : null;
        try {
            const cidVersion = options.version != null ? options.version : 0;
            const codecName = options.format || (cidVersion === 0 ? 'dag-pb' : 'raw');
            const hasher = await hashers.getHasher(options.mhtype || 'sha2-256');
            const hash = await hasher.digest(block);
            const codec = await codecs.getCodec(codecName);
            const cid$1 = cid.CID.create(cidVersion, codec.code, hash);
            await repo.blocks.put(cid$1, block, {
                signal: options.signal
            });
            if (options.preload !== false) preload(cid$1);
            if (options.pin === true) await repo.pins.pinRecursively(cid$1, {
                signal: options.signal
            });
            return cid$1;
        } finally{
            if (release) release();
        }
    }
    return withTimeoutOption.withTimeoutOption(put);
}
exports.createPut = createPut;

},{"multiformats/cid":"fJJnW","ipfs-core-utils/with-timeout-option":"5AiVw"}],"gIFZ7":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var errCode = require('err-code');
var parallel = require('it-parallel');
var map = require('it-map');
var filter = require('it-filter');
var itPipe = require('it-pipe');
var utils = require('./utils.js');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
var parallel__default = /*#__PURE__*/ _interopDefaultLegacy(parallel);
var map__default = /*#__PURE__*/ _interopDefaultLegacy(map);
var filter__default = /*#__PURE__*/ _interopDefaultLegacy(filter);
const BLOCK_RM_CONCURRENCY = 8;
function createRm({ repo  }) {
    async function* rm(cids, options = {
    }) {
        if (!Array.isArray(cids)) cids = [
            cids
        ];
        const release = await repo.gcLock.writeLock();
        try {
            yield* itPipe.pipe(cids, (source)=>map__default['default'](source, (cid)=>{
                    return async ()=>{
                        cid = utils.cleanCid(cid);
                        const result = {
                            cid
                        };
                        try {
                            const has = await repo.blocks.has(cid);
                            if (!has) throw errCode__default['default'](new Error('block not found'), 'ERR_BLOCK_NOT_FOUND');
                            await repo.blocks.delete(cid);
                        } catch (err) {
                            if (!options.force) {
                                err.message = `cannot remove ${cid}: ${err.message}`;
                                result.error = err;
                            }
                        }
                        return result;
                    };
                })
            , (source)=>parallel__default['default'](source, BLOCK_RM_CONCURRENCY)
            , (source)=>filter__default['default'](source, ()=>!options.quiet
                )
            );
        } finally{
            release();
        }
    }
    return withTimeoutOption.withTimeoutOption(rm);
}
exports.createRm = createRm;

},{"err-code":"eQvyh","it-parallel":"7GFE7","it-map":"dOmp3","it-filter":"7NtwB","it-pipe":"4jukm","./utils.js":"6ZyYe","ipfs-core-utils/with-timeout-option":"5AiVw"}],"7GFE7":[function(require,module,exports) {
'use strict';
const defer = require('p-defer');
const EventEmitter = require('events').EventEmitter;
/**
 * Takes an (async) iterator that emits promise-returning functions,
 * invokes them in parallel and emits the results as they become available but
 * in the same order as the input
 *
 * @template T
 * @param {Iterable<() => Promise<T>> | AsyncIterable<() => Promise<T>>} source
 * @param {number} [concurrency=1]
 * @returns {AsyncIterable<T>}
 */ async function* parallel(source, concurrency = 1) {
    if (concurrency < 1) concurrency = 1;
    const emitter = new EventEmitter();
    /** @type {any[]} */ const ops = [];
    let slotAvailable = defer();
    let sourceFinished = false;
    let resultAvailable = defer();
    emitter.on('task-complete', ()=>{
        resultAvailable.resolve();
        resultAvailable = defer();
    });
    Promise.resolve().then(async ()=>{
        try {
            for await (const task of source){
                if (ops.length === concurrency) await slotAvailable.promise;
                /**
         * @type {any}
         */ const op = {
                    done: false
                };
                ops.push(op);
                task().then((result)=>{
                    op.done = true;
                    op.ok = true;
                    op.value = result;
                    emitter.emit('task-complete');
                }, (err)=>{
                    op.done = true;
                    op.err = err;
                    emitter.emit('task-complete');
                });
            }
            sourceFinished = true;
        } catch (err) {
            emitter.emit('task-complete');
        }
    });
    while(true){
        await resultAvailable.promise;
        while(ops.length && ops[0].done){
            const op = ops[0];
            ops.shift();
            if (op.ok) yield op.value;
            else throw op.err;
            slotAvailable.resolve();
            slotAvailable = defer();
        }
        if (sourceFinished && ops.length === 0) break;
    }
}
module.exports = parallel;

},{"p-defer":"gZqcC","events":"bHM3D"}],"gZqcC":[function(require,module,exports) {
'use strict';
const pDefer = ()=>{
    const deferred = {
    };
    deferred.promise = new Promise((resolve, reject)=>{
        deferred.resolve = resolve;
        deferred.reject = reject;
    });
    return deferred;
};
module.exports = pDefer;

},{}],"bHM3D":[function(require,module,exports) {
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
var R = typeof Reflect === 'object' ? Reflect : null;
var ReflectApply = R && typeof R.apply === 'function' ? R.apply : function ReflectApply(target, receiver, args) {
    return Function.prototype.apply.call(target, receiver, args);
};
var ReflectOwnKeys;
if (R && typeof R.ownKeys === 'function') ReflectOwnKeys = R.ownKeys;
else if (Object.getOwnPropertySymbols) ReflectOwnKeys = function ReflectOwnKeys(target) {
    return Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target));
};
else ReflectOwnKeys = function ReflectOwnKeys(target) {
    return Object.getOwnPropertyNames(target);
};
function ProcessEmitWarning(warning) {
    if (console && console.warn) console.warn(warning);
}
var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) {
    return value !== value;
};
function EventEmitter() {
    EventEmitter.init.call(this);
}
module.exports = EventEmitter;
module.exports.once = once;
// Backwards-compat with node 0.10.x
EventEmitter.EventEmitter = EventEmitter;
EventEmitter.prototype._events = undefined;
EventEmitter.prototype._eventsCount = 0;
EventEmitter.prototype._maxListeners = undefined;
// By default EventEmitters will print a warning if more than 10 listeners are
// added to it. This is a useful default which helps finding memory leaks.
var defaultMaxListeners = 10;
function checkListener(listener) {
    if (typeof listener !== 'function') throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener);
}
Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
    enumerable: true,
    get: function() {
        return defaultMaxListeners;
    },
    set: function(arg) {
        if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.');
        defaultMaxListeners = arg;
    }
});
EventEmitter.init = function() {
    if (this._events === undefined || this._events === Object.getPrototypeOf(this)._events) {
        this._events = Object.create(null);
        this._eventsCount = 0;
    }
    this._maxListeners = this._maxListeners || undefined;
};
// Obviously not all Emitters should be limited to 10. This function allows
// that to be increased. Set to zero for unlimited.
EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
    if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + '.');
    this._maxListeners = n;
    return this;
};
function _getMaxListeners(that) {
    if (that._maxListeners === undefined) return EventEmitter.defaultMaxListeners;
    return that._maxListeners;
}
EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
    return _getMaxListeners(this);
};
EventEmitter.prototype.emit = function emit(type) {
    var args = [];
    for(var i = 1; i < arguments.length; i++)args.push(arguments[i]);
    var doError = type === 'error';
    var events = this._events;
    if (events !== undefined) doError = doError && events.error === undefined;
    else if (!doError) return false;
    // If there is no 'error' event listener then throw.
    if (doError) {
        var er;
        if (args.length > 0) er = args[0];
        if (er instanceof Error) // Note: The comments on the `throw` lines are intentional, they show
        // up in Node's output if this results in an unhandled exception.
        throw er; // Unhandled 'error' event
        // At least give some kind of context to the user
        var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : ''));
        err.context = er;
        throw err; // Unhandled 'error' event
    }
    var handler = events[type];
    if (handler === undefined) return false;
    if (typeof handler === 'function') ReflectApply(handler, this, args);
    else {
        var len = handler.length;
        var listeners = arrayClone(handler, len);
        for(var i = 0; i < len; ++i)ReflectApply(listeners[i], this, args);
    }
    return true;
};
function _addListener(target, type, listener, prepend) {
    var m;
    var events;
    var existing;
    checkListener(listener);
    events = target._events;
    if (events === undefined) {
        events = target._events = Object.create(null);
        target._eventsCount = 0;
    } else {
        // To avoid recursion in the case that type === "newListener"! Before
        // adding it to the listeners, first emit "newListener".
        if (events.newListener !== undefined) {
            target.emit('newListener', type, listener.listener ? listener.listener : listener);
            // Re-assign `events` because a newListener handler could have caused the
            // this._events to be assigned to a new object
            events = target._events;
        }
        existing = events[type];
    }
    if (existing === undefined) {
        // Optimize the case of one listener. Don't need the extra array object.
        existing = events[type] = listener;
        ++target._eventsCount;
    } else {
        if (typeof existing === 'function') // Adding the second element, need to change to array.
        existing = events[type] = prepend ? [
            listener,
            existing
        ] : [
            existing,
            listener
        ];
        else if (prepend) existing.unshift(listener);
        else existing.push(listener);
        // Check for listener leak
        m = _getMaxListeners(target);
        if (m > 0 && existing.length > m && !existing.warned) {
            existing.warned = true;
            // No error code for this since it is a Warning
            // eslint-disable-next-line no-restricted-syntax
            var w = new Error('Possible EventEmitter memory leak detected. ' + existing.length + ' ' + String(type) + ' listeners ' + 'added. Use emitter.setMaxListeners() to ' + 'increase limit');
            w.name = 'MaxListenersExceededWarning';
            w.emitter = target;
            w.type = type;
            w.count = existing.length;
            ProcessEmitWarning(w);
        }
    }
    return target;
}
EventEmitter.prototype.addListener = function addListener(type, listener) {
    return _addListener(this, type, listener, false);
};
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
EventEmitter.prototype.prependListener = function prependListener(type, listener) {
    return _addListener(this, type, listener, true);
};
function onceWrapper() {
    if (!this.fired) {
        this.target.removeListener(this.type, this.wrapFn);
        this.fired = true;
        if (arguments.length === 0) return this.listener.call(this.target);
        return this.listener.apply(this.target, arguments);
    }
}
function _onceWrap(target, type, listener) {
    var state = {
        fired: false,
        wrapFn: undefined,
        target: target,
        type: type,
        listener: listener
    };
    var wrapped = onceWrapper.bind(state);
    wrapped.listener = listener;
    state.wrapFn = wrapped;
    return wrapped;
}
EventEmitter.prototype.once = function once(type, listener) {
    checkListener(listener);
    this.on(type, _onceWrap(this, type, listener));
    return this;
};
EventEmitter.prototype.prependOnceListener = function prependOnceListener(type, listener) {
    checkListener(listener);
    this.prependListener(type, _onceWrap(this, type, listener));
    return this;
};
// Emits a 'removeListener' event if and only if the listener was removed.
EventEmitter.prototype.removeListener = function removeListener(type, listener) {
    var list, events, position, i, originalListener;
    checkListener(listener);
    events = this._events;
    if (events === undefined) return this;
    list = events[type];
    if (list === undefined) return this;
    if (list === listener || list.listener === listener) {
        if (--this._eventsCount === 0) this._events = Object.create(null);
        else {
            delete events[type];
            if (events.removeListener) this.emit('removeListener', type, list.listener || listener);
        }
    } else if (typeof list !== 'function') {
        position = -1;
        for(i = list.length - 1; i >= 0; i--)if (list[i] === listener || list[i].listener === listener) {
            originalListener = list[i].listener;
            position = i;
            break;
        }
        if (position < 0) return this;
        if (position === 0) list.shift();
        else spliceOne(list, position);
        if (list.length === 1) events[type] = list[0];
        if (events.removeListener !== undefined) this.emit('removeListener', type, originalListener || listener);
    }
    return this;
};
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
EventEmitter.prototype.removeAllListeners = function removeAllListeners(type) {
    var listeners, events, i;
    events = this._events;
    if (events === undefined) return this;
    // not listening for removeListener, no need to emit
    if (events.removeListener === undefined) {
        if (arguments.length === 0) {
            this._events = Object.create(null);
            this._eventsCount = 0;
        } else if (events[type] !== undefined) {
            if (--this._eventsCount === 0) this._events = Object.create(null);
            else delete events[type];
        }
        return this;
    }
    // emit removeListener for all listeners on all events
    if (arguments.length === 0) {
        var keys = Object.keys(events);
        var key;
        for(i = 0; i < keys.length; ++i){
            key = keys[i];
            if (key === 'removeListener') continue;
            this.removeAllListeners(key);
        }
        this.removeAllListeners('removeListener');
        this._events = Object.create(null);
        this._eventsCount = 0;
        return this;
    }
    listeners = events[type];
    if (typeof listeners === 'function') this.removeListener(type, listeners);
    else if (listeners !== undefined) // LIFO order
    for(i = listeners.length - 1; i >= 0; i--)this.removeListener(type, listeners[i]);
    return this;
};
function _listeners(target, type, unwrap) {
    var events = target._events;
    if (events === undefined) return [];
    var evlistener = events[type];
    if (evlistener === undefined) return [];
    if (typeof evlistener === 'function') return unwrap ? [
        evlistener.listener || evlistener
    ] : [
        evlistener
    ];
    return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
}
EventEmitter.prototype.listeners = function listeners(type) {
    return _listeners(this, type, true);
};
EventEmitter.prototype.rawListeners = function rawListeners(type) {
    return _listeners(this, type, false);
};
EventEmitter.listenerCount = function(emitter, type) {
    if (typeof emitter.listenerCount === 'function') return emitter.listenerCount(type);
    else return listenerCount.call(emitter, type);
};
EventEmitter.prototype.listenerCount = listenerCount;
function listenerCount(type) {
    var events = this._events;
    if (events !== undefined) {
        var evlistener = events[type];
        if (typeof evlistener === 'function') return 1;
        else if (evlistener !== undefined) return evlistener.length;
    }
    return 0;
}
EventEmitter.prototype.eventNames = function eventNames() {
    return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];
};
function arrayClone(arr, n) {
    var copy = new Array(n);
    for(var i = 0; i < n; ++i)copy[i] = arr[i];
    return copy;
}
function spliceOne(list, index) {
    for(; index + 1 < list.length; index++)list[index] = list[index + 1];
    list.pop();
}
function unwrapListeners(arr) {
    var ret = new Array(arr.length);
    for(var i = 0; i < ret.length; ++i)ret[i] = arr[i].listener || arr[i];
    return ret;
}
function once(emitter, name) {
    return new Promise(function(resolve, reject) {
        function errorListener(err) {
            emitter.removeListener(name, resolver);
            reject(err);
        }
        function resolver() {
            if (typeof emitter.removeListener === 'function') emitter.removeListener('error', errorListener);
            resolve([].slice.call(arguments));
        }
        eventTargetAgnosticAddListener(emitter, name, resolver, {
            once: true
        });
        if (name !== 'error') addErrorHandlerIfEventEmitter(emitter, errorListener, {
            once: true
        });
    });
}
function addErrorHandlerIfEventEmitter(emitter, handler, flags) {
    if (typeof emitter.on === 'function') eventTargetAgnosticAddListener(emitter, 'error', handler, flags);
}
function eventTargetAgnosticAddListener(emitter, name, listener, flags) {
    if (typeof emitter.on === 'function') {
        if (flags.once) emitter.once(name, listener);
        else emitter.on(name, listener);
    } else if (typeof emitter.addEventListener === 'function') // EventTarget does not have `error` event semantics like Node
    // EventEmitters, we do not listen for `error` events here.
    emitter.addEventListener(name, function wrapListener(arg) {
        // IE does not have builtin `{ once: true }` support so we
        // have to do it manually.
        if (flags.once) emitter.removeEventListener(name, wrapListener);
        listener(arg);
    });
    else throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type ' + typeof emitter);
}

},{}],"6ZyYe":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
function cleanCid(cid$1) {
    if (cid$1 instanceof Uint8Array) return cid.CID.decode(cid$1);
    return cid.CID.parse(cid$1.toString());
}
exports.cleanCid = cleanCid;

},{"multiformats/cid":"fJJnW"}],"lCezQ":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var utils = require('./utils.js');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function createStat({ repo , preload  }) {
    async function stat(cid, options = {
    }) {
        cid = utils.cleanCid(cid);
        if (options.preload !== false) preload(cid);
        const block = await repo.blocks.get(cid);
        return {
            cid,
            size: block.length
        };
    }
    return withTimeoutOption.withTimeoutOption(stat);
}
exports.createStat = createStat;

},{"./utils.js":"6ZyYe","ipfs-core-utils/with-timeout-option":"5AiVw"}],"9Zlor":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var add = require('./add.js');
var index = require('./add-all/index.js');
var cat = require('./cat.js');
var get = require('./get.js');
var ls = require('./ls.js');
class RootAPI {
    constructor({ preload , repo , options  }){
        const addAll = index.createAddAll({
            preload,
            repo,
            options
        });
        this.addAll = addAll;
        this.add = add.createAdd({
            addAll
        });
        this.cat = cat.createCat({
            repo,
            preload
        });
        this.get = get.createGet({
            repo,
            preload
        });
        this.ls = ls.createLs({
            repo,
            preload
        });
    }
}
exports.RootAPI = RootAPI;

},{"./add.js":"83hwn","./add-all/index.js":"i6cL7","./cat.js":"kwiZz","./get.js":"2cO9x","./ls.js":"8fBhO"}],"83hwn":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var last = require('it-last');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var last__default = /*#__PURE__*/ _interopDefaultLegacy(last);
function createAdd({ addAll  }) {
    async function add(entry, options = {
    }) {
        const result = await last__default['default'](addAll(entry, options));
        if (result == null) throw Error('Failed to add a file, if you see this please report a bug');
        return result;
    }
    return add;
}
exports.createAdd = createAdd;

},{"it-last":"7VTHF"}],"i6cL7":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var ipfsUnixfsImporter = require('ipfs-unixfs-importer');
var normaliseInput = require('ipfs-core-utils/files/normalise-input');
var utils = require('./utils.js');
var itPipe = require('it-pipe');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
var mergeOpts = require('merge-options');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var mergeOpts__default = /*#__PURE__*/ _interopDefaultLegacy(mergeOpts);
const mergeOptions = mergeOpts__default['default'].bind({
    ignoreUndefined: true
});
function createAddAll({ repo , preload , options: options1  }) {
    const isShardingEnabled = options1 && options1.sharding;
    async function* addAll(source1, options = {
    }) {
        const opts = mergeOptions({
            shardSplitThreshold: isShardingEnabled ? 1000 : Infinity,
            strategy: 'balanced'
        }, options, {
            ...utils.parseChunkerString(options.chunker)
        });
        if (opts.hashAlg && opts.hashAlg !== 'sha2-256' && opts.cidVersion !== 1) opts.cidVersion = 1;
        if (opts.trickle) opts.strategy = 'trickle';
        if (opts.strategy === 'trickle') {
            opts.leafType = 'raw';
            opts.reduceSingleLeafToSelf = false;
        }
        if (opts.cidVersion > 0 && opts.rawLeaves === undefined) opts.rawLeaves = true;
        if (opts.hashAlg !== undefined && opts.rawLeaves === undefined) opts.rawLeaves = true;
        delete opts.trickle;
        const totals = {
        };
        if (opts.progress) {
            const prog = opts.progress;
            opts.progress = (bytes, path)=>{
                if (!totals[path]) totals[path] = 0;
                totals[path] += bytes;
                prog(totals[path], path);
            };
        }
        const iterator = itPipe.pipe(normaliseInput.normaliseInput(source1), (source)=>ipfsUnixfsImporter.importer(source, repo.blocks, {
                ...opts,
                pin: false
            })
        , transformFile1(opts), preloadFile(preload, opts), pinFile(repo, opts));
        const releaseLock = await repo.gcLock.readLock();
        try {
            for await (const added of iterator){
                delete totals[added.path];
                yield added;
            }
        } finally{
            releaseLock();
        }
    }
    return withTimeoutOption.withTimeoutOption(addAll);
}
function transformFile1(opts) {
    async function* transformFile(source) {
        for await (const file of source){
            let cid = file.cid;
            if (opts.cidVersion === 1) cid = cid.toV1();
            let path = file.path ? file.path : cid.toString();
            if (opts.wrapWithDirectory && !file.path) path = '';
            yield {
                path,
                cid: cid,
                size: file.size,
                mode: file.unixfs && file.unixfs.mode,
                mtime: file.unixfs && file.unixfs.mtime
            };
        }
    }
    return transformFile;
}
function preloadFile(preload, opts) {
    async function* maybePreloadFile(source) {
        for await (const file of source){
            const isRootFile = !file.path || opts.wrapWithDirectory ? file.path === '' : !file.path.includes('/');
            const shouldPreload = isRootFile && !opts.onlyHash && opts.preload !== false;
            if (shouldPreload) preload(file.cid);
            yield file;
        }
    }
    return maybePreloadFile;
}
function pinFile(repo, opts) {
    async function* maybePinFile(source) {
        for await (const file of source){
            const isRootDir = !(file.path && file.path.includes('/'));
            const shouldPin = (opts.pin == null ? true : opts.pin) && isRootDir && !opts.onlyHash;
            if (shouldPin) await repo.pins.pinRecursively(file.cid);
            yield file;
        }
    }
    return maybePinFile;
}
exports.createAddAll = createAddAll;

},{"ipfs-unixfs-importer":"6sMoO","ipfs-core-utils/files/normalise-input":"43xHp","./utils.js":"9ToCa","it-pipe":"4jukm","ipfs-core-utils/with-timeout-option":"5AiVw","merge-options":"8VjFj"}],"6sMoO":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var parallelBatch = require('it-parallel-batch');
var options = require('./options.js');
var index = require('./dag-builder/index.js');
var treeBuilder = require('./tree-builder.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var parallelBatch__default = /*#__PURE__*/ _interopDefaultLegacy(parallelBatch);
async function* importer(source, blockstore, options$1 = {
}) {
    const opts = options(options$1);
    let dagBuilder;
    if (typeof options$1.dagBuilder === 'function') dagBuilder = options$1.dagBuilder;
    else dagBuilder = index;
    let treeBuilder$1;
    if (typeof options$1.treeBuilder === 'function') treeBuilder$1 = options$1.treeBuilder;
    else treeBuilder$1 = treeBuilder;
    let candidates;
    if (Symbol.asyncIterator in source || Symbol.iterator in source) candidates = source;
    else candidates = [
        source
    ];
    for await (const entry of treeBuilder$1(parallelBatch__default['default'](dagBuilder(candidates, blockstore, opts), opts.fileImportConcurrency), blockstore, opts))yield {
        cid: entry.cid,
        path: entry.path,
        unixfs: entry.unixfs,
        size: entry.size
    };
}
exports.importer = importer;

},{"it-parallel-batch":"4B5jX","./options.js":"bI6vZ","./dag-builder/index.js":"7kAcI","./tree-builder.js":"hIgvs"}],"4B5jX":[function(require,module,exports) {
'use strict';
const batch = require('it-batch');
/**
 * @template T
 * @typedef {{ok:true, value:T}} Success
 */ /**
 * @typedef {{ok:false, err:Error}} Failure
 */ /**
 * Takes an (async) iterator that emits promise-returning functions,
 * invokes them in parallel and emits the results as they become available but
 * in the same order as the input
 *
 * @template T
 * @param {AsyncIterable<() => Promise<T>>} source
 * @param {number} [size=1]
 * @returns {AsyncIterable<T>}
 */ async function* parallelBatch(source, size = 1) {
    for await (const tasks of batch(source, size)){
        /** @type {Promise<Success<T>|Failure>[]} */ const things = tasks.map(/**
       * @param {() => Promise<T>} p
       */ (p)=>{
            return p().then((value)=>({
                    ok: true,
                    value
                })
            , (err)=>({
                    ok: false,
                    err
                })
            );
        });
        for(let i = 0; i < things.length; i++){
            const result = await things[i];
            if (result.ok) yield result.value;
            else throw result.err;
        }
    }
}
module.exports = parallelBatch;

},{"it-batch":"7Ok44"}],"7Ok44":[function(require,module,exports) {
'use strict';
/**
 * Takes an (async) iterable that emits things and returns an async iterable that
 * emits those things in fixed-sized batches.
 *
 * @template T
 * @param {AsyncIterable<T>|Iterable<T>} source
 * @param {number} [size=1]
 * @returns {AsyncIterable<T[]>}
 */ async function* batch(source, size = 1) {
    /** @type {T[]} */ let things = [];
    if (size < 1) size = 1;
    for await (const thing of source){
        things.push(thing);
        while(things.length >= size){
            yield things.slice(0, size);
            things = things.slice(size);
        }
    }
    while(things.length){
        yield things.slice(0, size);
        things = things.slice(size);
    }
}
module.exports = batch;

},{}],"bI6vZ":[function(require,module,exports) {
'use strict';
var mergeOptions = require('merge-options');
var sha2 = require('multiformats/hashes/sha2');
var murmur3 = require('@multiformats/murmur3');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var mergeOptions__default = /*#__PURE__*/ _interopDefaultLegacy(mergeOptions);
async function hamtHashFn(buf) {
    return (await murmur3.murmur3128.encode(buf)).slice(0, 8).reverse();
}
const defaultOptions = {
    chunker: 'fixed',
    strategy: 'balanced',
    rawLeaves: false,
    onlyHash: false,
    reduceSingleLeafToSelf: true,
    hasher: sha2.sha256,
    leafType: 'file',
    cidVersion: 0,
    progress: ()=>()=>{
        }
    ,
    shardSplitThreshold: 1000,
    fileImportConcurrency: 50,
    blockWriteConcurrency: 10,
    minChunkSize: 262144,
    maxChunkSize: 262144,
    avgChunkSize: 262144,
    window: 16,
    polynomial: 17437180132763652,
    maxChildrenPerNode: 174,
    layerRepeat: 4,
    wrapWithDirectory: false,
    recursive: false,
    hidden: false,
    timeout: undefined,
    hamtHashFn,
    hamtHashCode: 34,
    hamtBucketBits: 8
};
var defaultOptions$1 = (options = {
})=>{
    const defaults = mergeOptions__default['default'].bind({
        ignoreUndefined: true
    });
    return defaults(defaultOptions, options);
};
module.exports = defaultOptions$1;

},{"merge-options":"8VjFj","multiformats/hashes/sha2":"i8JnP","@multiformats/murmur3":"dDuFh"}],"dDuFh":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var hasher = require('multiformats/hashes/hasher');
var multiformats = require('multiformats');
var mur = require('murmurhash3js-revisited');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var mur__default = /*#__PURE__*/ _interopDefaultLegacy(mur);
function fromNumberTo32BitBuf(number) {
    const bytes = new Array(4);
    for(let i = 0; i < 4; i++){
        bytes[i] = number & 255;
        number = number >> 8;
    }
    return new Uint8Array(bytes);
}
const murmur332 = hasher.from({
    name: 'murmur3-32',
    code: 35,
    encode: (input)=>fromNumberTo32BitBuf(mur__default["default"].x86.hash32(input))
});
const murmur3128 = hasher.from({
    name: 'murmur3-128',
    code: 34,
    encode: (input)=>multiformats.bytes.fromHex(mur__default["default"].x64.hash128(input))
});
exports.murmur3128 = murmur3128;
exports.murmur332 = murmur332;

},{"multiformats/hashes/hasher":"cjNRZ","multiformats":"8T5ng","murmurhash3js-revisited":"1KrtV"}],"1KrtV":[function(require,module,exports) {
module.exports = require('./lib/murmurHash3js');

},{"./lib/murmurHash3js":"bQuJu"}],"bQuJu":[function(require,module,exports) {
(function(root, undefined) {
    // Create a local object that'll be exported or referenced globally.
    var library = {
        'version': '3.0.0',
        'x86': {
        },
        'x64': {
        },
        'inputValidation': true
    };
    // PRIVATE FUNCTIONS
    // -----------------
    function _validBytes(bytes) {
        // check the input is an array or a typed array
        if (!Array.isArray(bytes) && !ArrayBuffer.isView(bytes)) return false;
        // check all bytes are actually bytes
        for(var i = 0; i < bytes.length; i++){
            if (!Number.isInteger(bytes[i]) || bytes[i] < 0 || bytes[i] > 255) return false;
        }
        return true;
    }
    function _x86Multiply(m, n) {
        //
        // Given two 32bit ints, returns the two multiplied together as a
        // 32bit int.
        //
        return (m & 65535) * n + (((m >>> 16) * n & 65535) << 16);
    }
    function _x86Rotl(m, n) {
        //
        // Given a 32bit int and an int representing a number of bit positions,
        // returns the 32bit int rotated left by that number of positions.
        //
        return m << n | m >>> 32 - n;
    }
    function _x86Fmix(h) {
        //
        // Given a block, returns murmurHash3's final x86 mix of that block.
        //
        h ^= h >>> 16;
        h = _x86Multiply(h, 2246822507);
        h ^= h >>> 13;
        h = _x86Multiply(h, 3266489909);
        h ^= h >>> 16;
        return h;
    }
    function _x64Add(m, n) {
        //
        // Given two 64bit ints (as an array of two 32bit ints) returns the two
        // added together as a 64bit int (as an array of two 32bit ints).
        //
        m = [
            m[0] >>> 16,
            m[0] & 65535,
            m[1] >>> 16,
            m[1] & 65535
        ];
        n = [
            n[0] >>> 16,
            n[0] & 65535,
            n[1] >>> 16,
            n[1] & 65535
        ];
        var o = [
            0,
            0,
            0,
            0
        ];
        o[3] += m[3] + n[3];
        o[2] += o[3] >>> 16;
        o[3] &= 65535;
        o[2] += m[2] + n[2];
        o[1] += o[2] >>> 16;
        o[2] &= 65535;
        o[1] += m[1] + n[1];
        o[0] += o[1] >>> 16;
        o[1] &= 65535;
        o[0] += m[0] + n[0];
        o[0] &= 65535;
        return [
            o[0] << 16 | o[1],
            o[2] << 16 | o[3]
        ];
    }
    function _x64Multiply(m, n) {
        //
        // Given two 64bit ints (as an array of two 32bit ints) returns the two
        // multiplied together as a 64bit int (as an array of two 32bit ints).
        //
        m = [
            m[0] >>> 16,
            m[0] & 65535,
            m[1] >>> 16,
            m[1] & 65535
        ];
        n = [
            n[0] >>> 16,
            n[0] & 65535,
            n[1] >>> 16,
            n[1] & 65535
        ];
        var o = [
            0,
            0,
            0,
            0
        ];
        o[3] += m[3] * n[3];
        o[2] += o[3] >>> 16;
        o[3] &= 65535;
        o[2] += m[2] * n[3];
        o[1] += o[2] >>> 16;
        o[2] &= 65535;
        o[2] += m[3] * n[2];
        o[1] += o[2] >>> 16;
        o[2] &= 65535;
        o[1] += m[1] * n[3];
        o[0] += o[1] >>> 16;
        o[1] &= 65535;
        o[1] += m[2] * n[2];
        o[0] += o[1] >>> 16;
        o[1] &= 65535;
        o[1] += m[3] * n[1];
        o[0] += o[1] >>> 16;
        o[1] &= 65535;
        o[0] += m[0] * n[3] + m[1] * n[2] + m[2] * n[1] + m[3] * n[0];
        o[0] &= 65535;
        return [
            o[0] << 16 | o[1],
            o[2] << 16 | o[3]
        ];
    }
    function _x64Rotl(m, n) {
        //
        // Given a 64bit int (as an array of two 32bit ints) and an int
        // representing a number of bit positions, returns the 64bit int (as an
        // array of two 32bit ints) rotated left by that number of positions.
        //
        n %= 64;
        if (n === 32) return [
            m[1],
            m[0]
        ];
        else if (n < 32) return [
            m[0] << n | m[1] >>> 32 - n,
            m[1] << n | m[0] >>> 32 - n
        ];
        else {
            n -= 32;
            return [
                m[1] << n | m[0] >>> 32 - n,
                m[0] << n | m[1] >>> 32 - n
            ];
        }
    }
    function _x64LeftShift(m, n) {
        //
        // Given a 64bit int (as an array of two 32bit ints) and an int
        // representing a number of bit positions, returns the 64bit int (as an
        // array of two 32bit ints) shifted left by that number of positions.
        //
        n %= 64;
        if (n === 0) return m;
        else if (n < 32) return [
            m[0] << n | m[1] >>> 32 - n,
            m[1] << n
        ];
        else return [
            m[1] << n - 32,
            0
        ];
    }
    function _x64Xor(m, n) {
        //
        // Given two 64bit ints (as an array of two 32bit ints) returns the two
        // xored together as a 64bit int (as an array of two 32bit ints).
        //
        return [
            m[0] ^ n[0],
            m[1] ^ n[1]
        ];
    }
    function _x64Fmix(h) {
        //
        // Given a block, returns murmurHash3's final x64 mix of that block.
        // (`[0, h[0] >>> 1]` is a 33 bit unsigned right shift. This is the
        // only place where we need to right shift 64bit ints.)
        //
        h = _x64Xor(h, [
            0,
            h[0] >>> 1
        ]);
        h = _x64Multiply(h, [
            4283543511,
            3981806797
        ]);
        h = _x64Xor(h, [
            0,
            h[0] >>> 1
        ]);
        h = _x64Multiply(h, [
            3301882366,
            444984403
        ]);
        h = _x64Xor(h, [
            0,
            h[0] >>> 1
        ]);
        return h;
    }
    // PUBLIC FUNCTIONS
    // ----------------
    library.x86.hash32 = function(bytes, seed) {
        //
        // Given a string and an optional seed as an int, returns a 32 bit hash
        // using the x86 flavor of MurmurHash3, as an unsigned int.
        //
        if (library.inputValidation && !_validBytes(bytes)) return undefined;
        seed = seed || 0;
        var remainder = bytes.length % 4;
        var blocks = bytes.length - remainder;
        var h1 = seed;
        var k1 = 0;
        var c1 = 3432918353;
        var c2 = 461845907;
        for(var i = 0; i < blocks; i = i + 4){
            k1 = bytes[i] | bytes[i + 1] << 8 | bytes[i + 2] << 16 | bytes[i + 3] << 24;
            k1 = _x86Multiply(k1, c1);
            k1 = _x86Rotl(k1, 15);
            k1 = _x86Multiply(k1, c2);
            h1 ^= k1;
            h1 = _x86Rotl(h1, 13);
            h1 = _x86Multiply(h1, 5) + 3864292196;
        }
        k1 = 0;
        switch(remainder){
            case 3:
                k1 ^= bytes[i + 2] << 16;
            case 2:
                k1 ^= bytes[i + 1] << 8;
            case 1:
                k1 ^= bytes[i];
                k1 = _x86Multiply(k1, c1);
                k1 = _x86Rotl(k1, 15);
                k1 = _x86Multiply(k1, c2);
                h1 ^= k1;
        }
        h1 ^= bytes.length;
        h1 = _x86Fmix(h1);
        return h1 >>> 0;
    };
    library.x86.hash128 = function(bytes, seed) {
        //
        // Given a string and an optional seed as an int, returns a 128 bit
        // hash using the x86 flavor of MurmurHash3, as an unsigned hex.
        //
        if (library.inputValidation && !_validBytes(bytes)) return undefined;
        seed = seed || 0;
        var remainder = bytes.length % 16;
        var blocks = bytes.length - remainder;
        var h1 = seed;
        var h2 = seed;
        var h3 = seed;
        var h4 = seed;
        var k1 = 0;
        var k2 = 0;
        var k3 = 0;
        var k4 = 0;
        var c1 = 597399067;
        var c2 = 2869860233;
        var c3 = 951274213;
        var c4 = 2716044179;
        for(var i = 0; i < blocks; i = i + 16){
            k1 = bytes[i] | bytes[i + 1] << 8 | bytes[i + 2] << 16 | bytes[i + 3] << 24;
            k2 = bytes[i + 4] | bytes[i + 5] << 8 | bytes[i + 6] << 16 | bytes[i + 7] << 24;
            k3 = bytes[i + 8] | bytes[i + 9] << 8 | bytes[i + 10] << 16 | bytes[i + 11] << 24;
            k4 = bytes[i + 12] | bytes[i + 13] << 8 | bytes[i + 14] << 16 | bytes[i + 15] << 24;
            k1 = _x86Multiply(k1, c1);
            k1 = _x86Rotl(k1, 15);
            k1 = _x86Multiply(k1, c2);
            h1 ^= k1;
            h1 = _x86Rotl(h1, 19);
            h1 += h2;
            h1 = _x86Multiply(h1, 5) + 1444728091;
            k2 = _x86Multiply(k2, c2);
            k2 = _x86Rotl(k2, 16);
            k2 = _x86Multiply(k2, c3);
            h2 ^= k2;
            h2 = _x86Rotl(h2, 17);
            h2 += h3;
            h2 = _x86Multiply(h2, 5) + 197830471;
            k3 = _x86Multiply(k3, c3);
            k3 = _x86Rotl(k3, 17);
            k3 = _x86Multiply(k3, c4);
            h3 ^= k3;
            h3 = _x86Rotl(h3, 15);
            h3 += h4;
            h3 = _x86Multiply(h3, 5) + 2530024501;
            k4 = _x86Multiply(k4, c4);
            k4 = _x86Rotl(k4, 18);
            k4 = _x86Multiply(k4, c1);
            h4 ^= k4;
            h4 = _x86Rotl(h4, 13);
            h4 += h1;
            h4 = _x86Multiply(h4, 5) + 850148119;
        }
        k1 = 0;
        k2 = 0;
        k3 = 0;
        k4 = 0;
        switch(remainder){
            case 15:
                k4 ^= bytes[i + 14] << 16;
            case 14:
                k4 ^= bytes[i + 13] << 8;
            case 13:
                k4 ^= bytes[i + 12];
                k4 = _x86Multiply(k4, c4);
                k4 = _x86Rotl(k4, 18);
                k4 = _x86Multiply(k4, c1);
                h4 ^= k4;
            case 12:
                k3 ^= bytes[i + 11] << 24;
            case 11:
                k3 ^= bytes[i + 10] << 16;
            case 10:
                k3 ^= bytes[i + 9] << 8;
            case 9:
                k3 ^= bytes[i + 8];
                k3 = _x86Multiply(k3, c3);
                k3 = _x86Rotl(k3, 17);
                k3 = _x86Multiply(k3, c4);
                h3 ^= k3;
            case 8:
                k2 ^= bytes[i + 7] << 24;
            case 7:
                k2 ^= bytes[i + 6] << 16;
            case 6:
                k2 ^= bytes[i + 5] << 8;
            case 5:
                k2 ^= bytes[i + 4];
                k2 = _x86Multiply(k2, c2);
                k2 = _x86Rotl(k2, 16);
                k2 = _x86Multiply(k2, c3);
                h2 ^= k2;
            case 4:
                k1 ^= bytes[i + 3] << 24;
            case 3:
                k1 ^= bytes[i + 2] << 16;
            case 2:
                k1 ^= bytes[i + 1] << 8;
            case 1:
                k1 ^= bytes[i];
                k1 = _x86Multiply(k1, c1);
                k1 = _x86Rotl(k1, 15);
                k1 = _x86Multiply(k1, c2);
                h1 ^= k1;
        }
        h1 ^= bytes.length;
        h2 ^= bytes.length;
        h3 ^= bytes.length;
        h4 ^= bytes.length;
        h1 += h2;
        h1 += h3;
        h1 += h4;
        h2 += h1;
        h3 += h1;
        h4 += h1;
        h1 = _x86Fmix(h1);
        h2 = _x86Fmix(h2);
        h3 = _x86Fmix(h3);
        h4 = _x86Fmix(h4);
        h1 += h2;
        h1 += h3;
        h1 += h4;
        h2 += h1;
        h3 += h1;
        h4 += h1;
        return ("00000000" + (h1 >>> 0).toString(16)).slice(-8) + ("00000000" + (h2 >>> 0).toString(16)).slice(-8) + ("00000000" + (h3 >>> 0).toString(16)).slice(-8) + ("00000000" + (h4 >>> 0).toString(16)).slice(-8);
    };
    library.x64.hash128 = function(bytes, seed) {
        //
        // Given a string and an optional seed as an int, returns a 128 bit
        // hash using the x64 flavor of MurmurHash3, as an unsigned hex.
        //
        if (library.inputValidation && !_validBytes(bytes)) return undefined;
        seed = seed || 0;
        var remainder = bytes.length % 16;
        var blocks = bytes.length - remainder;
        var h1 = [
            0,
            seed
        ];
        var h2 = [
            0,
            seed
        ];
        var k1 = [
            0,
            0
        ];
        var k2 = [
            0,
            0
        ];
        var c1 = [
            2277735313,
            289559509
        ];
        var c2 = [
            1291169091,
            658871167
        ];
        for(var i = 0; i < blocks; i = i + 16){
            k1 = [
                bytes[i + 4] | bytes[i + 5] << 8 | bytes[i + 6] << 16 | bytes[i + 7] << 24,
                bytes[i] | bytes[i + 1] << 8 | bytes[i + 2] << 16 | bytes[i + 3] << 24
            ];
            k2 = [
                bytes[i + 12] | bytes[i + 13] << 8 | bytes[i + 14] << 16 | bytes[i + 15] << 24,
                bytes[i + 8] | bytes[i + 9] << 8 | bytes[i + 10] << 16 | bytes[i + 11] << 24
            ];
            k1 = _x64Multiply(k1, c1);
            k1 = _x64Rotl(k1, 31);
            k1 = _x64Multiply(k1, c2);
            h1 = _x64Xor(h1, k1);
            h1 = _x64Rotl(h1, 27);
            h1 = _x64Add(h1, h2);
            h1 = _x64Add(_x64Multiply(h1, [
                0,
                5
            ]), [
                0,
                1390208809
            ]);
            k2 = _x64Multiply(k2, c2);
            k2 = _x64Rotl(k2, 33);
            k2 = _x64Multiply(k2, c1);
            h2 = _x64Xor(h2, k2);
            h2 = _x64Rotl(h2, 31);
            h2 = _x64Add(h2, h1);
            h2 = _x64Add(_x64Multiply(h2, [
                0,
                5
            ]), [
                0,
                944331445
            ]);
        }
        k1 = [
            0,
            0
        ];
        k2 = [
            0,
            0
        ];
        switch(remainder){
            case 15:
                k2 = _x64Xor(k2, _x64LeftShift([
                    0,
                    bytes[i + 14]
                ], 48));
            case 14:
                k2 = _x64Xor(k2, _x64LeftShift([
                    0,
                    bytes[i + 13]
                ], 40));
            case 13:
                k2 = _x64Xor(k2, _x64LeftShift([
                    0,
                    bytes[i + 12]
                ], 32));
            case 12:
                k2 = _x64Xor(k2, _x64LeftShift([
                    0,
                    bytes[i + 11]
                ], 24));
            case 11:
                k2 = _x64Xor(k2, _x64LeftShift([
                    0,
                    bytes[i + 10]
                ], 16));
            case 10:
                k2 = _x64Xor(k2, _x64LeftShift([
                    0,
                    bytes[i + 9]
                ], 8));
            case 9:
                k2 = _x64Xor(k2, [
                    0,
                    bytes[i + 8]
                ]);
                k2 = _x64Multiply(k2, c2);
                k2 = _x64Rotl(k2, 33);
                k2 = _x64Multiply(k2, c1);
                h2 = _x64Xor(h2, k2);
            case 8:
                k1 = _x64Xor(k1, _x64LeftShift([
                    0,
                    bytes[i + 7]
                ], 56));
            case 7:
                k1 = _x64Xor(k1, _x64LeftShift([
                    0,
                    bytes[i + 6]
                ], 48));
            case 6:
                k1 = _x64Xor(k1, _x64LeftShift([
                    0,
                    bytes[i + 5]
                ], 40));
            case 5:
                k1 = _x64Xor(k1, _x64LeftShift([
                    0,
                    bytes[i + 4]
                ], 32));
            case 4:
                k1 = _x64Xor(k1, _x64LeftShift([
                    0,
                    bytes[i + 3]
                ], 24));
            case 3:
                k1 = _x64Xor(k1, _x64LeftShift([
                    0,
                    bytes[i + 2]
                ], 16));
            case 2:
                k1 = _x64Xor(k1, _x64LeftShift([
                    0,
                    bytes[i + 1]
                ], 8));
            case 1:
                k1 = _x64Xor(k1, [
                    0,
                    bytes[i]
                ]);
                k1 = _x64Multiply(k1, c1);
                k1 = _x64Rotl(k1, 31);
                k1 = _x64Multiply(k1, c2);
                h1 = _x64Xor(h1, k1);
        }
        h1 = _x64Xor(h1, [
            0,
            bytes.length
        ]);
        h2 = _x64Xor(h2, [
            0,
            bytes.length
        ]);
        h1 = _x64Add(h1, h2);
        h2 = _x64Add(h2, h1);
        h1 = _x64Fmix(h1);
        h2 = _x64Fmix(h2);
        h1 = _x64Add(h1, h2);
        h2 = _x64Add(h2, h1);
        return ("00000000" + (h1[0] >>> 0).toString(16)).slice(-8) + ("00000000" + (h1[1] >>> 0).toString(16)).slice(-8) + ("00000000" + (h2[0] >>> 0).toString(16)).slice(-8) + ("00000000" + (h2[1] >>> 0).toString(16)).slice(-8);
    };
    // INITIALIZATION
    // --------------
    // Export murmurHash3 for CommonJS, either as an AMD module or just as part
    // of the global object.
    if (typeof exports !== 'undefined') {
        if (typeof module !== 'undefined' && module.exports) exports = module.exports = library;
        exports.murmurHash3 = library;
    } else if (typeof define === 'function' && define.amd) define([], function() {
        return library;
    });
    else {
        // Use murmurHash3.noConflict to restore `murmurHash3` back to its
        // original value. Returns a reference to the library object, to allow
        // it to be used under a different name.
        library._murmurHash3 = root.murmurHash3;
        library.noConflict = function() {
            root.murmurHash3 = library._murmurHash3;
            library._murmurHash3 = undefined;
            library.noConflict = undefined;
            return library;
        };
        root.murmurHash3 = library;
    }
})(this);

},{}],"7kAcI":[function(require,module,exports) {
'use strict';
var dir = require('./dir.js');
var index = require('./file/index.js');
var errCode = require('err-code');
var rabin = require('../chunker/rabin.js');
var fixedSize = require('../chunker/fixed-size.js');
var validateChunks = require('./validate-chunks.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
function isIterable(thing) {
    return Symbol.iterator in thing;
}
function isAsyncIterable(thing) {
    return Symbol.asyncIterator in thing;
}
function contentAsAsyncIterable(content) {
    try {
        if (content instanceof Uint8Array) return (async function*() {
            yield content;
        })();
        else if (isIterable(content)) return (async function*() {
            yield* content;
        })();
        else if (isAsyncIterable(content)) return content;
    } catch  {
        throw errCode__default['default'](new Error('Content was invalid'), 'ERR_INVALID_CONTENT');
    }
    throw errCode__default['default'](new Error('Content was invalid'), 'ERR_INVALID_CONTENT');
}
async function* dagBuilder(source, blockstore, options) {
    for await (const entry of source){
        if (entry.path) {
            if (entry.path.substring(0, 2) === './') options.wrapWithDirectory = true;
            entry.path = entry.path.split('/').filter((path)=>path && path !== '.'
            ).join('/');
        }
        if (entry.content) {
            let chunker;
            if (typeof options.chunker === 'function') chunker = options.chunker;
            else if (options.chunker === 'rabin') chunker = rabin;
            else chunker = fixedSize;
            let chunkValidator;
            if (typeof options.chunkValidator === 'function') chunkValidator = options.chunkValidator;
            else chunkValidator = validateChunks;
            const file = {
                path: entry.path,
                mtime: entry.mtime,
                mode: entry.mode,
                content: chunker(chunkValidator(contentAsAsyncIterable(entry.content), options), options)
            };
            yield ()=>index(file, blockstore, options)
            ;
        } else if (entry.path) {
            const dir$1 = {
                path: entry.path,
                mtime: entry.mtime,
                mode: entry.mode
            };
            yield ()=>dir(dir$1, blockstore, options)
            ;
        } else throw new Error('Import candidate must have content or path or both');
    }
}
module.exports = dagBuilder;

},{"./dir.js":"gJnm2","./file/index.js":"7ImKK","err-code":"eQvyh","../chunker/rabin.js":"ezzWb","../chunker/fixed-size.js":"2cwnx","./validate-chunks.js":"eOfW1"}],"gJnm2":[function(require,module,exports) {
'use strict';
var ipfsUnixfs = require('ipfs-unixfs');
var persist = require('../utils/persist.js');
var dagPb = require('@ipld/dag-pb');
const dirBuilder = async (item, blockstore, options)=>{
    const unixfs = new ipfsUnixfs.UnixFS({
        type: 'directory',
        mtime: item.mtime,
        mode: item.mode
    });
    const buffer = dagPb.encode(dagPb.prepare({
        Data: unixfs.marshal()
    }));
    const cid = await persist(buffer, blockstore, options);
    const path = item.path;
    return {
        cid,
        path,
        unixfs,
        size: buffer.length
    };
};
module.exports = dirBuilder;

},{"ipfs-unixfs":"fttXc","../utils/persist.js":"fagNy","@ipld/dag-pb":"e9gy2"}],"fagNy":[function(require,module,exports) {
'use strict';
var cid = require('multiformats/cid');
var dagPb = require('@ipld/dag-pb');
var sha2 = require('multiformats/hashes/sha2');
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n['default'] = e;
    return Object.freeze(n);
}
var dagPb__namespace = /*#__PURE__*/ _interopNamespace(dagPb);
const persist = async (buffer, blockstore, options)=>{
    if (!options.codec) options.codec = dagPb__namespace;
    if (!options.hasher) options.hasher = sha2.sha256;
    if (options.cidVersion === undefined) options.cidVersion = 1;
    if (options.codec === dagPb__namespace && options.hasher !== sha2.sha256) options.cidVersion = 1;
    const multihash = await options.hasher.digest(buffer);
    const cid$1 = cid.CID.create(options.cidVersion, options.codec.code, multihash);
    if (!options.onlyHash) await blockstore.put(cid$1, buffer, {
        signal: options.signal
    });
    return cid$1;
};
module.exports = persist;

},{"multiformats/cid":"fJJnW","@ipld/dag-pb":"e9gy2","multiformats/hashes/sha2":"i8JnP"}],"7ImKK":[function(require,module,exports) {
'use strict';
var errCode = require('err-code');
var ipfsUnixfs = require('ipfs-unixfs');
var persist = require('../../utils/persist.js');
var dagPb = require('@ipld/dag-pb');
var parallelBatch = require('it-parallel-batch');
var rawCodec = require('multiformats/codecs/raw');
var flat = require('./flat.js');
var balanced = require('./balanced.js');
var trickle = require('./trickle.js');
var bufferImporter = require('./buffer-importer.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n['default'] = e;
    return Object.freeze(n);
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
var dagPb__namespace = /*#__PURE__*/ _interopNamespace(dagPb);
var parallelBatch__default = /*#__PURE__*/ _interopDefaultLegacy(parallelBatch);
var rawCodec__namespace = /*#__PURE__*/ _interopNamespace(rawCodec);
const dagBuilders = {
    flat: flat,
    balanced: balanced,
    trickle: trickle
};
async function* buildFileBatch(file, blockstore, options) {
    let count = -1;
    let previous;
    let bufferImporter$1;
    if (typeof options.bufferImporter === 'function') bufferImporter$1 = options.bufferImporter;
    else bufferImporter$1 = bufferImporter;
    for await (const entry of parallelBatch__default['default'](bufferImporter$1(file, blockstore, options), options.blockWriteConcurrency)){
        count++;
        if (count === 0) {
            previous = entry;
            continue;
        } else if (count === 1 && previous) {
            yield previous;
            previous = null;
        }
        yield entry;
    }
    if (previous) {
        previous.single = true;
        yield previous;
    }
}
const reduce = (file, blockstore, options)=>{
    async function reducer(leaves) {
        if (leaves.length === 1 && leaves[0].single && options.reduceSingleLeafToSelf) {
            const leaf = leaves[0];
            if (leaf.cid.code === rawCodec__namespace.code && (file.mtime !== undefined || file.mode !== undefined)) {
                let buffer = await blockstore.get(leaf.cid);
                leaf.unixfs = new ipfsUnixfs.UnixFS({
                    type: 'file',
                    mtime: file.mtime,
                    mode: file.mode,
                    data: buffer
                });
                buffer = dagPb.encode(dagPb.prepare({
                    Data: leaf.unixfs.marshal()
                }));
                leaf.cid = await persist(buffer, blockstore, {
                    ...options,
                    codec: dagPb__namespace,
                    hasher: options.hasher,
                    cidVersion: options.cidVersion
                });
                leaf.size = buffer.length;
            }
            return {
                cid: leaf.cid,
                path: file.path,
                unixfs: leaf.unixfs,
                size: leaf.size
            };
        }
        const f = new ipfsUnixfs.UnixFS({
            type: 'file',
            mtime: file.mtime,
            mode: file.mode
        });
        const links = leaves.filter((leaf)=>{
            if (leaf.cid.code === rawCodec__namespace.code && leaf.size) return true;
            if (leaf.unixfs && !leaf.unixfs.data && leaf.unixfs.fileSize()) return true;
            return Boolean(leaf.unixfs && leaf.unixfs.data && leaf.unixfs.data.length);
        }).map((leaf)=>{
            if (leaf.cid.code === rawCodec__namespace.code) {
                f.addBlockSize(leaf.size);
                return {
                    Name: '',
                    Tsize: leaf.size,
                    Hash: leaf.cid
                };
            }
            if (!leaf.unixfs || !leaf.unixfs.data) f.addBlockSize(leaf.unixfs && leaf.unixfs.fileSize() || 0);
            else f.addBlockSize(leaf.unixfs.data.length);
            return {
                Name: '',
                Tsize: leaf.size,
                Hash: leaf.cid
            };
        });
        const node = {
            Data: f.marshal(),
            Links: links
        };
        const buffer = dagPb.encode(dagPb.prepare(node));
        const cid = await persist(buffer, blockstore, options);
        return {
            cid,
            path: file.path,
            unixfs: f,
            size: buffer.length + node.Links.reduce((acc, curr)=>acc + curr.Tsize
            , 0)
        };
    }
    return reducer;
};
function fileBuilder(file, block, options) {
    const dagBuilder = dagBuilders[options.strategy];
    if (!dagBuilder) throw errCode__default['default'](new Error(`Unknown importer build strategy name: ${options.strategy}`), 'ERR_BAD_STRATEGY');
    return dagBuilder(buildFileBatch(file, block, options), reduce(file, block, options), options);
}
module.exports = fileBuilder;

},{"err-code":"eQvyh","ipfs-unixfs":"fttXc","../../utils/persist.js":"fagNy","@ipld/dag-pb":"e9gy2","it-parallel-batch":"4B5jX","multiformats/codecs/raw":"dkcyY","./flat.js":"4DVw2","./balanced.js":"clfdw","./trickle.js":"eOFHP","./buffer-importer.js":"dqwnI"}],"4DVw2":[function(require,module,exports) {
'use strict';
var all = require('it-all');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var all__default = /*#__PURE__*/ _interopDefaultLegacy(all);
async function flat(source, reduce) {
    return reduce(await all__default['default'](source));
}
module.exports = flat;

},{"it-all":"hynpN"}],"clfdw":[function(require,module,exports) {
'use strict';
var batch = require('it-batch');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var batch__default = /*#__PURE__*/ _interopDefaultLegacy(batch);
function balanced(source, reduce, options) {
    return reduceToParents(source, reduce, options);
}
async function reduceToParents(source, reduce, options) {
    const roots = [];
    for await (const chunked of batch__default['default'](source, options.maxChildrenPerNode))roots.push(await reduce(chunked));
    if (roots.length > 1) return reduceToParents(roots, reduce, options);
    return roots[0];
}
module.exports = balanced;

},{"it-batch":"7Ok44"}],"eOFHP":[function(require,module,exports) {
'use strict';
var batch = require('it-batch');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var batch__default = /*#__PURE__*/ _interopDefaultLegacy(batch);
async function trickleStream(source, reduce, options) {
    const root = new Root(options.layerRepeat);
    let iteration = 0;
    let maxDepth = 1;
    let subTree = root;
    for await (const layer of batch__default['default'](source, options.maxChildrenPerNode)){
        if (subTree.isFull()) {
            if (subTree !== root) root.addChild(await subTree.reduce(reduce));
            if (iteration && iteration % options.layerRepeat === 0) maxDepth++;
            subTree = new SubTree(maxDepth, options.layerRepeat, iteration);
            iteration++;
        }
        subTree.append(layer);
    }
    if (subTree && subTree !== root) root.addChild(await subTree.reduce(reduce));
    return root.reduce(reduce);
}
class SubTree {
    constructor(maxDepth, layerRepeat, iteration = 0){
        this.maxDepth = maxDepth;
        this.layerRepeat = layerRepeat;
        this.currentDepth = 1;
        this.iteration = iteration;
        this.root = this.node = this.parent = {
            children: [],
            depth: this.currentDepth,
            maxDepth,
            maxChildren: (this.maxDepth - this.currentDepth) * this.layerRepeat
        };
    }
    isFull() {
        if (!this.root.data) return false;
        if (this.currentDepth < this.maxDepth && this.node.maxChildren) {
            this._addNextNodeToParent(this.node);
            return false;
        }
        const distantRelative = this._findParent(this.node, this.currentDepth);
        if (distantRelative) {
            this._addNextNodeToParent(distantRelative);
            return false;
        }
        return true;
    }
    _addNextNodeToParent(parent) {
        this.parent = parent;
        const nextNode = {
            children: [],
            depth: parent.depth + 1,
            parent,
            maxDepth: this.maxDepth,
            maxChildren: Math.floor(parent.children.length / this.layerRepeat) * this.layerRepeat
        };
        parent.children.push(nextNode);
        this.currentDepth = nextNode.depth;
        this.node = nextNode;
    }
    append(layer) {
        this.node.data = layer;
    }
    reduce(reduce) {
        return this._reduce(this.root, reduce);
    }
    async _reduce(node, reduce1) {
        let children = [];
        if (node.children.length) children = await Promise.all(node.children.filter((child)=>child.data
        ).map((child)=>this._reduce(child, reduce1)
        ));
        return reduce1((node.data || []).concat(children));
    }
    _findParent(node1, depth) {
        const parent = node1.parent;
        if (!parent || parent.depth === 0) return;
        if (parent.children.length === parent.maxChildren || !parent.maxChildren) return this._findParent(parent, depth);
        return parent;
    }
}
class Root extends SubTree {
    constructor(layerRepeat1){
        super(0, layerRepeat1);
        this.root.depth = 0;
        this.currentDepth = 1;
    }
    addChild(child) {
        this.root.children.push(child);
    }
    reduce(reduce2) {
        return reduce2((this.root.data || []).concat(this.root.children));
    }
}
module.exports = trickleStream;

},{"it-batch":"7Ok44"}],"dqwnI":[function(require,module,exports) {
'use strict';
var ipfsUnixfs = require('ipfs-unixfs');
var persist = require('../../utils/persist.js');
var dagPb = require('@ipld/dag-pb');
var rawCodec = require('multiformats/codecs/raw');
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n['default'] = e;
    return Object.freeze(n);
}
var dagPb__namespace = /*#__PURE__*/ _interopNamespace(dagPb);
var rawCodec__namespace = /*#__PURE__*/ _interopNamespace(rawCodec);
async function* bufferImporter(file, block, options) {
    for await (let buffer of file.content)yield async ()=>{
        options.progress(buffer.length, file.path);
        let unixfs;
        const opts = {
            codec: dagPb__namespace,
            cidVersion: options.cidVersion,
            hasher: options.hasher,
            onlyHash: options.onlyHash
        };
        if (options.rawLeaves) {
            opts.codec = rawCodec__namespace;
            opts.cidVersion = 1;
        } else {
            unixfs = new ipfsUnixfs.UnixFS({
                type: options.leafType,
                data: buffer,
                mtime: file.mtime,
                mode: file.mode
            });
            buffer = dagPb__namespace.encode({
                Data: unixfs.marshal(),
                Links: []
            });
        }
        return {
            cid: await persist(buffer, block, opts),
            unixfs,
            size: buffer.length
        };
    };
}
module.exports = bufferImporter;

},{"ipfs-unixfs":"fttXc","../../utils/persist.js":"fagNy","@ipld/dag-pb":"e9gy2","multiformats/codecs/raw":"dkcyY"}],"ezzWb":[function(require,module,exports) {
'use strict';
var BufferList = require('bl/BufferList.js');
var rabinWasm = require('rabin-wasm');
var errCode = require('err-code');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var BufferList__default = /*#__PURE__*/ _interopDefaultLegacy(BufferList);
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
async function* rabinChunker(source, options) {
    let min, max, avg;
    if (options.minChunkSize && options.maxChunkSize && options.avgChunkSize) {
        avg = options.avgChunkSize;
        min = options.minChunkSize;
        max = options.maxChunkSize;
    } else if (!options.avgChunkSize) throw errCode__default['default'](new Error('please specify an average chunk size'), 'ERR_INVALID_AVG_CHUNK_SIZE');
    else {
        avg = options.avgChunkSize;
        min = avg / 3;
        max = avg + avg / 2;
    }
    if (min < 16) throw errCode__default['default'](new Error('rabin min must be greater than 16'), 'ERR_INVALID_MIN_CHUNK_SIZE');
    if (max < min) max = min;
    if (avg < min) avg = min;
    const sizepow = Math.floor(Math.log2(avg));
    for await (const chunk of rabin(source, {
        min: min,
        max: max,
        bits: sizepow,
        window: options.window,
        polynomial: options.polynomial
    }))yield chunk;
}
async function* rabin(source, options) {
    const r = await rabinWasm.create(options.bits, options.min, options.max, options.window);
    const buffers = new BufferList__default['default']();
    for await (const chunk of source){
        buffers.append(chunk);
        const sizes = r.fingerprint(chunk);
        for(let i = 0; i < sizes.length; i++){
            const size = sizes[i];
            const buf = buffers.slice(0, size);
            buffers.consume(size);
            yield buf;
        }
    }
    if (buffers.length) yield buffers.slice(0);
}
module.exports = rabinChunker;

},{"bl/BufferList.js":"cK5XN","rabin-wasm":"hoBU8","err-code":"eQvyh"}],"cK5XN":[function(require,module,exports) {
'use strict';
const { Buffer  } = require('buffer');
const symbol = Symbol.for('BufferList');
function BufferList(buf) {
    if (!(this instanceof BufferList)) return new BufferList(buf);
    BufferList._init.call(this, buf);
}
BufferList._init = function _init(buf) {
    Object.defineProperty(this, symbol, {
        value: true
    });
    this._bufs = [];
    this.length = 0;
    if (buf) this.append(buf);
};
BufferList.prototype._new = function _new(buf) {
    return new BufferList(buf);
};
BufferList.prototype._offset = function _offset(offset) {
    if (offset === 0) return [
        0,
        0
    ];
    let tot = 0;
    for(let i = 0; i < this._bufs.length; i++){
        const _t = tot + this._bufs[i].length;
        if (offset < _t || i === this._bufs.length - 1) return [
            i,
            offset - tot
        ];
        tot = _t;
    }
};
BufferList.prototype._reverseOffset = function(blOffset) {
    const bufferId = blOffset[0];
    let offset = blOffset[1];
    for(let i = 0; i < bufferId; i++)offset += this._bufs[i].length;
    return offset;
};
BufferList.prototype.get = function get(index) {
    if (index > this.length || index < 0) return undefined;
    const offset = this._offset(index);
    return this._bufs[offset[0]][offset[1]];
};
BufferList.prototype.slice = function slice(start, end) {
    if (typeof start === 'number' && start < 0) start += this.length;
    if (typeof end === 'number' && end < 0) end += this.length;
    return this.copy(null, 0, start, end);
};
BufferList.prototype.copy = function copy(dst, dstStart, srcStart, srcEnd) {
    if (typeof srcStart !== 'number' || srcStart < 0) srcStart = 0;
    if (typeof srcEnd !== 'number' || srcEnd > this.length) srcEnd = this.length;
    if (srcStart >= this.length) return dst || Buffer.alloc(0);
    if (srcEnd <= 0) return dst || Buffer.alloc(0);
    const copy = !!dst;
    const off = this._offset(srcStart);
    const len = srcEnd - srcStart;
    let bytes = len;
    let bufoff = copy && dstStart || 0;
    let start = off[1];
    // copy/slice everything
    if (srcStart === 0 && srcEnd === this.length) {
        if (!copy) // slice, but full concat if multiple buffers
        return this._bufs.length === 1 ? this._bufs[0] : Buffer.concat(this._bufs, this.length);
        // copy, need to copy individual buffers
        for(let i = 0; i < this._bufs.length; i++){
            this._bufs[i].copy(dst, bufoff);
            bufoff += this._bufs[i].length;
        }
        return dst;
    }
    // easy, cheap case where it's a subset of one of the buffers
    if (bytes <= this._bufs[off[0]].length - start) return copy ? this._bufs[off[0]].copy(dst, dstStart, start, start + bytes) : this._bufs[off[0]].slice(start, start + bytes);
    if (!copy) // a slice, we need something to copy in to
    dst = Buffer.allocUnsafe(len);
    for(let i = off[0]; i < this._bufs.length; i++){
        const l = this._bufs[i].length - start;
        if (bytes > l) {
            this._bufs[i].copy(dst, bufoff, start);
            bufoff += l;
        } else {
            this._bufs[i].copy(dst, bufoff, start, start + bytes);
            bufoff += l;
            break;
        }
        bytes -= l;
        if (start) start = 0;
    }
    // safeguard so that we don't return uninitialized memory
    if (dst.length > bufoff) return dst.slice(0, bufoff);
    return dst;
};
BufferList.prototype.shallowSlice = function shallowSlice(start, end) {
    start = start || 0;
    end = typeof end !== 'number' ? this.length : end;
    if (start < 0) start += this.length;
    if (end < 0) end += this.length;
    if (start === end) return this._new();
    const startOffset = this._offset(start);
    const endOffset = this._offset(end);
    const buffers = this._bufs.slice(startOffset[0], endOffset[0] + 1);
    if (endOffset[1] === 0) buffers.pop();
    else buffers[buffers.length - 1] = buffers[buffers.length - 1].slice(0, endOffset[1]);
    if (startOffset[1] !== 0) buffers[0] = buffers[0].slice(startOffset[1]);
    return this._new(buffers);
};
BufferList.prototype.toString = function toString(encoding, start, end) {
    return this.slice(start, end).toString(encoding);
};
BufferList.prototype.consume = function consume(bytes) {
    // first, normalize the argument, in accordance with how Buffer does it
    bytes = Math.trunc(bytes);
    // do nothing if not a positive number
    if (Number.isNaN(bytes) || bytes <= 0) return this;
    while(this._bufs.length)if (bytes >= this._bufs[0].length) {
        bytes -= this._bufs[0].length;
        this.length -= this._bufs[0].length;
        this._bufs.shift();
    } else {
        this._bufs[0] = this._bufs[0].slice(bytes);
        this.length -= bytes;
        break;
    }
    return this;
};
BufferList.prototype.duplicate = function duplicate() {
    const copy = this._new();
    for(let i = 0; i < this._bufs.length; i++)copy.append(this._bufs[i]);
    return copy;
};
BufferList.prototype.append = function append(buf) {
    if (buf == null) return this;
    if (buf.buffer) // append a view of the underlying ArrayBuffer
    this._appendBuffer(Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength));
    else if (Array.isArray(buf)) for(let i = 0; i < buf.length; i++)this.append(buf[i]);
    else if (this._isBufferList(buf)) // unwrap argument into individual BufferLists
    for(let i1 = 0; i1 < buf._bufs.length; i1++)this.append(buf._bufs[i1]);
    else {
        // coerce number arguments to strings, since Buffer(number) does
        // uninitialized memory allocation
        if (typeof buf === 'number') buf = buf.toString();
        this._appendBuffer(Buffer.from(buf));
    }
    return this;
};
BufferList.prototype._appendBuffer = function appendBuffer(buf) {
    this._bufs.push(buf);
    this.length += buf.length;
};
BufferList.prototype.indexOf = function(search, offset, encoding) {
    if (encoding === undefined && typeof offset === 'string') {
        encoding = offset;
        offset = undefined;
    }
    if (typeof search === 'function' || Array.isArray(search)) throw new TypeError('The "value" argument must be one of type string, Buffer, BufferList, or Uint8Array.');
    else if (typeof search === 'number') search = Buffer.from([
        search
    ]);
    else if (typeof search === 'string') search = Buffer.from(search, encoding);
    else if (this._isBufferList(search)) search = search.slice();
    else if (Array.isArray(search.buffer)) search = Buffer.from(search.buffer, search.byteOffset, search.byteLength);
    else if (!Buffer.isBuffer(search)) search = Buffer.from(search);
    offset = Number(offset || 0);
    if (isNaN(offset)) offset = 0;
    if (offset < 0) offset = this.length + offset;
    if (offset < 0) offset = 0;
    if (search.length === 0) return offset > this.length ? this.length : offset;
    const blOffset = this._offset(offset);
    let blIndex = blOffset[0] // index of which internal buffer we're working on
    ;
    let buffOffset = blOffset[1] // offset of the internal buffer we're working on
    ;
    // scan over each buffer
    for(; blIndex < this._bufs.length; blIndex++){
        const buff = this._bufs[blIndex];
        while(buffOffset < buff.length){
            const availableWindow = buff.length - buffOffset;
            if (availableWindow >= search.length) {
                const nativeSearchResult = buff.indexOf(search, buffOffset);
                if (nativeSearchResult !== -1) return this._reverseOffset([
                    blIndex,
                    nativeSearchResult
                ]);
                buffOffset = buff.length - search.length + 1 // end of native search window
                ;
            } else {
                const revOffset = this._reverseOffset([
                    blIndex,
                    buffOffset
                ]);
                if (this._match(revOffset, search)) return revOffset;
                buffOffset++;
            }
        }
        buffOffset = 0;
    }
    return -1;
};
BufferList.prototype._match = function(offset, search) {
    if (this.length - offset < search.length) return false;
    for(let searchOffset = 0; searchOffset < search.length; searchOffset++){
        if (this.get(offset + searchOffset) !== search[searchOffset]) return false;
    }
    return true;
};
(function() {
    const methods = {
        readDoubleBE: 8,
        readDoubleLE: 8,
        readFloatBE: 4,
        readFloatLE: 4,
        readInt32BE: 4,
        readInt32LE: 4,
        readUInt32BE: 4,
        readUInt32LE: 4,
        readInt16BE: 2,
        readInt16LE: 2,
        readUInt16BE: 2,
        readUInt16LE: 2,
        readInt8: 1,
        readUInt8: 1,
        readIntBE: null,
        readIntLE: null,
        readUIntBE: null,
        readUIntLE: null
    };
    for(const m in methods)(function(m) {
        if (methods[m] === null) BufferList.prototype[m] = function(offset, byteLength) {
            return this.slice(offset, offset + byteLength)[m](0, byteLength);
        };
        else BufferList.prototype[m] = function(offset = 0) {
            return this.slice(offset, offset + methods[m])[m](0);
        };
    })(m);
})();
// Used internally by the class and also as an indicator of this object being
// a `BufferList`. It's not possible to use `instanceof BufferList` in a browser
// environment because there could be multiple different copies of the
// BufferList class and some `BufferList`s might be `BufferList`s.
BufferList.prototype._isBufferList = function _isBufferList(b) {
    return b instanceof BufferList || BufferList.isBufferList(b);
};
BufferList.isBufferList = function isBufferList(b) {
    return b != null && b[symbol];
};
module.exports = BufferList;

},{"buffer":"eKea5"}],"eKea5":[function(require,module,exports) {
/*!
 * The buffer module from node.js, for the browser.
 *
 * @author   Feross Aboukhadijeh <https://feross.org>
 * @license  MIT
 */ /* eslint-disable no-proto */ 'use strict';
var base64 = require('base64-js');
var ieee754 = require('ieee754');
var customInspectSymbol = typeof Symbol === 'function' && typeof Symbol['for'] === 'function' ? Symbol['for']('nodejs.util.inspect.custom') // eslint-disable-line dot-notation
 : null;
exports.Buffer = Buffer;
exports.SlowBuffer = SlowBuffer;
exports.INSPECT_MAX_BYTES = 50;
var K_MAX_LENGTH = 2147483647;
exports.kMaxLength = K_MAX_LENGTH;
/**
 * If `Buffer.TYPED_ARRAY_SUPPORT`:
 *   === true    Use Uint8Array implementation (fastest)
 *   === false   Print warning and recommend using `buffer` v4.x which has an Object
 *               implementation (most compatible, even IE6)
 *
 * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
 * Opera 11.6+, iOS 4.2+.
 *
 * We report that the browser does not support typed arrays if the are not subclassable
 * using __proto__. Firefox 4-29 lacks support for adding new properties to `Uint8Array`
 * (See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438). IE 10 lacks support
 * for __proto__ and has a buggy typed array implementation.
 */ Buffer.TYPED_ARRAY_SUPPORT = typedArraySupport();
if (!Buffer.TYPED_ARRAY_SUPPORT && typeof console !== 'undefined' && typeof console.error === 'function') console.error("This browser lacks typed array (Uint8Array) support which is required by `buffer` v5.x. Use `buffer` v4.x if you require old browser support.");
function typedArraySupport() {
    // Can typed array instances can be augmented?
    try {
        var arr = new Uint8Array(1);
        var proto = {
            foo: function() {
                return 42;
            }
        };
        Object.setPrototypeOf(proto, Uint8Array.prototype);
        Object.setPrototypeOf(arr, proto);
        return arr.foo() === 42;
    } catch (e) {
        return false;
    }
}
Object.defineProperty(Buffer.prototype, 'parent', {
    enumerable: true,
    get: function() {
        if (!Buffer.isBuffer(this)) return undefined;
        return this.buffer;
    }
});
Object.defineProperty(Buffer.prototype, 'offset', {
    enumerable: true,
    get: function() {
        if (!Buffer.isBuffer(this)) return undefined;
        return this.byteOffset;
    }
});
function createBuffer(length) {
    if (length > K_MAX_LENGTH) throw new RangeError('The value "' + length + '" is invalid for option "size"');
    // Return an augmented `Uint8Array` instance
    var buf = new Uint8Array(length);
    Object.setPrototypeOf(buf, Buffer.prototype);
    return buf;
}
/**
 * The Buffer constructor returns instances of `Uint8Array` that have their
 * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of
 * `Uint8Array`, so the returned instances will have all the node `Buffer` methods
 * and the `Uint8Array` methods. Square bracket notation works as expected -- it
 * returns a single octet.
 *
 * The `Uint8Array` prototype remains unmodified.
 */ function Buffer(arg, encodingOrOffset, length) {
    // Common case.
    if (typeof arg === 'number') {
        if (typeof encodingOrOffset === 'string') throw new TypeError('The "string" argument must be of type string. Received type number');
        return allocUnsafe(arg);
    }
    return from(arg, encodingOrOffset, length);
}
Buffer.poolSize = 8192 // not used by this implementation
;
function from(value, encodingOrOffset, length) {
    if (typeof value === 'string') return fromString(value, encodingOrOffset);
    if (ArrayBuffer.isView(value)) return fromArrayView(value);
    if (value == null) throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type " + typeof value);
    if (isInstance(value, ArrayBuffer) || value && isInstance(value.buffer, ArrayBuffer)) return fromArrayBuffer(value, encodingOrOffset, length);
    if (typeof SharedArrayBuffer !== 'undefined' && (isInstance(value, SharedArrayBuffer) || value && isInstance(value.buffer, SharedArrayBuffer))) return fromArrayBuffer(value, encodingOrOffset, length);
    if (typeof value === 'number') throw new TypeError('The "value" argument must not be of type number. Received type number');
    var valueOf = value.valueOf && value.valueOf();
    if (valueOf != null && valueOf !== value) return Buffer.from(valueOf, encodingOrOffset, length);
    var b = fromObject(value);
    if (b) return b;
    if (typeof Symbol !== 'undefined' && Symbol.toPrimitive != null && typeof value[Symbol.toPrimitive] === 'function') return Buffer.from(value[Symbol.toPrimitive]('string'), encodingOrOffset, length);
    throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type " + typeof value);
}
/**
 * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError
 * if value is a number.
 * Buffer.from(str[, encoding])
 * Buffer.from(array)
 * Buffer.from(buffer)
 * Buffer.from(arrayBuffer[, byteOffset[, length]])
 **/ Buffer.from = function(value, encodingOrOffset, length) {
    return from(value, encodingOrOffset, length);
};
// Note: Change prototype *after* Buffer.from is defined to workaround Chrome bug:
// https://github.com/feross/buffer/pull/148
Object.setPrototypeOf(Buffer.prototype, Uint8Array.prototype);
Object.setPrototypeOf(Buffer, Uint8Array);
function assertSize(size) {
    if (typeof size !== 'number') throw new TypeError('"size" argument must be of type number');
    else if (size < 0) throw new RangeError('The value "' + size + '" is invalid for option "size"');
}
function alloc(size, fill, encoding) {
    assertSize(size);
    if (size <= 0) return createBuffer(size);
    if (fill !== undefined) // Only pay attention to encoding if it's a string. This
    // prevents accidentally sending in a number that would
    // be interpreted as a start offset.
    return typeof encoding === 'string' ? createBuffer(size).fill(fill, encoding) : createBuffer(size).fill(fill);
    return createBuffer(size);
}
/**
 * Creates a new filled Buffer instance.
 * alloc(size[, fill[, encoding]])
 **/ Buffer.alloc = function(size, fill, encoding) {
    return alloc(size, fill, encoding);
};
function allocUnsafe(size) {
    assertSize(size);
    return createBuffer(size < 0 ? 0 : checked(size) | 0);
}
/**
 * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.
 * */ Buffer.allocUnsafe = function(size) {
    return allocUnsafe(size);
};
/**
 * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.
 */ Buffer.allocUnsafeSlow = function(size) {
    return allocUnsafe(size);
};
function fromString(string, encoding) {
    if (typeof encoding !== 'string' || encoding === '') encoding = 'utf8';
    if (!Buffer.isEncoding(encoding)) throw new TypeError('Unknown encoding: ' + encoding);
    var length = byteLength1(string, encoding) | 0;
    var buf = createBuffer(length);
    var actual = buf.write(string, encoding);
    if (actual !== length) // Writing a hex string, for example, that contains invalid characters will
    // cause everything after the first invalid character to be ignored. (e.g.
    // 'abxxcd' will be treated as 'ab')
    buf = buf.slice(0, actual);
    return buf;
}
function fromArrayLike(array) {
    var length = array.length < 0 ? 0 : checked(array.length) | 0;
    var buf = createBuffer(length);
    for(var i = 0; i < length; i += 1)buf[i] = array[i] & 255;
    return buf;
}
function fromArrayView(arrayView) {
    if (isInstance(arrayView, Uint8Array)) {
        var copy = new Uint8Array(arrayView);
        return fromArrayBuffer(copy.buffer, copy.byteOffset, copy.byteLength);
    }
    return fromArrayLike(arrayView);
}
function fromArrayBuffer(array, byteOffset, length) {
    if (byteOffset < 0 || array.byteLength < byteOffset) throw new RangeError('"offset" is outside of buffer bounds');
    if (array.byteLength < byteOffset + (length || 0)) throw new RangeError('"length" is outside of buffer bounds');
    var buf;
    if (byteOffset === undefined && length === undefined) buf = new Uint8Array(array);
    else if (length === undefined) buf = new Uint8Array(array, byteOffset);
    else buf = new Uint8Array(array, byteOffset, length);
    // Return an augmented `Uint8Array` instance
    Object.setPrototypeOf(buf, Buffer.prototype);
    return buf;
}
function fromObject(obj) {
    if (Buffer.isBuffer(obj)) {
        var len = checked(obj.length) | 0;
        var buf = createBuffer(len);
        if (buf.length === 0) return buf;
        obj.copy(buf, 0, 0, len);
        return buf;
    }
    if (obj.length !== undefined) {
        if (typeof obj.length !== 'number' || numberIsNaN(obj.length)) return createBuffer(0);
        return fromArrayLike(obj);
    }
    if (obj.type === 'Buffer' && Array.isArray(obj.data)) return fromArrayLike(obj.data);
}
function checked(length) {
    // Note: cannot use `length < K_MAX_LENGTH` here because that fails when
    // length is NaN (which is otherwise coerced to zero.)
    if (length >= K_MAX_LENGTH) throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x" + K_MAX_LENGTH.toString(16) + ' bytes');
    return length | 0;
}
function SlowBuffer(length) {
    if (+length != length) length = 0;
    return Buffer.alloc(+length);
}
Buffer.isBuffer = function isBuffer(b) {
    return b != null && b._isBuffer === true && b !== Buffer.prototype // so Buffer.isBuffer(Buffer.prototype) will be false
    ;
};
Buffer.compare = function compare(a, b) {
    if (isInstance(a, Uint8Array)) a = Buffer.from(a, a.offset, a.byteLength);
    if (isInstance(b, Uint8Array)) b = Buffer.from(b, b.offset, b.byteLength);
    if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) throw new TypeError('The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array');
    if (a === b) return 0;
    var x = a.length;
    var y = b.length;
    for(var i = 0, len = Math.min(x, y); i < len; ++i)if (a[i] !== b[i]) {
        x = a[i];
        y = b[i];
        break;
    }
    if (x < y) return -1;
    if (y < x) return 1;
    return 0;
};
Buffer.isEncoding = function isEncoding(encoding) {
    switch(String(encoding).toLowerCase()){
        case 'hex':
        case 'utf8':
        case 'utf-8':
        case 'ascii':
        case 'latin1':
        case 'binary':
        case 'base64':
        case 'ucs2':
        case 'ucs-2':
        case 'utf16le':
        case 'utf-16le':
            return true;
        default:
            return false;
    }
};
Buffer.concat = function concat(list, length) {
    if (!Array.isArray(list)) throw new TypeError('"list" argument must be an Array of Buffers');
    if (list.length === 0) return Buffer.alloc(0);
    var i;
    if (length === undefined) {
        length = 0;
        for(i = 0; i < list.length; ++i)length += list[i].length;
    }
    var buffer = Buffer.allocUnsafe(length);
    var pos = 0;
    for(i = 0; i < list.length; ++i){
        var buf = list[i];
        if (isInstance(buf, Uint8Array)) {
            if (pos + buf.length > buffer.length) Buffer.from(buf).copy(buffer, pos);
            else Uint8Array.prototype.set.call(buffer, buf, pos);
        } else if (!Buffer.isBuffer(buf)) throw new TypeError('"list" argument must be an Array of Buffers');
        else buf.copy(buffer, pos);
        pos += buf.length;
    }
    return buffer;
};
function byteLength1(string, encoding) {
    if (Buffer.isBuffer(string)) return string.length;
    if (ArrayBuffer.isView(string) || isInstance(string, ArrayBuffer)) return string.byteLength;
    if (typeof string !== 'string') throw new TypeError("The \"string\" argument must be one of type string, Buffer, or ArrayBuffer. Received type " + typeof string);
    var len = string.length;
    var mustMatch = arguments.length > 2 && arguments[2] === true;
    if (!mustMatch && len === 0) return 0;
    // Use a for loop to avoid recursion
    var loweredCase = false;
    for(;;)switch(encoding){
        case 'ascii':
        case 'latin1':
        case 'binary':
            return len;
        case 'utf8':
        case 'utf-8':
            return utf8ToBytes(string).length;
        case 'ucs2':
        case 'ucs-2':
        case 'utf16le':
        case 'utf-16le':
            return len * 2;
        case 'hex':
            return len >>> 1;
        case 'base64':
            return base64ToBytes(string).length;
        default:
            if (loweredCase) return mustMatch ? -1 : utf8ToBytes(string).length // assume utf8
            ;
            encoding = ('' + encoding).toLowerCase();
            loweredCase = true;
    }
}
Buffer.byteLength = byteLength1;
function slowToString(encoding, start, end) {
    var loweredCase = false;
    // No need to verify that "this.length <= MAX_UINT32" since it's a read-only
    // property of a typed array.
    // This behaves neither like String nor Uint8Array in that we set start/end
    // to their upper/lower bounds if the value passed is out of range.
    // undefined is handled specially as per ECMA-262 6th Edition,
    // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.
    if (start === undefined || start < 0) start = 0;
    // Return early if start > this.length. Done here to prevent potential uint32
    // coercion fail below.
    if (start > this.length) return '';
    if (end === undefined || end > this.length) end = this.length;
    if (end <= 0) return '';
    // Force coercion to uint32. This will also coerce falsey/NaN values to 0.
    end >>>= 0;
    start >>>= 0;
    if (end <= start) return '';
    if (!encoding) encoding = 'utf8';
    while(true)switch(encoding){
        case 'hex':
            return hexSlice(this, start, end);
        case 'utf8':
        case 'utf-8':
            return utf8Slice(this, start, end);
        case 'ascii':
            return asciiSlice(this, start, end);
        case 'latin1':
        case 'binary':
            return latin1Slice(this, start, end);
        case 'base64':
            return base64Slice(this, start, end);
        case 'ucs2':
        case 'ucs-2':
        case 'utf16le':
        case 'utf-16le':
            return utf16leSlice(this, start, end);
        default:
            if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding);
            encoding = (encoding + '').toLowerCase();
            loweredCase = true;
    }
}
// This property is used by `Buffer.isBuffer` (and the `is-buffer` npm package)
// to detect a Buffer instance. It's not possible to use `instanceof Buffer`
// reliably in a browserify context because there could be multiple different
// copies of the 'buffer' package in use. This method works even for Buffer
// instances that were created from another copy of the `buffer` package.
// See: https://github.com/feross/buffer/issues/154
Buffer.prototype._isBuffer = true;
function swap(b, n, m) {
    var i = b[n];
    b[n] = b[m];
    b[m] = i;
}
Buffer.prototype.swap16 = function swap16() {
    var len = this.length;
    if (len % 2 !== 0) throw new RangeError('Buffer size must be a multiple of 16-bits');
    for(var i = 0; i < len; i += 2)swap(this, i, i + 1);
    return this;
};
Buffer.prototype.swap32 = function swap32() {
    var len = this.length;
    if (len % 4 !== 0) throw new RangeError('Buffer size must be a multiple of 32-bits');
    for(var i = 0; i < len; i += 4){
        swap(this, i, i + 3);
        swap(this, i + 1, i + 2);
    }
    return this;
};
Buffer.prototype.swap64 = function swap64() {
    var len = this.length;
    if (len % 8 !== 0) throw new RangeError('Buffer size must be a multiple of 64-bits');
    for(var i = 0; i < len; i += 8){
        swap(this, i, i + 7);
        swap(this, i + 1, i + 6);
        swap(this, i + 2, i + 5);
        swap(this, i + 3, i + 4);
    }
    return this;
};
Buffer.prototype.toString = function toString() {
    var length = this.length;
    if (length === 0) return '';
    if (arguments.length === 0) return utf8Slice(this, 0, length);
    return slowToString.apply(this, arguments);
};
Buffer.prototype.toLocaleString = Buffer.prototype.toString;
Buffer.prototype.equals = function equals(b) {
    if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer');
    if (this === b) return true;
    return Buffer.compare(this, b) === 0;
};
Buffer.prototype.inspect = function inspect() {
    var str = '';
    var max = exports.INSPECT_MAX_BYTES;
    str = this.toString('hex', 0, max).replace(/(.{2})/g, '$1 ').trim();
    if (this.length > max) str += ' ... ';
    return '<Buffer ' + str + '>';
};
if (customInspectSymbol) Buffer.prototype[customInspectSymbol] = Buffer.prototype.inspect;
Buffer.prototype.compare = function compare(target, start, end, thisStart, thisEnd) {
    if (isInstance(target, Uint8Array)) target = Buffer.from(target, target.offset, target.byteLength);
    if (!Buffer.isBuffer(target)) throw new TypeError("The \"target\" argument must be one of type Buffer or Uint8Array. Received type " + typeof target);
    if (start === undefined) start = 0;
    if (end === undefined) end = target ? target.length : 0;
    if (thisStart === undefined) thisStart = 0;
    if (thisEnd === undefined) thisEnd = this.length;
    if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) throw new RangeError('out of range index');
    if (thisStart >= thisEnd && start >= end) return 0;
    if (thisStart >= thisEnd) return -1;
    if (start >= end) return 1;
    start >>>= 0;
    end >>>= 0;
    thisStart >>>= 0;
    thisEnd >>>= 0;
    if (this === target) return 0;
    var x = thisEnd - thisStart;
    var y = end - start;
    var len = Math.min(x, y);
    var thisCopy = this.slice(thisStart, thisEnd);
    var targetCopy = target.slice(start, end);
    for(var i = 0; i < len; ++i)if (thisCopy[i] !== targetCopy[i]) {
        x = thisCopy[i];
        y = targetCopy[i];
        break;
    }
    if (x < y) return -1;
    if (y < x) return 1;
    return 0;
};
// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,
// OR the last index of `val` in `buffer` at offset <= `byteOffset`.
//
// Arguments:
// - buffer - a Buffer to search
// - val - a string, Buffer, or number
// - byteOffset - an index into `buffer`; will be clamped to an int32
// - encoding - an optional encoding, relevant is val is a string
// - dir - true for indexOf, false for lastIndexOf
function bidirectionalIndexOf(buffer, val, byteOffset, encoding, dir) {
    // Empty buffer means no match
    if (buffer.length === 0) return -1;
    // Normalize byteOffset
    if (typeof byteOffset === 'string') {
        encoding = byteOffset;
        byteOffset = 0;
    } else if (byteOffset > 2147483647) byteOffset = 2147483647;
    else if (byteOffset < -2147483648) byteOffset = -2147483648;
    byteOffset = +byteOffset // Coerce to Number.
    ;
    if (numberIsNaN(byteOffset)) // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer
    byteOffset = dir ? 0 : buffer.length - 1;
    // Normalize byteOffset: negative offsets start from the end of the buffer
    if (byteOffset < 0) byteOffset = buffer.length + byteOffset;
    if (byteOffset >= buffer.length) {
        if (dir) return -1;
        else byteOffset = buffer.length - 1;
    } else if (byteOffset < 0) {
        if (dir) byteOffset = 0;
        else return -1;
    }
    // Normalize val
    if (typeof val === 'string') val = Buffer.from(val, encoding);
    // Finally, search either indexOf (if dir is true) or lastIndexOf
    if (Buffer.isBuffer(val)) {
        // Special case: looking for empty string/buffer always fails
        if (val.length === 0) return -1;
        return arrayIndexOf(buffer, val, byteOffset, encoding, dir);
    } else if (typeof val === 'number') {
        val = val & 255 // Search for a byte value [0-255]
        ;
        if (typeof Uint8Array.prototype.indexOf === 'function') {
            if (dir) return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset);
            else return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset);
        }
        return arrayIndexOf(buffer, [
            val
        ], byteOffset, encoding, dir);
    }
    throw new TypeError('val must be string, number or Buffer');
}
function arrayIndexOf(arr, val, byteOffset, encoding, dir) {
    var indexSize = 1;
    var arrLength = arr.length;
    var valLength = val.length;
    if (encoding !== undefined) {
        encoding = String(encoding).toLowerCase();
        if (encoding === 'ucs2' || encoding === 'ucs-2' || encoding === 'utf16le' || encoding === 'utf-16le') {
            if (arr.length < 2 || val.length < 2) return -1;
            indexSize = 2;
            arrLength /= 2;
            valLength /= 2;
            byteOffset /= 2;
        }
    }
    function read(buf, i) {
        if (indexSize === 1) return buf[i];
        else return buf.readUInt16BE(i * indexSize);
    }
    var i1;
    if (dir) {
        var foundIndex = -1;
        for(i1 = byteOffset; i1 < arrLength; i1++)if (read(arr, i1) === read(val, foundIndex === -1 ? 0 : i1 - foundIndex)) {
            if (foundIndex === -1) foundIndex = i1;
            if (i1 - foundIndex + 1 === valLength) return foundIndex * indexSize;
        } else {
            if (foundIndex !== -1) i1 -= i1 - foundIndex;
            foundIndex = -1;
        }
    } else {
        if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength;
        for(i1 = byteOffset; i1 >= 0; i1--){
            var found = true;
            for(var j = 0; j < valLength; j++)if (read(arr, i1 + j) !== read(val, j)) {
                found = false;
                break;
            }
            if (found) return i1;
        }
    }
    return -1;
}
Buffer.prototype.includes = function includes(val, byteOffset, encoding) {
    return this.indexOf(val, byteOffset, encoding) !== -1;
};
Buffer.prototype.indexOf = function indexOf(val, byteOffset, encoding) {
    return bidirectionalIndexOf(this, val, byteOffset, encoding, true);
};
Buffer.prototype.lastIndexOf = function lastIndexOf(val, byteOffset, encoding) {
    return bidirectionalIndexOf(this, val, byteOffset, encoding, false);
};
function hexWrite(buf, string, offset, length) {
    offset = Number(offset) || 0;
    var remaining = buf.length - offset;
    if (!length) length = remaining;
    else {
        length = Number(length);
        if (length > remaining) length = remaining;
    }
    var strLen = string.length;
    if (length > strLen / 2) length = strLen / 2;
    for(var i = 0; i < length; ++i){
        var parsed = parseInt(string.substr(i * 2, 2), 16);
        if (numberIsNaN(parsed)) return i;
        buf[offset + i] = parsed;
    }
    return i;
}
function utf8Write(buf, string, offset, length) {
    return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length);
}
function asciiWrite(buf, string, offset, length) {
    return blitBuffer(asciiToBytes(string), buf, offset, length);
}
function base64Write(buf, string, offset, length) {
    return blitBuffer(base64ToBytes(string), buf, offset, length);
}
function ucs2Write(buf, string, offset, length) {
    return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length);
}
Buffer.prototype.write = function write(string, offset, length, encoding) {
    // Buffer#write(string)
    if (offset === undefined) {
        encoding = 'utf8';
        length = this.length;
        offset = 0;
    // Buffer#write(string, encoding)
    } else if (length === undefined && typeof offset === 'string') {
        encoding = offset;
        length = this.length;
        offset = 0;
    // Buffer#write(string, offset[, length][, encoding])
    } else if (isFinite(offset)) {
        offset = offset >>> 0;
        if (isFinite(length)) {
            length = length >>> 0;
            if (encoding === undefined) encoding = 'utf8';
        } else {
            encoding = length;
            length = undefined;
        }
    } else throw new Error('Buffer.write(string, encoding, offset[, length]) is no longer supported');
    var remaining = this.length - offset;
    if (length === undefined || length > remaining) length = remaining;
    if (string.length > 0 && (length < 0 || offset < 0) || offset > this.length) throw new RangeError('Attempt to write outside buffer bounds');
    if (!encoding) encoding = 'utf8';
    var loweredCase = false;
    for(;;)switch(encoding){
        case 'hex':
            return hexWrite(this, string, offset, length);
        case 'utf8':
        case 'utf-8':
            return utf8Write(this, string, offset, length);
        case 'ascii':
        case 'latin1':
        case 'binary':
            return asciiWrite(this, string, offset, length);
        case 'base64':
            // Warning: maxLength not taken into account in base64Write
            return base64Write(this, string, offset, length);
        case 'ucs2':
        case 'ucs-2':
        case 'utf16le':
        case 'utf-16le':
            return ucs2Write(this, string, offset, length);
        default:
            if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding);
            encoding = ('' + encoding).toLowerCase();
            loweredCase = true;
    }
};
Buffer.prototype.toJSON = function toJSON() {
    return {
        type: 'Buffer',
        data: Array.prototype.slice.call(this._arr || this, 0)
    };
};
function base64Slice(buf, start, end) {
    if (start === 0 && end === buf.length) return base64.fromByteArray(buf);
    else return base64.fromByteArray(buf.slice(start, end));
}
function utf8Slice(buf, start, end) {
    end = Math.min(buf.length, end);
    var res = [];
    var i = start;
    while(i < end){
        var firstByte = buf[i];
        var codePoint = null;
        var bytesPerSequence = firstByte > 239 ? 4 : firstByte > 223 ? 3 : firstByte > 191 ? 2 : 1;
        if (i + bytesPerSequence <= end) {
            var secondByte, thirdByte, fourthByte, tempCodePoint;
            switch(bytesPerSequence){
                case 1:
                    if (firstByte < 128) codePoint = firstByte;
                    break;
                case 2:
                    secondByte = buf[i + 1];
                    if ((secondByte & 192) === 128) {
                        tempCodePoint = (firstByte & 31) << 6 | secondByte & 63;
                        if (tempCodePoint > 127) codePoint = tempCodePoint;
                    }
                    break;
                case 3:
                    secondByte = buf[i + 1];
                    thirdByte = buf[i + 2];
                    if ((secondByte & 192) === 128 && (thirdByte & 192) === 128) {
                        tempCodePoint = (firstByte & 15) << 12 | (secondByte & 63) << 6 | thirdByte & 63;
                        if (tempCodePoint > 2047 && (tempCodePoint < 55296 || tempCodePoint > 57343)) codePoint = tempCodePoint;
                    }
                    break;
                case 4:
                    secondByte = buf[i + 1];
                    thirdByte = buf[i + 2];
                    fourthByte = buf[i + 3];
                    if ((secondByte & 192) === 128 && (thirdByte & 192) === 128 && (fourthByte & 192) === 128) {
                        tempCodePoint = (firstByte & 15) << 18 | (secondByte & 63) << 12 | (thirdByte & 63) << 6 | fourthByte & 63;
                        if (tempCodePoint > 65535 && tempCodePoint < 1114112) codePoint = tempCodePoint;
                    }
            }
        }
        if (codePoint === null) {
            // we did not generate a valid codePoint so insert a
            // replacement char (U+FFFD) and advance only 1 byte
            codePoint = 65533;
            bytesPerSequence = 1;
        } else if (codePoint > 65535) {
            // encode to utf16 (surrogate pair dance)
            codePoint -= 65536;
            res.push(codePoint >>> 10 & 1023 | 55296);
            codePoint = 56320 | codePoint & 1023;
        }
        res.push(codePoint);
        i += bytesPerSequence;
    }
    return decodeCodePointsArray(res);
}
// Based on http://stackoverflow.com/a/22747272/680742, the browser with
// the lowest limit is Chrome, with 0x10000 args.
// We go 1 magnitude less, for safety
var MAX_ARGUMENTS_LENGTH = 4096;
function decodeCodePointsArray(codePoints) {
    var len = codePoints.length;
    if (len <= MAX_ARGUMENTS_LENGTH) return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
    ;
    // Decode in chunks to avoid "call stack size exceeded".
    var res = '';
    var i = 0;
    while(i < len)res += String.fromCharCode.apply(String, codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH));
    return res;
}
function asciiSlice(buf, start, end) {
    var ret = '';
    end = Math.min(buf.length, end);
    for(var i = start; i < end; ++i)ret += String.fromCharCode(buf[i] & 127);
    return ret;
}
function latin1Slice(buf, start, end) {
    var ret = '';
    end = Math.min(buf.length, end);
    for(var i = start; i < end; ++i)ret += String.fromCharCode(buf[i]);
    return ret;
}
function hexSlice(buf, start, end) {
    var len = buf.length;
    if (!start || start < 0) start = 0;
    if (!end || end < 0 || end > len) end = len;
    var out = '';
    for(var i = start; i < end; ++i)out += hexSliceLookupTable[buf[i]];
    return out;
}
function utf16leSlice(buf, start, end) {
    var bytes = buf.slice(start, end);
    var res = '';
    // If bytes.length is odd, the last 8 bits must be ignored (same as node.js)
    for(var i = 0; i < bytes.length - 1; i += 2)res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256);
    return res;
}
Buffer.prototype.slice = function slice(start, end) {
    var len = this.length;
    start = ~~start;
    end = end === undefined ? len : ~~end;
    if (start < 0) {
        start += len;
        if (start < 0) start = 0;
    } else if (start > len) start = len;
    if (end < 0) {
        end += len;
        if (end < 0) end = 0;
    } else if (end > len) end = len;
    if (end < start) end = start;
    var newBuf = this.subarray(start, end);
    // Return an augmented `Uint8Array` instance
    Object.setPrototypeOf(newBuf, Buffer.prototype);
    return newBuf;
};
/*
 * Need to make sure that buffer isn't trying to write out of bounds.
 */ function checkOffset(offset, ext, length) {
    if (offset % 1 !== 0 || offset < 0) throw new RangeError('offset is not uint');
    if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length');
}
Buffer.prototype.readUintLE = Buffer.prototype.readUIntLE = function readUIntLE(offset, byteLength, noAssert) {
    offset = offset >>> 0;
    byteLength = byteLength >>> 0;
    if (!noAssert) checkOffset(offset, byteLength, this.length);
    var val = this[offset];
    var mul = 1;
    var i = 0;
    while(++i < byteLength && (mul *= 256))val += this[offset + i] * mul;
    return val;
};
Buffer.prototype.readUintBE = Buffer.prototype.readUIntBE = function readUIntBE(offset, byteLength, noAssert) {
    offset = offset >>> 0;
    byteLength = byteLength >>> 0;
    if (!noAssert) checkOffset(offset, byteLength, this.length);
    var val = this[offset + --byteLength];
    var mul = 1;
    while(byteLength > 0 && (mul *= 256))val += this[offset + --byteLength] * mul;
    return val;
};
Buffer.prototype.readUint8 = Buffer.prototype.readUInt8 = function readUInt8(offset, noAssert) {
    offset = offset >>> 0;
    if (!noAssert) checkOffset(offset, 1, this.length);
    return this[offset];
};
Buffer.prototype.readUint16LE = Buffer.prototype.readUInt16LE = function readUInt16LE(offset, noAssert) {
    offset = offset >>> 0;
    if (!noAssert) checkOffset(offset, 2, this.length);
    return this[offset] | this[offset + 1] << 8;
};
Buffer.prototype.readUint16BE = Buffer.prototype.readUInt16BE = function readUInt16BE(offset, noAssert) {
    offset = offset >>> 0;
    if (!noAssert) checkOffset(offset, 2, this.length);
    return this[offset] << 8 | this[offset + 1];
};
Buffer.prototype.readUint32LE = Buffer.prototype.readUInt32LE = function readUInt32LE(offset, noAssert) {
    offset = offset >>> 0;
    if (!noAssert) checkOffset(offset, 4, this.length);
    return (this[offset] | this[offset + 1] << 8 | this[offset + 2] << 16) + this[offset + 3] * 16777216;
};
Buffer.prototype.readUint32BE = Buffer.prototype.readUInt32BE = function readUInt32BE(offset, noAssert) {
    offset = offset >>> 0;
    if (!noAssert) checkOffset(offset, 4, this.length);
    return this[offset] * 16777216 + (this[offset + 1] << 16 | this[offset + 2] << 8 | this[offset + 3]);
};
Buffer.prototype.readIntLE = function readIntLE(offset, byteLength, noAssert) {
    offset = offset >>> 0;
    byteLength = byteLength >>> 0;
    if (!noAssert) checkOffset(offset, byteLength, this.length);
    var val = this[offset];
    var mul = 1;
    var i = 0;
    while(++i < byteLength && (mul *= 256))val += this[offset + i] * mul;
    mul *= 128;
    if (val >= mul) val -= Math.pow(2, 8 * byteLength);
    return val;
};
Buffer.prototype.readIntBE = function readIntBE(offset, byteLength, noAssert) {
    offset = offset >>> 0;
    byteLength = byteLength >>> 0;
    if (!noAssert) checkOffset(offset, byteLength, this.length);
    var i = byteLength;
    var mul = 1;
    var val = this[offset + --i];
    while(i > 0 && (mul *= 256))val += this[offset + --i] * mul;
    mul *= 128;
    if (val >= mul) val -= Math.pow(2, 8 * byteLength);
    return val;
};
Buffer.prototype.readInt8 = function readInt8(offset, noAssert) {
    offset = offset >>> 0;
    if (!noAssert) checkOffset(offset, 1, this.length);
    if (!(this[offset] & 128)) return this[offset];
    return (255 - this[offset] + 1) * -1;
};
Buffer.prototype.readInt16LE = function readInt16LE(offset, noAssert) {
    offset = offset >>> 0;
    if (!noAssert) checkOffset(offset, 2, this.length);
    var val = this[offset] | this[offset + 1] << 8;
    return val & 32768 ? val | 4294901760 : val;
};
Buffer.prototype.readInt16BE = function readInt16BE(offset, noAssert) {
    offset = offset >>> 0;
    if (!noAssert) checkOffset(offset, 2, this.length);
    var val = this[offset + 1] | this[offset] << 8;
    return val & 32768 ? val | 4294901760 : val;
};
Buffer.prototype.readInt32LE = function readInt32LE(offset, noAssert) {
    offset = offset >>> 0;
    if (!noAssert) checkOffset(offset, 4, this.length);
    return this[offset] | this[offset + 1] << 8 | this[offset + 2] << 16 | this[offset + 3] << 24;
};
Buffer.prototype.readInt32BE = function readInt32BE(offset, noAssert) {
    offset = offset >>> 0;
    if (!noAssert) checkOffset(offset, 4, this.length);
    return this[offset] << 24 | this[offset + 1] << 16 | this[offset + 2] << 8 | this[offset + 3];
};
Buffer.prototype.readFloatLE = function readFloatLE(offset, noAssert) {
    offset = offset >>> 0;
    if (!noAssert) checkOffset(offset, 4, this.length);
    return ieee754.read(this, offset, true, 23, 4);
};
Buffer.prototype.readFloatBE = function readFloatBE(offset, noAssert) {
    offset = offset >>> 0;
    if (!noAssert) checkOffset(offset, 4, this.length);
    return ieee754.read(this, offset, false, 23, 4);
};
Buffer.prototype.readDoubleLE = function readDoubleLE(offset, noAssert) {
    offset = offset >>> 0;
    if (!noAssert) checkOffset(offset, 8, this.length);
    return ieee754.read(this, offset, true, 52, 8);
};
Buffer.prototype.readDoubleBE = function readDoubleBE(offset, noAssert) {
    offset = offset >>> 0;
    if (!noAssert) checkOffset(offset, 8, this.length);
    return ieee754.read(this, offset, false, 52, 8);
};
function checkInt(buf, value, offset, ext, max, min) {
    if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance');
    if (value > max || value < min) throw new RangeError('"value" argument is out of bounds');
    if (offset + ext > buf.length) throw new RangeError('Index out of range');
}
Buffer.prototype.writeUintLE = Buffer.prototype.writeUIntLE = function writeUIntLE(value, offset, byteLength, noAssert) {
    value = +value;
    offset = offset >>> 0;
    byteLength = byteLength >>> 0;
    if (!noAssert) {
        var maxBytes = Math.pow(2, 8 * byteLength) - 1;
        checkInt(this, value, offset, byteLength, maxBytes, 0);
    }
    var mul = 1;
    var i = 0;
    this[offset] = value & 255;
    while(++i < byteLength && (mul *= 256))this[offset + i] = value / mul & 255;
    return offset + byteLength;
};
Buffer.prototype.writeUintBE = Buffer.prototype.writeUIntBE = function writeUIntBE(value, offset, byteLength, noAssert) {
    value = +value;
    offset = offset >>> 0;
    byteLength = byteLength >>> 0;
    if (!noAssert) {
        var maxBytes = Math.pow(2, 8 * byteLength) - 1;
        checkInt(this, value, offset, byteLength, maxBytes, 0);
    }
    var i = byteLength - 1;
    var mul = 1;
    this[offset + i] = value & 255;
    while(--i >= 0 && (mul *= 256))this[offset + i] = value / mul & 255;
    return offset + byteLength;
};
Buffer.prototype.writeUint8 = Buffer.prototype.writeUInt8 = function writeUInt8(value, offset, noAssert) {
    value = +value;
    offset = offset >>> 0;
    if (!noAssert) checkInt(this, value, offset, 1, 255, 0);
    this[offset] = value & 255;
    return offset + 1;
};
Buffer.prototype.writeUint16LE = Buffer.prototype.writeUInt16LE = function writeUInt16LE(value, offset, noAssert) {
    value = +value;
    offset = offset >>> 0;
    if (!noAssert) checkInt(this, value, offset, 2, 65535, 0);
    this[offset] = value & 255;
    this[offset + 1] = value >>> 8;
    return offset + 2;
};
Buffer.prototype.writeUint16BE = Buffer.prototype.writeUInt16BE = function writeUInt16BE(value, offset, noAssert) {
    value = +value;
    offset = offset >>> 0;
    if (!noAssert) checkInt(this, value, offset, 2, 65535, 0);
    this[offset] = value >>> 8;
    this[offset + 1] = value & 255;
    return offset + 2;
};
Buffer.prototype.writeUint32LE = Buffer.prototype.writeUInt32LE = function writeUInt32LE(value, offset, noAssert) {
    value = +value;
    offset = offset >>> 0;
    if (!noAssert) checkInt(this, value, offset, 4, 4294967295, 0);
    this[offset + 3] = value >>> 24;
    this[offset + 2] = value >>> 16;
    this[offset + 1] = value >>> 8;
    this[offset] = value & 255;
    return offset + 4;
};
Buffer.prototype.writeUint32BE = Buffer.prototype.writeUInt32BE = function writeUInt32BE(value, offset, noAssert) {
    value = +value;
    offset = offset >>> 0;
    if (!noAssert) checkInt(this, value, offset, 4, 4294967295, 0);
    this[offset] = value >>> 24;
    this[offset + 1] = value >>> 16;
    this[offset + 2] = value >>> 8;
    this[offset + 3] = value & 255;
    return offset + 4;
};
Buffer.prototype.writeIntLE = function writeIntLE(value, offset, byteLength, noAssert) {
    value = +value;
    offset = offset >>> 0;
    if (!noAssert) {
        var limit = Math.pow(2, 8 * byteLength - 1);
        checkInt(this, value, offset, byteLength, limit - 1, -limit);
    }
    var i = 0;
    var mul = 1;
    var sub = 0;
    this[offset] = value & 255;
    while(++i < byteLength && (mul *= 256)){
        if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) sub = 1;
        this[offset + i] = (value / mul >> 0) - sub & 255;
    }
    return offset + byteLength;
};
Buffer.prototype.writeIntBE = function writeIntBE(value, offset, byteLength, noAssert) {
    value = +value;
    offset = offset >>> 0;
    if (!noAssert) {
        var limit = Math.pow(2, 8 * byteLength - 1);
        checkInt(this, value, offset, byteLength, limit - 1, -limit);
    }
    var i = byteLength - 1;
    var mul = 1;
    var sub = 0;
    this[offset + i] = value & 255;
    while(--i >= 0 && (mul *= 256)){
        if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) sub = 1;
        this[offset + i] = (value / mul >> 0) - sub & 255;
    }
    return offset + byteLength;
};
Buffer.prototype.writeInt8 = function writeInt8(value, offset, noAssert) {
    value = +value;
    offset = offset >>> 0;
    if (!noAssert) checkInt(this, value, offset, 1, 127, -128);
    if (value < 0) value = 255 + value + 1;
    this[offset] = value & 255;
    return offset + 1;
};
Buffer.prototype.writeInt16LE = function writeInt16LE(value, offset, noAssert) {
    value = +value;
    offset = offset >>> 0;
    if (!noAssert) checkInt(this, value, offset, 2, 32767, -32768);
    this[offset] = value & 255;
    this[offset + 1] = value >>> 8;
    return offset + 2;
};
Buffer.prototype.writeInt16BE = function writeInt16BE(value, offset, noAssert) {
    value = +value;
    offset = offset >>> 0;
    if (!noAssert) checkInt(this, value, offset, 2, 32767, -32768);
    this[offset] = value >>> 8;
    this[offset + 1] = value & 255;
    return offset + 2;
};
Buffer.prototype.writeInt32LE = function writeInt32LE(value, offset, noAssert) {
    value = +value;
    offset = offset >>> 0;
    if (!noAssert) checkInt(this, value, offset, 4, 2147483647, -2147483648);
    this[offset] = value & 255;
    this[offset + 1] = value >>> 8;
    this[offset + 2] = value >>> 16;
    this[offset + 3] = value >>> 24;
    return offset + 4;
};
Buffer.prototype.writeInt32BE = function writeInt32BE(value, offset, noAssert) {
    value = +value;
    offset = offset >>> 0;
    if (!noAssert) checkInt(this, value, offset, 4, 2147483647, -2147483648);
    if (value < 0) value = 4294967295 + value + 1;
    this[offset] = value >>> 24;
    this[offset + 1] = value >>> 16;
    this[offset + 2] = value >>> 8;
    this[offset + 3] = value & 255;
    return offset + 4;
};
function checkIEEE754(buf, value, offset, ext, max, min) {
    if (offset + ext > buf.length) throw new RangeError('Index out of range');
    if (offset < 0) throw new RangeError('Index out of range');
}
function writeFloat(buf, value, offset, littleEndian, noAssert) {
    value = +value;
    offset = offset >>> 0;
    if (!noAssert) checkIEEE754(buf, value, offset, 4, 340282346638528860000000000000000000000, -340282346638528860000000000000000000000);
    ieee754.write(buf, value, offset, littleEndian, 23, 4);
    return offset + 4;
}
Buffer.prototype.writeFloatLE = function writeFloatLE(value, offset, noAssert) {
    return writeFloat(this, value, offset, true, noAssert);
};
Buffer.prototype.writeFloatBE = function writeFloatBE(value, offset, noAssert) {
    return writeFloat(this, value, offset, false, noAssert);
};
function writeDouble(buf, value, offset, littleEndian, noAssert) {
    value = +value;
    offset = offset >>> 0;
    if (!noAssert) checkIEEE754(buf, value, offset, 8, 179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, -179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000);
    ieee754.write(buf, value, offset, littleEndian, 52, 8);
    return offset + 8;
}
Buffer.prototype.writeDoubleLE = function writeDoubleLE(value, offset, noAssert) {
    return writeDouble(this, value, offset, true, noAssert);
};
Buffer.prototype.writeDoubleBE = function writeDoubleBE(value, offset, noAssert) {
    return writeDouble(this, value, offset, false, noAssert);
};
// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
Buffer.prototype.copy = function copy(target, targetStart, start, end) {
    if (!Buffer.isBuffer(target)) throw new TypeError('argument should be a Buffer');
    if (!start) start = 0;
    if (!end && end !== 0) end = this.length;
    if (targetStart >= target.length) targetStart = target.length;
    if (!targetStart) targetStart = 0;
    if (end > 0 && end < start) end = start;
    // Copy 0 bytes; we're done
    if (end === start) return 0;
    if (target.length === 0 || this.length === 0) return 0;
    // Fatal error conditions
    if (targetStart < 0) throw new RangeError('targetStart out of bounds');
    if (start < 0 || start >= this.length) throw new RangeError('Index out of range');
    if (end < 0) throw new RangeError('sourceEnd out of bounds');
    // Are we oob?
    if (end > this.length) end = this.length;
    if (target.length - targetStart < end - start) end = target.length - targetStart + start;
    var len = end - start;
    if (this === target && typeof Uint8Array.prototype.copyWithin === 'function') // Use built-in when available, missing from IE11
    this.copyWithin(targetStart, start, end);
    else Uint8Array.prototype.set.call(target, this.subarray(start, end), targetStart);
    return len;
};
// Usage:
//    buffer.fill(number[, offset[, end]])
//    buffer.fill(buffer[, offset[, end]])
//    buffer.fill(string[, offset[, end]][, encoding])
Buffer.prototype.fill = function fill(val, start, end, encoding) {
    // Handle string cases:
    if (typeof val === 'string') {
        if (typeof start === 'string') {
            encoding = start;
            start = 0;
            end = this.length;
        } else if (typeof end === 'string') {
            encoding = end;
            end = this.length;
        }
        if (encoding !== undefined && typeof encoding !== 'string') throw new TypeError('encoding must be a string');
        if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) throw new TypeError('Unknown encoding: ' + encoding);
        if (val.length === 1) {
            var code = val.charCodeAt(0);
            if (encoding === 'utf8' && code < 128 || encoding === 'latin1') // Fast path: If `val` fits into a single byte, use that numeric value.
            val = code;
        }
    } else if (typeof val === 'number') val = val & 255;
    else if (typeof val === 'boolean') val = Number(val);
    // Invalid ranges are not set to a default, so can range check early.
    if (start < 0 || this.length < start || this.length < end) throw new RangeError('Out of range index');
    if (end <= start) return this;
    start = start >>> 0;
    end = end === undefined ? this.length : end >>> 0;
    if (!val) val = 0;
    var i;
    if (typeof val === 'number') for(i = start; i < end; ++i)this[i] = val;
    else {
        var bytes = Buffer.isBuffer(val) ? val : Buffer.from(val, encoding);
        var len = bytes.length;
        if (len === 0) throw new TypeError('The value "' + val + '" is invalid for argument "value"');
        for(i = 0; i < end - start; ++i)this[i + start] = bytes[i % len];
    }
    return this;
};
// HELPER FUNCTIONS
// ================
var INVALID_BASE64_RE = /[^+/0-9A-Za-z-_]/g;
function base64clean(str) {
    // Node takes equal signs as end of the Base64 encoding
    str = str.split('=')[0];
    // Node strips out invalid characters like \n and \t from the string, base64-js does not
    str = str.trim().replace(INVALID_BASE64_RE, '');
    // Node converts strings with length < 2 to ''
    if (str.length < 2) return '';
    // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
    while(str.length % 4 !== 0)str = str + '=';
    return str;
}
function utf8ToBytes(string, units) {
    units = units || Infinity;
    var codePoint;
    var length = string.length;
    var leadSurrogate = null;
    var bytes = [];
    for(var i = 0; i < length; ++i){
        codePoint = string.charCodeAt(i);
        // is surrogate component
        if (codePoint > 55295 && codePoint < 57344) {
            // last char was a lead
            if (!leadSurrogate) {
                // no lead yet
                if (codePoint > 56319) {
                    // unexpected trail
                    if ((units -= 3) > -1) bytes.push(239, 191, 189);
                    continue;
                } else if (i + 1 === length) {
                    // unpaired lead
                    if ((units -= 3) > -1) bytes.push(239, 191, 189);
                    continue;
                }
                // valid lead
                leadSurrogate = codePoint;
                continue;
            }
            // 2 leads in a row
            if (codePoint < 56320) {
                if ((units -= 3) > -1) bytes.push(239, 191, 189);
                leadSurrogate = codePoint;
                continue;
            }
            // valid surrogate pair
            codePoint = (leadSurrogate - 55296 << 10 | codePoint - 56320) + 65536;
        } else if (leadSurrogate) // valid bmp char, but last char was a lead
        {
            if ((units -= 3) > -1) bytes.push(239, 191, 189);
        }
        leadSurrogate = null;
        // encode utf8
        if (codePoint < 128) {
            if ((units -= 1) < 0) break;
            bytes.push(codePoint);
        } else if (codePoint < 2048) {
            if ((units -= 2) < 0) break;
            bytes.push(codePoint >> 6 | 192, codePoint & 63 | 128);
        } else if (codePoint < 65536) {
            if ((units -= 3) < 0) break;
            bytes.push(codePoint >> 12 | 224, codePoint >> 6 & 63 | 128, codePoint & 63 | 128);
        } else if (codePoint < 1114112) {
            if ((units -= 4) < 0) break;
            bytes.push(codePoint >> 18 | 240, codePoint >> 12 & 63 | 128, codePoint >> 6 & 63 | 128, codePoint & 63 | 128);
        } else throw new Error('Invalid code point');
    }
    return bytes;
}
function asciiToBytes(str) {
    var byteArray = [];
    for(var i = 0; i < str.length; ++i)// Node's code seems to be doing this and not & 0x7F..
    byteArray.push(str.charCodeAt(i) & 255);
    return byteArray;
}
function utf16leToBytes(str, units) {
    var c, hi, lo;
    var byteArray = [];
    for(var i = 0; i < str.length; ++i){
        if ((units -= 2) < 0) break;
        c = str.charCodeAt(i);
        hi = c >> 8;
        lo = c % 256;
        byteArray.push(lo);
        byteArray.push(hi);
    }
    return byteArray;
}
function base64ToBytes(str) {
    return base64.toByteArray(base64clean(str));
}
function blitBuffer(src, dst, offset, length) {
    for(var i = 0; i < length; ++i){
        if (i + offset >= dst.length || i >= src.length) break;
        dst[i + offset] = src[i];
    }
    return i;
}
// ArrayBuffer or Uint8Array objects from other contexts (i.e. iframes) do not pass
// the `instanceof` check but they should be treated as of that type.
// See: https://github.com/feross/buffer/issues/166
function isInstance(obj, type) {
    return obj instanceof type || obj != null && obj.constructor != null && obj.constructor.name != null && obj.constructor.name === type.name;
}
function numberIsNaN(obj) {
    // For IE11 support
    return obj !== obj // eslint-disable-line no-self-compare
    ;
}
// Create lookup table for `toString('hex')`
// See: https://github.com/feross/buffer/issues/219
var hexSliceLookupTable = function() {
    var alphabet = '0123456789abcdef';
    var table = new Array(256);
    for(var i = 0; i < 16; ++i){
        var i16 = i * 16;
        for(var j = 0; j < 16; ++j)table[i16 + j] = alphabet[i] + alphabet[j];
    }
    return table;
}();

},{"base64-js":"nR26C","ieee754":"ljh7N"}],"nR26C":[function(require,module,exports) {
'use strict';
exports.byteLength = byteLength;
exports.toByteArray = toByteArray;
exports.fromByteArray = fromByteArray;
var lookup = [];
var revLookup = [];
var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array;
var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
for(var i1 = 0, len1 = code.length; i1 < len1; ++i1){
    lookup[i1] = code[i1];
    revLookup[code.charCodeAt(i1)] = i1;
}
// Support decoding URL-safe base64 strings, as Node.js does.
// See: https://en.wikipedia.org/wiki/Base64#URL_applications
revLookup['-'.charCodeAt(0)] = 62;
revLookup['_'.charCodeAt(0)] = 63;
function getLens(b64) {
    var len = b64.length;
    if (len % 4 > 0) throw new Error('Invalid string. Length must be a multiple of 4');
    // Trim off extra bytes after placeholder bytes are found
    // See: https://github.com/beatgammit/base64-js/issues/42
    var validLen = b64.indexOf('=');
    if (validLen === -1) validLen = len;
    var placeHoldersLen = validLen === len ? 0 : 4 - validLen % 4;
    return [
        validLen,
        placeHoldersLen
    ];
}
// base64 is 4/3 + up to two characters of the original data
function byteLength(b64) {
    var lens = getLens(b64);
    var validLen = lens[0];
    var placeHoldersLen = lens[1];
    return (validLen + placeHoldersLen) * 3 / 4 - placeHoldersLen;
}
function _byteLength(b64, validLen, placeHoldersLen) {
    return (validLen + placeHoldersLen) * 3 / 4 - placeHoldersLen;
}
function toByteArray(b64) {
    var tmp;
    var lens = getLens(b64);
    var validLen = lens[0];
    var placeHoldersLen = lens[1];
    var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen));
    var curByte = 0;
    // if there are placeholders, only get up to the last complete 4 chars
    var len = placeHoldersLen > 0 ? validLen - 4 : validLen;
    var i;
    for(i = 0; i < len; i += 4){
        tmp = revLookup[b64.charCodeAt(i)] << 18 | revLookup[b64.charCodeAt(i + 1)] << 12 | revLookup[b64.charCodeAt(i + 2)] << 6 | revLookup[b64.charCodeAt(i + 3)];
        arr[curByte++] = tmp >> 16 & 255;
        arr[curByte++] = tmp >> 8 & 255;
        arr[curByte++] = tmp & 255;
    }
    if (placeHoldersLen === 2) {
        tmp = revLookup[b64.charCodeAt(i)] << 2 | revLookup[b64.charCodeAt(i + 1)] >> 4;
        arr[curByte++] = tmp & 255;
    }
    if (placeHoldersLen === 1) {
        tmp = revLookup[b64.charCodeAt(i)] << 10 | revLookup[b64.charCodeAt(i + 1)] << 4 | revLookup[b64.charCodeAt(i + 2)] >> 2;
        arr[curByte++] = tmp >> 8 & 255;
        arr[curByte++] = tmp & 255;
    }
    return arr;
}
function tripletToBase64(num) {
    return lookup[num >> 18 & 63] + lookup[num >> 12 & 63] + lookup[num >> 6 & 63] + lookup[num & 63];
}
function encodeChunk(uint8, start, end) {
    var tmp;
    var output = [];
    for(var i = start; i < end; i += 3){
        tmp = (uint8[i] << 16 & 16711680) + (uint8[i + 1] << 8 & 65280) + (uint8[i + 2] & 255);
        output.push(tripletToBase64(tmp));
    }
    return output.join('');
}
function fromByteArray(uint8) {
    var tmp;
    var len = uint8.length;
    var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
    ;
    var parts = [];
    var maxChunkLength = 16383 // must be multiple of 3
    ;
    // go through the array every three bytes, we'll deal with trailing stuff later
    for(var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength)parts.push(encodeChunk(uint8, i, i + maxChunkLength > len2 ? len2 : i + maxChunkLength));
    // pad the end with zeros, but make sure to not forget the extra bytes
    if (extraBytes === 1) {
        tmp = uint8[len - 1];
        parts.push(lookup[tmp >> 2] + lookup[tmp << 4 & 63] + '==');
    } else if (extraBytes === 2) {
        tmp = (uint8[len - 2] << 8) + uint8[len - 1];
        parts.push(lookup[tmp >> 10] + lookup[tmp >> 4 & 63] + lookup[tmp << 2 & 63] + '=');
    }
    return parts.join('');
}

},{}],"ljh7N":[function(require,module,exports) {
/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */ exports.read = function(buffer, offset, isLE, mLen, nBytes) {
    var e, m;
    var eLen = nBytes * 8 - mLen - 1;
    var eMax = (1 << eLen) - 1;
    var eBias = eMax >> 1;
    var nBits = -7;
    var i = isLE ? nBytes - 1 : 0;
    var d = isLE ? -1 : 1;
    var s = buffer[offset + i];
    i += d;
    e = s & (1 << -nBits) - 1;
    s >>= -nBits;
    nBits += eLen;
    for(; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8);
    m = e & (1 << -nBits) - 1;
    e >>= -nBits;
    nBits += mLen;
    for(; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8);
    if (e === 0) e = 1 - eBias;
    else if (e === eMax) return m ? NaN : (s ? -1 : 1) * Infinity;
    else {
        m = m + Math.pow(2, mLen);
        e = e - eBias;
    }
    return (s ? -1 : 1) * m * Math.pow(2, e - mLen);
};
exports.write = function(buffer, value, offset, isLE, mLen, nBytes) {
    var e, m, c;
    var eLen = nBytes * 8 - mLen - 1;
    var eMax = (1 << eLen) - 1;
    var eBias = eMax >> 1;
    var rt = mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0;
    var i = isLE ? 0 : nBytes - 1;
    var d = isLE ? 1 : -1;
    var s = value < 0 || value === 0 && 1 / value < 0 ? 1 : 0;
    value = Math.abs(value);
    if (isNaN(value) || value === Infinity) {
        m = isNaN(value) ? 1 : 0;
        e = eMax;
    } else {
        e = Math.floor(Math.log(value) / Math.LN2);
        if (value * (c = Math.pow(2, -e)) < 1) {
            e--;
            c *= 2;
        }
        if (e + eBias >= 1) value += rt / c;
        else value += rt * Math.pow(2, 1 - eBias);
        if (value * c >= 2) {
            e++;
            c /= 2;
        }
        if (e + eBias >= eMax) {
            m = 0;
            e = eMax;
        } else if (e + eBias >= 1) {
            m = (value * c - 1) * Math.pow(2, mLen);
            e = e + eBias;
        } else {
            m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen);
            e = 0;
        }
    }
    for(; mLen >= 8; buffer[offset + i] = m & 255, i += d, m /= 256, mLen -= 8);
    e = e << mLen | m;
    eLen += mLen;
    for(; eLen > 0; buffer[offset + i] = e & 255, i += d, e /= 256, eLen -= 8);
    buffer[offset + i - d] |= s * 128;
};

},{}],"hoBU8":[function(require,module,exports) {
const Rabin = require('./rabin');
const getRabin = require('../dist/rabin-wasm.node.js');
const create = async (avg, min, max, windowSize, polynomial)=>{
    const compiled = await getRabin();
    return new Rabin(compiled, avg, min, max, windowSize, polynomial);
};
module.exports = {
    Rabin,
    create
};

},{"./rabin":"6UjD2","../dist/rabin-wasm.node.js":"5bl4Q"}],"6UjD2":[function(require,module,exports) {
/**
 * Rabin fingerprinting
 *
 * @class Rabin
 */ class Rabin {
    /**
     * Creates an instance of Rabin.
     * @param { import("./../dist/rabin-wasm") } asModule
     * @param {number} [bits=12]
     * @param {number} [min=8 * 1024]
     * @param {number} [max=32 * 1024]
     * @param {number} polynomial
     * @memberof Rabin
     */ constructor(asModule, bits = 12, min = 8192, max = 32768, windowSize = 64, polynomial){
        this.bits = bits;
        this.min = min;
        this.max = max;
        this.asModule = asModule;
        this.rabin = new asModule.Rabin(bits, min, max, windowSize, polynomial);
        this.polynomial = polynomial;
    }
    /**
     * Fingerprints the buffer
     *
     * @param {Uint8Array} buf
     * @returns {Array<number>}
     * @memberof Rabin
     */ fingerprint(buf) {
        const { __retain , __release , __allocArray , __getInt32Array , Int32Array_ID , Uint8Array_ID  } = this.asModule;
        const lengths = new Int32Array(Math.ceil(buf.length / this.min));
        const lengthsPtr = __retain(__allocArray(Int32Array_ID, lengths));
        const pointer = __retain(__allocArray(Uint8Array_ID, buf));
        const out = this.rabin.fingerprint(pointer, lengthsPtr);
        const processed = __getInt32Array(out);
        __release(pointer);
        __release(lengthsPtr);
        const end = processed.indexOf(0);
        return end >= 0 ? processed.subarray(0, end) : processed;
    }
}
module.exports = Rabin;

},{}],"5bl4Q":[function(require,module,exports) {
const { instantiate  } = require("@assemblyscript/loader");
loadWebAssembly.supported = typeof WebAssembly !== 'undefined';
function loadWebAssembly(imp = {
}) {
    if (!loadWebAssembly.supported) return null;
    var wasm = new Uint8Array([
        0,
        97,
        115,
        109,
        1,
        0,
        0,
        0,
        1,
        78,
        14,
        96,
        2,
        127,
        126,
        0,
        96,
        1,
        127,
        1,
        126,
        96,
        2,
        127,
        127,
        0,
        96,
        1,
        127,
        1,
        127,
        96,
        1,
        127,
        0,
        96,
        2,
        127,
        127,
        1,
        127,
        96,
        3,
        127,
        127,
        127,
        1,
        127,
        96,
        0,
        0,
        96,
        3,
        127,
        127,
        127,
        0,
        96,
        0,
        1,
        127,
        96,
        4,
        127,
        127,
        127,
        127,
        0,
        96,
        5,
        127,
        127,
        127,
        127,
        127,
        1,
        127,
        96,
        1,
        126,
        1,
        127,
        96,
        2,
        126,
        126,
        1,
        126,
        2,
        13,
        1,
        3,
        101,
        110,
        118,
        5,
        97,
        98,
        111,
        114,
        116,
        0,
        10,
        3,
        54,
        53,
        2,
        2,
        8,
        9,
        3,
        5,
        2,
        8,
        6,
        5,
        3,
        4,
        2,
        6,
        9,
        12,
        13,
        2,
        5,
        11,
        3,
        2,
        3,
        2,
        3,
        2,
        1,
        0,
        1,
        0,
        1,
        0,
        1,
        0,
        1,
        0,
        1,
        0,
        1,
        0,
        1,
        0,
        1,
        0,
        1,
        0,
        1,
        0,
        6,
        7,
        7,
        4,
        4,
        5,
        3,
        1,
        0,
        1,
        6,
        47,
        9,
        127,
        1,
        65,
        0,
        11,
        127,
        1,
        65,
        0,
        11,
        127,
        0,
        65,
        3,
        11,
        127,
        0,
        65,
        4,
        11,
        127,
        1,
        65,
        0,
        11,
        127,
        1,
        65,
        0,
        11,
        127,
        1,
        65,
        0,
        11,
        127,
        0,
        65,
        240,
        2,
        11,
        127,
        0,
        65,
        6,
        11,
        7,
        240,
        5,
        41,
        6,
        109,
        101,
        109,
        111,
        114,
        121,
        2,
        0,
        7,
        95,
        95,
        97,
        108,
        108,
        111,
        99,
        0,
        10,
        8,
        95,
        95,
        114,
        101,
        116,
        97,
        105,
        110,
        0,
        11,
        9,
        95,
        95,
        114,
        101,
        108,
        101,
        97,
        115,
        101,
        0,
        12,
        9,
        95,
        95,
        99,
        111,
        108,
        108,
        101,
        99,
        116,
        0,
        51,
        11,
        95,
        95,
        114,
        116,
        116,
        105,
        95,
        98,
        97,
        115,
        101,
        3,
        7,
        13,
        73,
        110,
        116,
        51,
        50,
        65,
        114,
        114,
        97,
        121,
        95,
        73,
        68,
        3,
        2,
        13,
        85,
        105,
        110,
        116,
        56,
        65,
        114,
        114,
        97,
        121,
        95,
        73,
        68,
        3,
        3,
        6,
        100,
        101,
        103,
        114,
        101,
        101,
        0,
        16,
        3,
        109,
        111,
        100,
        0,
        17,
        5,
        82,
        97,
        98,
        105,
        110,
        3,
        8,
        16,
        82,
        97,
        98,
        105,
        110,
        35,
        103,
        101,
        116,
        58,
        119,
        105,
        110,
        100,
        111,
        119,
        0,
        21,
        16,
        82,
        97,
        98,
        105,
        110,
        35,
        115,
        101,
        116,
        58,
        119,
        105,
        110,
        100,
        111,
        119,
        0,
        22,
        21,
        82,
        97,
        98,
        105,
        110,
        35,
        103,
        101,
        116,
        58,
        119,
        105,
        110,
        100,
        111,
        119,
        95,
        115,
        105,
        122,
        101,
        0,
        23,
        21,
        82,
        97,
        98,
        105,
        110,
        35,
        115,
        101,
        116,
        58,
        119,
        105,
        110,
        100,
        111,
        119,
        95,
        115,
        105,
        122,
        101,
        0,
        24,
        14,
        82,
        97,
        98,
        105,
        110,
        35,
        103,
        101,
        116,
        58,
        119,
        112,
        111,
        115,
        0,
        25,
        14,
        82,
        97,
        98,
        105,
        110,
        35,
        115,
        101,
        116,
        58,
        119,
        112,
        111,
        115,
        0,
        26,
        15,
        82,
        97,
        98,
        105,
        110,
        35,
        103,
        101,
        116,
        58,
        99,
        111,
        117,
        110,
        116,
        0,
        27,
        15,
        82,
        97,
        98,
        105,
        110,
        35,
        115,
        101,
        116,
        58,
        99,
        111,
        117,
        110,
        116,
        0,
        28,
        13,
        82,
        97,
        98,
        105,
        110,
        35,
        103,
        101,
        116,
        58,
        112,
        111,
        115,
        0,
        29,
        13,
        82,
        97,
        98,
        105,
        110,
        35,
        115,
        101,
        116,
        58,
        112,
        111,
        115,
        0,
        30,
        15,
        82,
        97,
        98,
        105,
        110,
        35,
        103,
        101,
        116,
        58,
        115,
        116,
        97,
        114,
        116,
        0,
        31,
        15,
        82,
        97,
        98,
        105,
        110,
        35,
        115,
        101,
        116,
        58,
        115,
        116,
        97,
        114,
        116,
        0,
        32,
        16,
        82,
        97,
        98,
        105,
        110,
        35,
        103,
        101,
        116,
        58,
        100,
        105,
        103,
        101,
        115,
        116,
        0,
        33,
        16,
        82,
        97,
        98,
        105,
        110,
        35,
        115,
        101,
        116,
        58,
        100,
        105,
        103,
        101,
        115,
        116,
        0,
        34,
        21,
        82,
        97,
        98,
        105,
        110,
        35,
        103,
        101,
        116,
        58,
        99,
        104,
        117,
        110,
        107,
        95,
        115,
        116,
        97,
        114,
        116,
        0,
        35,
        21,
        82,
        97,
        98,
        105,
        110,
        35,
        115,
        101,
        116,
        58,
        99,
        104,
        117,
        110,
        107,
        95,
        115,
        116,
        97,
        114,
        116,
        0,
        36,
        22,
        82,
        97,
        98,
        105,
        110,
        35,
        103,
        101,
        116,
        58,
        99,
        104,
        117,
        110,
        107,
        95,
        108,
        101,
        110,
        103,
        116,
        104,
        0,
        37,
        22,
        82,
        97,
        98,
        105,
        110,
        35,
        115,
        101,
        116,
        58,
        99,
        104,
        117,
        110,
        107,
        95,
        108,
        101,
        110,
        103,
        116,
        104,
        0,
        38,
        31,
        82,
        97,
        98,
        105,
        110,
        35,
        103,
        101,
        116,
        58,
        99,
        104,
        117,
        110,
        107,
        95,
        99,
        117,
        116,
        95,
        102,
        105,
        110,
        103,
        101,
        114,
        112,
        114,
        105,
        110,
        116,
        0,
        39,
        31,
        82,
        97,
        98,
        105,
        110,
        35,
        115,
        101,
        116,
        58,
        99,
        104,
        117,
        110,
        107,
        95,
        99,
        117,
        116,
        95,
        102,
        105,
        110,
        103,
        101,
        114,
        112,
        114,
        105,
        110,
        116,
        0,
        40,
        20,
        82,
        97,
        98,
        105,
        110,
        35,
        103,
        101,
        116,
        58,
        112,
        111,
        108,
        121,
        110,
        111,
        109,
        105,
        97,
        108,
        0,
        41,
        20,
        82,
        97,
        98,
        105,
        110,
        35,
        115,
        101,
        116,
        58,
        112,
        111,
        108,
        121,
        110,
        111,
        109,
        105,
        97,
        108,
        0,
        42,
        17,
        82,
        97,
        98,
        105,
        110,
        35,
        103,
        101,
        116,
        58,
        109,
        105,
        110,
        115,
        105,
        122,
        101,
        0,
        43,
        17,
        82,
        97,
        98,
        105,
        110,
        35,
        115,
        101,
        116,
        58,
        109,
        105,
        110,
        115,
        105,
        122,
        101,
        0,
        44,
        17,
        82,
        97,
        98,
        105,
        110,
        35,
        103,
        101,
        116,
        58,
        109,
        97,
        120,
        115,
        105,
        122,
        101,
        0,
        45,
        17,
        82,
        97,
        98,
        105,
        110,
        35,
        115,
        101,
        116,
        58,
        109,
        97,
        120,
        115,
        105,
        122,
        101,
        0,
        46,
        14,
        82,
        97,
        98,
        105,
        110,
        35,
        103,
        101,
        116,
        58,
        109,
        97,
        115,
        107,
        0,
        47,
        14,
        82,
        97,
        98,
        105,
        110,
        35,
        115,
        101,
        116,
        58,
        109,
        97,
        115,
        107,
        0,
        48,
        17,
        82,
        97,
        98,
        105,
        110,
        35,
        99,
        111,
        110,
        115,
        116,
        114,
        117,
        99,
        116,
        111,
        114,
        0,
        20,
        17,
        82,
        97,
        98,
        105,
        110,
        35,
        102,
        105,
        110,
        103,
        101,
        114,
        112,
        114,
        105,
        110,
        116,
        0,
        49,
        8,
        1,
        50,
        10,
        165,
        31,
        53,
        199,
        1,
        1,
        4,
        127,
        32,
        1,
        40,
        2,
        0,
        65,
        124,
        113,
        34,
        2,
        65,
        128,
        2,
        73,
        4,
        127,
        32,
        2,
        65,
        4,
        118,
        33,
        4,
        65,
        0,
        5,
        32,
        2,
        65,
        31,
        32,
        2,
        103,
        107,
        34,
        3,
        65,
        4,
        107,
        118,
        65,
        16,
        115,
        33,
        4,
        32,
        3,
        65,
        7,
        107,
        11,
        33,
        3,
        32,
        1,
        40,
        2,
        20,
        33,
        2,
        32,
        1,
        40,
        2,
        16,
        34,
        5,
        4,
        64,
        32,
        5,
        32,
        2,
        54,
        2,
        20,
        11,
        32,
        2,
        4,
        64,
        32,
        2,
        32,
        5,
        54,
        2,
        16,
        11,
        32,
        1,
        32,
        0,
        32,
        4,
        32,
        3,
        65,
        4,
        116,
        106,
        65,
        2,
        116,
        106,
        40,
        2,
        96,
        70,
        4,
        64,
        32,
        0,
        32,
        4,
        32,
        3,
        65,
        4,
        116,
        106,
        65,
        2,
        116,
        106,
        32,
        2,
        54,
        2,
        96,
        32,
        2,
        69,
        4,
        64,
        32,
        0,
        32,
        3,
        65,
        2,
        116,
        106,
        32,
        0,
        32,
        3,
        65,
        2,
        116,
        106,
        40,
        2,
        4,
        65,
        1,
        32,
        4,
        116,
        65,
        127,
        115,
        113,
        34,
        1,
        54,
        2,
        4,
        32,
        1,
        69,
        4,
        64,
        32,
        0,
        32,
        0,
        40,
        2,
        0,
        65,
        1,
        32,
        3,
        116,
        65,
        127,
        115,
        113,
        54,
        2,
        0,
        11,
        11,
        11,
        11,
        226,
        2,
        1,
        6,
        127,
        32,
        1,
        40,
        2,
        0,
        33,
        3,
        32,
        1,
        65,
        16,
        106,
        32,
        1,
        40,
        2,
        0,
        65,
        124,
        113,
        106,
        34,
        4,
        40,
        2,
        0,
        34,
        5,
        65,
        1,
        113,
        4,
        64,
        32,
        3,
        65,
        124,
        113,
        65,
        16,
        106,
        32,
        5,
        65,
        124,
        113,
        106,
        34,
        2,
        65,
        240,
        255,
        255,
        255,
        3,
        73,
        4,
        64,
        32,
        0,
        32,
        4,
        16,
        1,
        32,
        1,
        32,
        2,
        32,
        3,
        65,
        3,
        113,
        114,
        34,
        3,
        54,
        2,
        0,
        32,
        1,
        65,
        16,
        106,
        32,
        1,
        40,
        2,
        0,
        65,
        124,
        113,
        106,
        34,
        4,
        40,
        2,
        0,
        33,
        5,
        11,
        11,
        32,
        3,
        65,
        2,
        113,
        4,
        64,
        32,
        1,
        65,
        4,
        107,
        40,
        2,
        0,
        34,
        2,
        40,
        2,
        0,
        34,
        6,
        65,
        124,
        113,
        65,
        16,
        106,
        32,
        3,
        65,
        124,
        113,
        106,
        34,
        7,
        65,
        240,
        255,
        255,
        255,
        3,
        73,
        4,
        64,
        32,
        0,
        32,
        2,
        16,
        1,
        32,
        2,
        32,
        7,
        32,
        6,
        65,
        3,
        113,
        114,
        34,
        3,
        54,
        2,
        0,
        32,
        2,
        33,
        1,
        11,
        11,
        32,
        4,
        32,
        5,
        65,
        2,
        114,
        54,
        2,
        0,
        32,
        4,
        65,
        4,
        107,
        32,
        1,
        54,
        2,
        0,
        32,
        0,
        32,
        3,
        65,
        124,
        113,
        34,
        2,
        65,
        128,
        2,
        73,
        4,
        127,
        32,
        2,
        65,
        4,
        118,
        33,
        4,
        65,
        0,
        5,
        32,
        2,
        65,
        31,
        32,
        2,
        103,
        107,
        34,
        2,
        65,
        4,
        107,
        118,
        65,
        16,
        115,
        33,
        4,
        32,
        2,
        65,
        7,
        107,
        11,
        34,
        3,
        65,
        4,
        116,
        32,
        4,
        106,
        65,
        2,
        116,
        106,
        40,
        2,
        96,
        33,
        2,
        32,
        1,
        65,
        0,
        54,
        2,
        16,
        32,
        1,
        32,
        2,
        54,
        2,
        20,
        32,
        2,
        4,
        64,
        32,
        2,
        32,
        1,
        54,
        2,
        16,
        11,
        32,
        0,
        32,
        4,
        32,
        3,
        65,
        4,
        116,
        106,
        65,
        2,
        116,
        106,
        32,
        1,
        54,
        2,
        96,
        32,
        0,
        32,
        0,
        40,
        2,
        0,
        65,
        1,
        32,
        3,
        116,
        114,
        54,
        2,
        0,
        32,
        0,
        32,
        3,
        65,
        2,
        116,
        106,
        32,
        0,
        32,
        3,
        65,
        2,
        116,
        106,
        40,
        2,
        4,
        65,
        1,
        32,
        4,
        116,
        114,
        54,
        2,
        4,
        11,
        119,
        1,
        1,
        127,
        32,
        2,
        2,
        127,
        32,
        0,
        40,
        2,
        160,
        12,
        34,
        2,
        4,
        64,
        32,
        2,
        32,
        1,
        65,
        16,
        107,
        70,
        4,
        64,
        32,
        2,
        40,
        2,
        0,
        33,
        3,
        32,
        1,
        65,
        16,
        107,
        33,
        1,
        11,
        11,
        32,
        1,
        11,
        107,
        34,
        2,
        65,
        48,
        73,
        4,
        64,
        15,
        11,
        32,
        1,
        32,
        3,
        65,
        2,
        113,
        32,
        2,
        65,
        32,
        107,
        65,
        1,
        114,
        114,
        54,
        2,
        0,
        32,
        1,
        65,
        0,
        54,
        2,
        16,
        32,
        1,
        65,
        0,
        54,
        2,
        20,
        32,
        1,
        32,
        2,
        106,
        65,
        16,
        107,
        34,
        2,
        65,
        2,
        54,
        2,
        0,
        32,
        0,
        32,
        2,
        54,
        2,
        160,
        12,
        32,
        0,
        32,
        1,
        16,
        2,
        11,
        155,
        1,
        1,
        3,
        127,
        35,
        0,
        34,
        0,
        69,
        4,
        64,
        65,
        1,
        63,
        0,
        34,
        0,
        74,
        4,
        127,
        65,
        1,
        32,
        0,
        107,
        64,
        0,
        65,
        0,
        72,
        5,
        65,
        0,
        11,
        4,
        64,
        0,
        11,
        65,
        176,
        3,
        34,
        0,
        65,
        0,
        54,
        2,
        0,
        65,
        208,
        15,
        65,
        0,
        54,
        2,
        0,
        3,
        64,
        32,
        1,
        65,
        23,
        73,
        4,
        64,
        32,
        1,
        65,
        2,
        116,
        65,
        176,
        3,
        106,
        65,
        0,
        54,
        2,
        4,
        65,
        0,
        33,
        2,
        3,
        64,
        32,
        2,
        65,
        16,
        73,
        4,
        64,
        32,
        1,
        65,
        4,
        116,
        32,
        2,
        106,
        65,
        2,
        116,
        65,
        176,
        3,
        106,
        65,
        0,
        54,
        2,
        96,
        32,
        2,
        65,
        1,
        106,
        33,
        2,
        12,
        1,
        11,
        11,
        32,
        1,
        65,
        1,
        106,
        33,
        1,
        12,
        1,
        11,
        11,
        65,
        176,
        3,
        65,
        224,
        15,
        63,
        0,
        65,
        16,
        116,
        16,
        3,
        65,
        176,
        3,
        36,
        0,
        11,
        32,
        0,
        11,
        45,
        0,
        32,
        0,
        65,
        240,
        255,
        255,
        255,
        3,
        79,
        4,
        64,
        65,
        32,
        65,
        224,
        0,
        65,
        201,
        3,
        65,
        29,
        16,
        0,
        0,
        11,
        32,
        0,
        65,
        15,
        106,
        65,
        112,
        113,
        34,
        0,
        65,
        16,
        32,
        0,
        65,
        16,
        75,
        27,
        11,
        169,
        1,
        1,
        1,
        127,
        32,
        0,
        32,
        1,
        65,
        128,
        2,
        73,
        4,
        127,
        32,
        1,
        65,
        4,
        118,
        33,
        1,
        65,
        0,
        5,
        32,
        1,
        65,
        248,
        255,
        255,
        255,
        1,
        73,
        4,
        64,
        32,
        1,
        65,
        1,
        65,
        27,
        32,
        1,
        103,
        107,
        116,
        106,
        65,
        1,
        107,
        33,
        1,
        11,
        32,
        1,
        65,
        31,
        32,
        1,
        103,
        107,
        34,
        2,
        65,
        4,
        107,
        118,
        65,
        16,
        115,
        33,
        1,
        32,
        2,
        65,
        7,
        107,
        11,
        34,
        2,
        65,
        2,
        116,
        106,
        40,
        2,
        4,
        65,
        127,
        32,
        1,
        116,
        113,
        34,
        1,
        4,
        127,
        32,
        0,
        32,
        1,
        104,
        32,
        2,
        65,
        4,
        116,
        106,
        65,
        2,
        116,
        106,
        40,
        2,
        96,
        5,
        32,
        0,
        40,
        2,
        0,
        65,
        127,
        32,
        2,
        65,
        1,
        106,
        116,
        113,
        34,
        1,
        4,
        127,
        32,
        0,
        32,
        0,
        32,
        1,
        104,
        34,
        0,
        65,
        2,
        116,
        106,
        40,
        2,
        4,
        104,
        32,
        0,
        65,
        4,
        116,
        106,
        65,
        2,
        116,
        106,
        40,
        2,
        96,
        5,
        65,
        0,
        11,
        11,
        11,
        111,
        1,
        1,
        127,
        63,
        0,
        34,
        2,
        32,
        1,
        65,
        248,
        255,
        255,
        255,
        1,
        73,
        4,
        127,
        32,
        1,
        65,
        1,
        65,
        27,
        32,
        1,
        103,
        107,
        116,
        65,
        1,
        107,
        106,
        5,
        32,
        1,
        11,
        65,
        16,
        32,
        0,
        40,
        2,
        160,
        12,
        32,
        2,
        65,
        16,
        116,
        65,
        16,
        107,
        71,
        116,
        106,
        65,
        255,
        255,
        3,
        106,
        65,
        128,
        128,
        124,
        113,
        65,
        16,
        118,
        34,
        1,
        32,
        2,
        32,
        1,
        74,
        27,
        64,
        0,
        65,
        0,
        72,
        4,
        64,
        32,
        1,
        64,
        0,
        65,
        0,
        72,
        4,
        64,
        0,
        11,
        11,
        32,
        0,
        32,
        2,
        65,
        16,
        116,
        63,
        0,
        65,
        16,
        116,
        16,
        3,
        11,
        113,
        1,
        2,
        127,
        32,
        1,
        40,
        2,
        0,
        34,
        3,
        65,
        124,
        113,
        32,
        2,
        107,
        34,
        4,
        65,
        32,
        79,
        4,
        64,
        32,
        1,
        32,
        2,
        32,
        3,
        65,
        2,
        113,
        114,
        54,
        2,
        0,
        32,
        2,
        32,
        1,
        65,
        16,
        106,
        106,
        34,
        1,
        32,
        4,
        65,
        16,
        107,
        65,
        1,
        114,
        54,
        2,
        0,
        32,
        0,
        32,
        1,
        16,
        2,
        5,
        32,
        1,
        32,
        3,
        65,
        126,
        113,
        54,
        2,
        0,
        32,
        1,
        65,
        16,
        106,
        32,
        1,
        40,
        2,
        0,
        65,
        124,
        113,
        106,
        32,
        1,
        65,
        16,
        106,
        32,
        1,
        40,
        2,
        0,
        65,
        124,
        113,
        106,
        40,
        2,
        0,
        65,
        125,
        113,
        54,
        2,
        0,
        11,
        11,
        91,
        1,
        2,
        127,
        32,
        0,
        32,
        1,
        16,
        5,
        34,
        4,
        16,
        6,
        34,
        3,
        69,
        4,
        64,
        65,
        1,
        36,
        1,
        65,
        0,
        36,
        1,
        32,
        0,
        32,
        4,
        16,
        6,
        34,
        3,
        69,
        4,
        64,
        32,
        0,
        32,
        4,
        16,
        7,
        32,
        0,
        32,
        4,
        16,
        6,
        33,
        3,
        11,
        11,
        32,
        3,
        65,
        0,
        54,
        2,
        4,
        32,
        3,
        32,
        2,
        54,
        2,
        8,
        32,
        3,
        32,
        1,
        54,
        2,
        12,
        32,
        0,
        32,
        3,
        16,
        1,
        32,
        0,
        32,
        3,
        32,
        4,
        16,
        8,
        32,
        3,
        11,
        13,
        0,
        16,
        4,
        32,
        0,
        32,
        1,
        16,
        9,
        65,
        16,
        106,
        11,
        33,
        1,
        1,
        127,
        32,
        0,
        65,
        172,
        3,
        75,
        4,
        64,
        32,
        0,
        65,
        16,
        107,
        34,
        1,
        32,
        1,
        40,
        2,
        4,
        65,
        1,
        106,
        54,
        2,
        4,
        11,
        32,
        0,
        11,
        18,
        0,
        32,
        0,
        65,
        172,
        3,
        75,
        4,
        64,
        32,
        0,
        65,
        16,
        107,
        16,
        52,
        11,
        11,
        140,
        3,
        1,
        1,
        127,
        2,
        64,
        32,
        1,
        69,
        13,
        0,
        32,
        0,
        65,
        0,
        58,
        0,
        0,
        32,
        0,
        32,
        1,
        106,
        65,
        1,
        107,
        65,
        0,
        58,
        0,
        0,
        32,
        1,
        65,
        2,
        77,
        13,
        0,
        32,
        0,
        65,
        1,
        106,
        65,
        0,
        58,
        0,
        0,
        32,
        0,
        65,
        2,
        106,
        65,
        0,
        58,
        0,
        0,
        32,
        0,
        32,
        1,
        106,
        34,
        2,
        65,
        2,
        107,
        65,
        0,
        58,
        0,
        0,
        32,
        2,
        65,
        3,
        107,
        65,
        0,
        58,
        0,
        0,
        32,
        1,
        65,
        6,
        77,
        13,
        0,
        32,
        0,
        65,
        3,
        106,
        65,
        0,
        58,
        0,
        0,
        32,
        0,
        32,
        1,
        106,
        65,
        4,
        107,
        65,
        0,
        58,
        0,
        0,
        32,
        1,
        65,
        8,
        77,
        13,
        0,
        32,
        1,
        65,
        0,
        32,
        0,
        107,
        65,
        3,
        113,
        34,
        1,
        107,
        33,
        2,
        32,
        0,
        32,
        1,
        106,
        34,
        0,
        65,
        0,
        54,
        2,
        0,
        32,
        0,
        32,
        2,
        65,
        124,
        113,
        34,
        1,
        106,
        65,
        4,
        107,
        65,
        0,
        54,
        2,
        0,
        32,
        1,
        65,
        8,
        77,
        13,
        0,
        32,
        0,
        65,
        4,
        106,
        65,
        0,
        54,
        2,
        0,
        32,
        0,
        65,
        8,
        106,
        65,
        0,
        54,
        2,
        0,
        32,
        0,
        32,
        1,
        106,
        34,
        2,
        65,
        12,
        107,
        65,
        0,
        54,
        2,
        0,
        32,
        2,
        65,
        8,
        107,
        65,
        0,
        54,
        2,
        0,
        32,
        1,
        65,
        24,
        77,
        13,
        0,
        32,
        0,
        65,
        12,
        106,
        65,
        0,
        54,
        2,
        0,
        32,
        0,
        65,
        16,
        106,
        65,
        0,
        54,
        2,
        0,
        32,
        0,
        65,
        20,
        106,
        65,
        0,
        54,
        2,
        0,
        32,
        0,
        65,
        24,
        106,
        65,
        0,
        54,
        2,
        0,
        32,
        0,
        32,
        1,
        106,
        34,
        2,
        65,
        28,
        107,
        65,
        0,
        54,
        2,
        0,
        32,
        2,
        65,
        24,
        107,
        65,
        0,
        54,
        2,
        0,
        32,
        2,
        65,
        20,
        107,
        65,
        0,
        54,
        2,
        0,
        32,
        2,
        65,
        16,
        107,
        65,
        0,
        54,
        2,
        0,
        32,
        0,
        32,
        0,
        65,
        4,
        113,
        65,
        24,
        106,
        34,
        2,
        106,
        33,
        0,
        32,
        1,
        32,
        2,
        107,
        33,
        1,
        3,
        64,
        32,
        1,
        65,
        32,
        79,
        4,
        64,
        32,
        0,
        66,
        0,
        55,
        3,
        0,
        32,
        0,
        65,
        8,
        106,
        66,
        0,
        55,
        3,
        0,
        32,
        0,
        65,
        16,
        106,
        66,
        0,
        55,
        3,
        0,
        32,
        0,
        65,
        24,
        106,
        66,
        0,
        55,
        3,
        0,
        32,
        1,
        65,
        32,
        107,
        33,
        1,
        32,
        0,
        65,
        32,
        106,
        33,
        0,
        12,
        1,
        11,
        11,
        11,
        11,
        178,
        1,
        1,
        3,
        127,
        32,
        1,
        65,
        240,
        255,
        255,
        255,
        3,
        32,
        2,
        118,
        75,
        4,
        64,
        65,
        144,
        1,
        65,
        192,
        1,
        65,
        23,
        65,
        56,
        16,
        0,
        0,
        11,
        32,
        1,
        32,
        2,
        116,
        34,
        3,
        65,
        0,
        16,
        10,
        34,
        2,
        32,
        3,
        16,
        13,
        32,
        0,
        69,
        4,
        64,
        65,
        12,
        65,
        2,
        16,
        10,
        34,
        0,
        65,
        172,
        3,
        75,
        4,
        64,
        32,
        0,
        65,
        16,
        107,
        34,
        1,
        32,
        1,
        40,
        2,
        4,
        65,
        1,
        106,
        54,
        2,
        4,
        11,
        11,
        32,
        0,
        65,
        0,
        54,
        2,
        0,
        32,
        0,
        65,
        0,
        54,
        2,
        4,
        32,
        0,
        65,
        0,
        54,
        2,
        8,
        32,
        2,
        34,
        1,
        32,
        0,
        40,
        2,
        0,
        34,
        4,
        71,
        4,
        64,
        32,
        1,
        65,
        172,
        3,
        75,
        4,
        64,
        32,
        1,
        65,
        16,
        107,
        34,
        5,
        32,
        5,
        40,
        2,
        4,
        65,
        1,
        106,
        54,
        2,
        4,
        11,
        32,
        4,
        16,
        12,
        11,
        32,
        0,
        32,
        1,
        54,
        2,
        0,
        32,
        0,
        32,
        2,
        54,
        2,
        4,
        32,
        0,
        32,
        3,
        54,
        2,
        8,
        32,
        0,
        11,
        46,
        1,
        2,
        127,
        65,
        12,
        65,
        5,
        16,
        10,
        34,
        0,
        65,
        172,
        3,
        75,
        4,
        64,
        32,
        0,
        65,
        16,
        107,
        34,
        1,
        32,
        1,
        40,
        2,
        4,
        65,
        1,
        106,
        54,
        2,
        4,
        11,
        32,
        0,
        65,
        128,
        2,
        65,
        3,
        16,
        14,
        11,
        9,
        0,
        65,
        63,
        32,
        0,
        121,
        167,
        107,
        11,
        49,
        1,
        2,
        127,
        65,
        63,
        32,
        1,
        121,
        167,
        107,
        33,
        2,
        3,
        64,
        65,
        63,
        32,
        0,
        121,
        167,
        107,
        32,
        2,
        107,
        34,
        3,
        65,
        0,
        78,
        4,
        64,
        32,
        0,
        32,
        1,
        32,
        3,
        172,
        134,
        133,
        33,
        0,
        12,
        1,
        11,
        11,
        32,
        0,
        11,
        40,
        0,
        32,
        1,
        32,
        0,
        40,
        2,
        8,
        79,
        4,
        64,
        65,
        128,
        2,
        65,
        192,
        2,
        65,
        163,
        1,
        65,
        44,
        16,
        0,
        0,
        11,
        32,
        1,
        32,
        0,
        40,
        2,
        4,
        106,
        65,
        0,
        58,
        0,
        0,
        11,
        38,
        0,
        32,
        1,
        32,
        0,
        40,
        2,
        8,
        79,
        4,
        64,
        65,
        128,
        2,
        65,
        192,
        2,
        65,
        152,
        1,
        65,
        44,
        16,
        0,
        0,
        11,
        32,
        1,
        32,
        0,
        40,
        2,
        4,
        106,
        45,
        0,
        0,
        11,
        254,
        5,
        2,
        1,
        127,
        4,
        126,
        32,
        0,
        69,
        4,
        64,
        65,
        232,
        0,
        65,
        6,
        16,
        10,
        34,
        0,
        65,
        172,
        3,
        75,
        4,
        64,
        32,
        0,
        65,
        16,
        107,
        34,
        5,
        32,
        5,
        40,
        2,
        4,
        65,
        1,
        106,
        54,
        2,
        4,
        11,
        11,
        32,
        0,
        65,
        0,
        54,
        2,
        0,
        32,
        0,
        65,
        0,
        54,
        2,
        4,
        32,
        0,
        65,
        0,
        54,
        2,
        8,
        32,
        0,
        66,
        0,
        55,
        3,
        16,
        32,
        0,
        66,
        0,
        55,
        3,
        24,
        32,
        0,
        66,
        0,
        55,
        3,
        32,
        32,
        0,
        66,
        0,
        55,
        3,
        40,
        32,
        0,
        66,
        0,
        55,
        3,
        48,
        32,
        0,
        66,
        0,
        55,
        3,
        56,
        32,
        0,
        66,
        0,
        55,
        3,
        64,
        32,
        0,
        66,
        0,
        55,
        3,
        72,
        32,
        0,
        66,
        0,
        55,
        3,
        80,
        32,
        0,
        66,
        0,
        55,
        3,
        88,
        32,
        0,
        66,
        0,
        55,
        3,
        96,
        32,
        0,
        32,
        2,
        173,
        55,
        3,
        80,
        32,
        0,
        32,
        3,
        173,
        55,
        3,
        88,
        65,
        12,
        65,
        4,
        16,
        10,
        34,
        2,
        65,
        172,
        3,
        75,
        4,
        64,
        32,
        2,
        65,
        16,
        107,
        34,
        3,
        32,
        3,
        40,
        2,
        4,
        65,
        1,
        106,
        54,
        2,
        4,
        11,
        32,
        2,
        32,
        4,
        65,
        0,
        16,
        14,
        33,
        2,
        32,
        0,
        40,
        2,
        0,
        16,
        12,
        32,
        0,
        32,
        2,
        54,
        2,
        0,
        32,
        0,
        32,
        4,
        54,
        2,
        4,
        32,
        0,
        66,
        1,
        32,
        1,
        173,
        134,
        66,
        1,
        125,
        55,
        3,
        96,
        32,
        0,
        66,
        243,
        130,
        183,
        218,
        216,
        230,
        232,
        30,
        55,
        3,
        72,
        35,
        4,
        69,
        4,
        64,
        65,
        0,
        33,
        2,
        3,
        64,
        32,
        2,
        65,
        128,
        2,
        72,
        4,
        64,
        32,
        2,
        65,
        255,
        1,
        113,
        173,
        33,
        6,
        32,
        0,
        41,
        3,
        72,
        34,
        7,
        33,
        8,
        65,
        63,
        32,
        7,
        121,
        167,
        107,
        33,
        1,
        3,
        64,
        65,
        63,
        32,
        6,
        121,
        167,
        107,
        32,
        1,
        107,
        34,
        3,
        65,
        0,
        78,
        4,
        64,
        32,
        6,
        32,
        8,
        32,
        3,
        172,
        134,
        133,
        33,
        6,
        12,
        1,
        11,
        11,
        65,
        0,
        33,
        4,
        3,
        64,
        32,
        4,
        32,
        0,
        40,
        2,
        4,
        65,
        1,
        107,
        72,
        4,
        64,
        32,
        6,
        66,
        8,
        134,
        33,
        6,
        32,
        0,
        41,
        3,
        72,
        34,
        7,
        33,
        8,
        65,
        63,
        32,
        7,
        121,
        167,
        107,
        33,
        1,
        3,
        64,
        65,
        63,
        32,
        6,
        121,
        167,
        107,
        32,
        1,
        107,
        34,
        3,
        65,
        0,
        78,
        4,
        64,
        32,
        6,
        32,
        8,
        32,
        3,
        172,
        134,
        133,
        33,
        6,
        12,
        1,
        11,
        11,
        32,
        4,
        65,
        1,
        106,
        33,
        4,
        12,
        1,
        11,
        11,
        35,
        6,
        40,
        2,
        4,
        32,
        2,
        65,
        3,
        116,
        106,
        32,
        6,
        55,
        3,
        0,
        32,
        2,
        65,
        1,
        106,
        33,
        2,
        12,
        1,
        11,
        11,
        65,
        63,
        32,
        0,
        41,
        3,
        72,
        121,
        167,
        107,
        172,
        33,
        7,
        65,
        0,
        33,
        2,
        3,
        64,
        32,
        2,
        65,
        128,
        2,
        72,
        4,
        64,
        35,
        5,
        33,
        1,
        32,
        2,
        172,
        32,
        7,
        134,
        34,
        8,
        33,
        6,
        65,
        63,
        32,
        0,
        41,
        3,
        72,
        34,
        9,
        121,
        167,
        107,
        33,
        3,
        3,
        64,
        65,
        63,
        32,
        6,
        121,
        167,
        107,
        32,
        3,
        107,
        34,
        4,
        65,
        0,
        78,
        4,
        64,
        32,
        6,
        32,
        9,
        32,
        4,
        172,
        134,
        133,
        33,
        6,
        12,
        1,
        11,
        11,
        32,
        1,
        40,
        2,
        4,
        32,
        2,
        65,
        3,
        116,
        106,
        32,
        6,
        32,
        8,
        132,
        55,
        3,
        0,
        32,
        2,
        65,
        1,
        106,
        33,
        2,
        12,
        1,
        11,
        11,
        65,
        1,
        36,
        4,
        11,
        32,
        0,
        66,
        0,
        55,
        3,
        24,
        32,
        0,
        66,
        0,
        55,
        3,
        32,
        65,
        0,
        33,
        2,
        3,
        64,
        32,
        2,
        32,
        0,
        40,
        2,
        4,
        72,
        4,
        64,
        32,
        0,
        40,
        2,
        0,
        32,
        2,
        16,
        18,
        32,
        2,
        65,
        1,
        106,
        33,
        2,
        12,
        1,
        11,
        11,
        32,
        0,
        66,
        0,
        55,
        3,
        40,
        32,
        0,
        65,
        0,
        54,
        2,
        8,
        32,
        0,
        66,
        0,
        55,
        3,
        16,
        32,
        0,
        66,
        0,
        55,
        3,
        40,
        32,
        0,
        40,
        2,
        0,
        32,
        0,
        40,
        2,
        8,
        16,
        19,
        33,
        1,
        32,
        0,
        40,
        2,
        8,
        32,
        0,
        40,
        2,
        0,
        40,
        2,
        4,
        106,
        65,
        1,
        58,
        0,
        0,
        32,
        0,
        32,
        0,
        41,
        3,
        40,
        35,
        6,
        40,
        2,
        4,
        32,
        1,
        65,
        3,
        116,
        106,
        41,
        3,
        0,
        133,
        55,
        3,
        40,
        32,
        0,
        32,
        0,
        40,
        2,
        8,
        65,
        1,
        106,
        32,
        0,
        40,
        2,
        4,
        111,
        54,
        2,
        8,
        32,
        0,
        35,
        5,
        40,
        2,
        4,
        32,
        0,
        41,
        3,
        40,
        34,
        6,
        66,
        45,
        136,
        167,
        65,
        3,
        116,
        106,
        41,
        3,
        0,
        32,
        6,
        66,
        8,
        134,
        66,
        1,
        132,
        133,
        55,
        3,
        40,
        32,
        0,
        11,
        38,
        1,
        1,
        127,
        32,
        0,
        40,
        2,
        0,
        34,
        0,
        65,
        172,
        3,
        75,
        4,
        64,
        32,
        0,
        65,
        16,
        107,
        34,
        1,
        32,
        1,
        40,
        2,
        4,
        65,
        1,
        106,
        54,
        2,
        4,
        11,
        32,
        0,
        11,
        55,
        1,
        2,
        127,
        32,
        1,
        32,
        0,
        40,
        2,
        0,
        34,
        2,
        71,
        4,
        64,
        32,
        1,
        65,
        172,
        3,
        75,
        4,
        64,
        32,
        1,
        65,
        16,
        107,
        34,
        3,
        32,
        3,
        40,
        2,
        4,
        65,
        1,
        106,
        54,
        2,
        4,
        11,
        32,
        2,
        16,
        12,
        11,
        32,
        0,
        32,
        1,
        54,
        2,
        0,
        11,
        7,
        0,
        32,
        0,
        40,
        2,
        4,
        11,
        9,
        0,
        32,
        0,
        32,
        1,
        54,
        2,
        4,
        11,
        7,
        0,
        32,
        0,
        40,
        2,
        8,
        11,
        9,
        0,
        32,
        0,
        32,
        1,
        54,
        2,
        8,
        11,
        7,
        0,
        32,
        0,
        41,
        3,
        16,
        11,
        9,
        0,
        32,
        0,
        32,
        1,
        55,
        3,
        16,
        11,
        7,
        0,
        32,
        0,
        41,
        3,
        24,
        11,
        9,
        0,
        32,
        0,
        32,
        1,
        55,
        3,
        24,
        11,
        7,
        0,
        32,
        0,
        41,
        3,
        32,
        11,
        9,
        0,
        32,
        0,
        32,
        1,
        55,
        3,
        32,
        11,
        7,
        0,
        32,
        0,
        41,
        3,
        40,
        11,
        9,
        0,
        32,
        0,
        32,
        1,
        55,
        3,
        40,
        11,
        7,
        0,
        32,
        0,
        41,
        3,
        48,
        11,
        9,
        0,
        32,
        0,
        32,
        1,
        55,
        3,
        48,
        11,
        7,
        0,
        32,
        0,
        41,
        3,
        56,
        11,
        9,
        0,
        32,
        0,
        32,
        1,
        55,
        3,
        56,
        11,
        7,
        0,
        32,
        0,
        41,
        3,
        64,
        11,
        9,
        0,
        32,
        0,
        32,
        1,
        55,
        3,
        64,
        11,
        7,
        0,
        32,
        0,
        41,
        3,
        72,
        11,
        9,
        0,
        32,
        0,
        32,
        1,
        55,
        3,
        72,
        11,
        7,
        0,
        32,
        0,
        41,
        3,
        80,
        11,
        9,
        0,
        32,
        0,
        32,
        1,
        55,
        3,
        80,
        11,
        7,
        0,
        32,
        0,
        41,
        3,
        88,
        11,
        9,
        0,
        32,
        0,
        32,
        1,
        55,
        3,
        88,
        11,
        7,
        0,
        32,
        0,
        41,
        3,
        96,
        11,
        9,
        0,
        32,
        0,
        32,
        1,
        55,
        3,
        96,
        11,
        172,
        4,
        2,
        5,
        127,
        1,
        126,
        32,
        2,
        65,
        172,
        3,
        75,
        4,
        64,
        32,
        2,
        65,
        16,
        107,
        34,
        4,
        32,
        4,
        40,
        2,
        4,
        65,
        1,
        106,
        54,
        2,
        4,
        11,
        32,
        2,
        33,
        4,
        65,
        0,
        33,
        2,
        32,
        1,
        40,
        2,
        8,
        33,
        5,
        32,
        1,
        40,
        2,
        4,
        33,
        6,
        3,
        64,
        2,
        127,
        65,
        0,
        33,
        3,
        3,
        64,
        32,
        3,
        32,
        5,
        72,
        4,
        64,
        32,
        3,
        32,
        6,
        106,
        45,
        0,
        0,
        33,
        1,
        32,
        0,
        40,
        2,
        0,
        32,
        0,
        40,
        2,
        8,
        16,
        19,
        33,
        7,
        32,
        0,
        40,
        2,
        8,
        32,
        0,
        40,
        2,
        0,
        40,
        2,
        4,
        106,
        32,
        1,
        58,
        0,
        0,
        32,
        0,
        32,
        0,
        41,
        3,
        40,
        35,
        6,
        40,
        2,
        4,
        32,
        7,
        65,
        3,
        116,
        106,
        41,
        3,
        0,
        133,
        55,
        3,
        40,
        32,
        0,
        32,
        0,
        40,
        2,
        8,
        65,
        1,
        106,
        32,
        0,
        40,
        2,
        4,
        111,
        54,
        2,
        8,
        32,
        0,
        35,
        5,
        40,
        2,
        4,
        32,
        0,
        41,
        3,
        40,
        34,
        8,
        66,
        45,
        136,
        167,
        65,
        3,
        116,
        106,
        41,
        3,
        0,
        32,
        1,
        173,
        32,
        8,
        66,
        8,
        134,
        132,
        133,
        55,
        3,
        40,
        32,
        0,
        32,
        0,
        41,
        3,
        16,
        66,
        1,
        124,
        55,
        3,
        16,
        32,
        0,
        32,
        0,
        41,
        3,
        24,
        66,
        1,
        124,
        55,
        3,
        24,
        32,
        0,
        41,
        3,
        16,
        32,
        0,
        41,
        3,
        80,
        90,
        4,
        127,
        32,
        0,
        41,
        3,
        40,
        32,
        0,
        41,
        3,
        96,
        131,
        80,
        5,
        65,
        0,
        11,
        4,
        127,
        65,
        1,
        5,
        32,
        0,
        41,
        3,
        16,
        32,
        0,
        41,
        3,
        88,
        90,
        11,
        4,
        64,
        32,
        0,
        32,
        0,
        41,
        3,
        32,
        55,
        3,
        48,
        32,
        0,
        32,
        0,
        41,
        3,
        16,
        55,
        3,
        56,
        32,
        0,
        32,
        0,
        41,
        3,
        40,
        55,
        3,
        64,
        65,
        0,
        33,
        1,
        3,
        64,
        32,
        1,
        32,
        0,
        40,
        2,
        4,
        72,
        4,
        64,
        32,
        0,
        40,
        2,
        0,
        32,
        1,
        16,
        18,
        32,
        1,
        65,
        1,
        106,
        33,
        1,
        12,
        1,
        11,
        11,
        32,
        0,
        66,
        0,
        55,
        3,
        40,
        32,
        0,
        65,
        0,
        54,
        2,
        8,
        32,
        0,
        66,
        0,
        55,
        3,
        16,
        32,
        0,
        66,
        0,
        55,
        3,
        40,
        32,
        0,
        40,
        2,
        0,
        32,
        0,
        40,
        2,
        8,
        16,
        19,
        33,
        1,
        32,
        0,
        40,
        2,
        8,
        32,
        0,
        40,
        2,
        0,
        40,
        2,
        4,
        106,
        65,
        1,
        58,
        0,
        0,
        32,
        0,
        32,
        0,
        41,
        3,
        40,
        35,
        6,
        40,
        2,
        4,
        32,
        1,
        65,
        3,
        116,
        106,
        41,
        3,
        0,
        133,
        55,
        3,
        40,
        32,
        0,
        32,
        0,
        40,
        2,
        8,
        65,
        1,
        106,
        32,
        0,
        40,
        2,
        4,
        111,
        54,
        2,
        8,
        32,
        0,
        35,
        5,
        40,
        2,
        4,
        32,
        0,
        41,
        3,
        40,
        34,
        8,
        66,
        45,
        136,
        167,
        65,
        3,
        116,
        106,
        41,
        3,
        0,
        32,
        8,
        66,
        8,
        134,
        66,
        1,
        132,
        133,
        55,
        3,
        40,
        32,
        3,
        65,
        1,
        106,
        12,
        3,
        11,
        32,
        3,
        65,
        1,
        106,
        33,
        3,
        12,
        1,
        11,
        11,
        65,
        127,
        11,
        34,
        1,
        65,
        0,
        78,
        4,
        64,
        32,
        5,
        32,
        1,
        107,
        33,
        5,
        32,
        1,
        32,
        6,
        106,
        33,
        6,
        32,
        2,
        34,
        1,
        65,
        1,
        106,
        33,
        2,
        32,
        4,
        40,
        2,
        4,
        32,
        1,
        65,
        2,
        116,
        106,
        32,
        0,
        41,
        3,
        56,
        62,
        2,
        0,
        12,
        1,
        11,
        11,
        32,
        4,
        11,
        10,
        0,
        16,
        15,
        36,
        5,
        16,
        15,
        36,
        6,
        11,
        3,
        0,
        1,
        11,
        73,
        1,
        2,
        127,
        32,
        0,
        40,
        2,
        4,
        34,
        1,
        65,
        255,
        255,
        255,
        255,
        0,
        113,
        34,
        2,
        65,
        1,
        70,
        4,
        64,
        32,
        0,
        65,
        16,
        106,
        16,
        53,
        32,
        0,
        32,
        0,
        40,
        2,
        0,
        65,
        1,
        114,
        54,
        2,
        0,
        35,
        0,
        32,
        0,
        16,
        2,
        5,
        32,
        0,
        32,
        2,
        65,
        1,
        107,
        32,
        1,
        65,
        128,
        128,
        128,
        128,
        127,
        113,
        114,
        54,
        2,
        4,
        11,
        11,
        58,
        0,
        2,
        64,
        2,
        64,
        2,
        64,
        32,
        0,
        65,
        8,
        107,
        40,
        2,
        0,
        14,
        7,
        0,
        0,
        1,
        1,
        1,
        1,
        1,
        2,
        11,
        15,
        11,
        32,
        0,
        40,
        2,
        0,
        34,
        0,
        4,
        64,
        32,
        0,
        65,
        172,
        3,
        79,
        4,
        64,
        32,
        0,
        65,
        16,
        107,
        16,
        52,
        11,
        11,
        15,
        11,
        0,
        11,
        11,
        137,
        3,
        7,
        0,
        65,
        16,
        11,
        55,
        40,
        0,
        0,
        0,
        1,
        0,
        0,
        0,
        1,
        0,
        0,
        0,
        40,
        0,
        0,
        0,
        97,
        0,
        108,
        0,
        108,
        0,
        111,
        0,
        99,
        0,
        97,
        0,
        116,
        0,
        105,
        0,
        111,
        0,
        110,
        0,
        32,
        0,
        116,
        0,
        111,
        0,
        111,
        0,
        32,
        0,
        108,
        0,
        97,
        0,
        114,
        0,
        103,
        0,
        101,
        0,
        65,
        208,
        0,
        11,
        45,
        30,
        0,
        0,
        0,
        1,
        0,
        0,
        0,
        1,
        0,
        0,
        0,
        30,
        0,
        0,
        0,
        126,
        0,
        108,
        0,
        105,
        0,
        98,
        0,
        47,
        0,
        114,
        0,
        116,
        0,
        47,
        0,
        116,
        0,
        108,
        0,
        115,
        0,
        102,
        0,
        46,
        0,
        116,
        0,
        115,
        0,
        65,
        128,
        1,
        11,
        43,
        28,
        0,
        0,
        0,
        1,
        0,
        0,
        0,
        1,
        0,
        0,
        0,
        28,
        0,
        0,
        0,
        73,
        0,
        110,
        0,
        118,
        0,
        97,
        0,
        108,
        0,
        105,
        0,
        100,
        0,
        32,
        0,
        108,
        0,
        101,
        0,
        110,
        0,
        103,
        0,
        116,
        0,
        104,
        0,
        65,
        176,
        1,
        11,
        53,
        38,
        0,
        0,
        0,
        1,
        0,
        0,
        0,
        1,
        0,
        0,
        0,
        38,
        0,
        0,
        0,
        126,
        0,
        108,
        0,
        105,
        0,
        98,
        0,
        47,
        0,
        97,
        0,
        114,
        0,
        114,
        0,
        97,
        0,
        121,
        0,
        98,
        0,
        117,
        0,
        102,
        0,
        102,
        0,
        101,
        0,
        114,
        0,
        46,
        0,
        116,
        0,
        115,
        0,
        65,
        240,
        1,
        11,
        51,
        36,
        0,
        0,
        0,
        1,
        0,
        0,
        0,
        1,
        0,
        0,
        0,
        36,
        0,
        0,
        0,
        73,
        0,
        110,
        0,
        100,
        0,
        101,
        0,
        120,
        0,
        32,
        0,
        111,
        0,
        117,
        0,
        116,
        0,
        32,
        0,
        111,
        0,
        102,
        0,
        32,
        0,
        114,
        0,
        97,
        0,
        110,
        0,
        103,
        0,
        101,
        0,
        65,
        176,
        2,
        11,
        51,
        36,
        0,
        0,
        0,
        1,
        0,
        0,
        0,
        1,
        0,
        0,
        0,
        36,
        0,
        0,
        0,
        126,
        0,
        108,
        0,
        105,
        0,
        98,
        0,
        47,
        0,
        116,
        0,
        121,
        0,
        112,
        0,
        101,
        0,
        100,
        0,
        97,
        0,
        114,
        0,
        114,
        0,
        97,
        0,
        121,
        0,
        46,
        0,
        116,
        0,
        115,
        0,
        65,
        240,
        2,
        11,
        53,
        7,
        0,
        0,
        0,
        16,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        16,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        16,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        145,
        4,
        0,
        0,
        2,
        0,
        0,
        0,
        49,
        0,
        0,
        0,
        2,
        0,
        0,
        0,
        17,
        1,
        0,
        0,
        2,
        0,
        0,
        0,
        16,
        0,
        34,
        16,
        115,
        111,
        117,
        114,
        99,
        101,
        77,
        97,
        112,
        112,
        105,
        110,
        103,
        85,
        82,
        76,
        16,
        46,
        47,
        114,
        97,
        98,
        105,
        110,
        46,
        119,
        97,
        115,
        109,
        46,
        109,
        97,
        112
    ]);
    // make it work async because browsers throw when a wasm module is bigger than 4kb and load sync
    return instantiate(new Response(new Blob([
        wasm
    ], {
        type: 'application/wasm'
    })), imp);
}
module.exports = loadWebAssembly;

},{"@assemblyscript/loader":"G8OKt"}],"G8OKt":[function(require,module,exports) {
"use strict";
// Runtime header offsets
const ID_OFFSET = -8;
const SIZE_OFFSET = -4;
// Runtime ids
const ARRAYBUFFER_ID = 0;
const STRING_ID = 1;
const ARRAYBUFFERVIEW_ID = 2;
// Runtime type information
const ARRAYBUFFERVIEW = 1;
const ARRAY = 2;
const SET = 4;
const MAP = 8;
const VAL_ALIGN_OFFSET = 5;
const VAL_ALIGN = 1 << VAL_ALIGN_OFFSET;
const VAL_SIGNED = 1024;
const VAL_FLOAT = 2048;
const VAL_NULLABLE = 4096;
const VAL_MANAGED = 8192;
const KEY_ALIGN_OFFSET = 14;
const KEY_ALIGN = 1 << KEY_ALIGN_OFFSET;
const KEY_SIGNED = 524288;
const KEY_FLOAT = 1048576;
const KEY_NULLABLE = 2097152;
const KEY_MANAGED = 4194304;
// Array(BufferView) layout
const ARRAYBUFFERVIEW_BUFFER_OFFSET = 0;
const ARRAYBUFFERVIEW_DATASTART_OFFSET = 4;
const ARRAYBUFFERVIEW_DATALENGTH_OFFSET = 8;
const ARRAYBUFFERVIEW_SIZE = 12;
const ARRAY_LENGTH_OFFSET = 12;
const ARRAY_SIZE = 16;
const BIGINT = typeof BigUint64Array !== "undefined";
const THIS = Symbol();
const CHUNKSIZE = 1024;
/** Gets a string from an U32 and an U16 view on a memory. */ function getStringImpl(buffer, ptr) {
    const U32 = new Uint32Array(buffer);
    const U16 = new Uint16Array(buffer);
    var length = U32[ptr + SIZE_OFFSET >>> 2] >>> 1;
    var offset = ptr >>> 1;
    if (length <= CHUNKSIZE) return String.fromCharCode.apply(String, U16.subarray(offset, offset + length));
    const parts = [];
    do {
        const last = U16[offset + CHUNKSIZE - 1];
        const size = last >= 55296 && last < 56320 ? CHUNKSIZE - 1 : CHUNKSIZE;
        parts.push(String.fromCharCode.apply(String, U16.subarray(offset, offset += size)));
        length -= size;
    }while (length > CHUNKSIZE)
    return parts.join("") + String.fromCharCode.apply(String, U16.subarray(offset, offset + length));
}
/** Prepares the base module prior to instantiation. */ function preInstantiate(imports) {
    const baseModule = {
    };
    function getString(memory, ptr) {
        if (!memory) return "<yet unknown>";
        return getStringImpl(memory.buffer, ptr);
    }
    // add common imports used by stdlib for convenience
    const env = imports.env = imports.env || {
    };
    env.abort = env.abort || function abort(mesg, file, line, colm) {
        const memory = baseModule.memory || env.memory; // prefer exported, otherwise try imported
        throw Error("abort: " + getString(memory, mesg) + " at " + getString(memory, file) + ":" + line + ":" + colm);
    };
    env.trace = env.trace || function trace(mesg, n) {
        const memory = baseModule.memory || env.memory;
        console.log("trace: " + getString(memory, mesg) + (n ? " " : "") + Array.prototype.slice.call(arguments, 2, 2 + n).join(", "));
    };
    imports.Math = imports.Math || Math;
    imports.Date = imports.Date || Date;
    return baseModule;
}
/** Prepares the final module once instantiation is complete. */ function postInstantiate(baseModule, instance) {
    const rawExports = instance.exports;
    const memory = rawExports.memory;
    const table = rawExports.table;
    const alloc = rawExports["__alloc"];
    const retain = rawExports["__retain"];
    const rttiBase = rawExports["__rtti_base"] || -1; // oob if not present
    /** Gets the runtime type info for the given id. */ function getInfo(id) {
        const U32 = new Uint32Array(memory.buffer);
        const count = U32[rttiBase >>> 2];
        if ((id >>>= 0) >= count) throw Error("invalid id: " + id);
        return U32[(rttiBase + 4 >>> 2) + id * 2];
    }
    /** Gets the runtime base id for the given id. */ function getBase(id) {
        const U32 = new Uint32Array(memory.buffer);
        const count = U32[rttiBase >>> 2];
        if ((id >>>= 0) >= count) throw Error("invalid id: " + id);
        return U32[(rttiBase + 4 >>> 2) + id * 2 + 1];
    }
    /** Gets the runtime alignment of a collection's values. */ function getValueAlign(info) {
        return 31 - Math.clz32(info >>> VAL_ALIGN_OFFSET & 31); // -1 if none
    }
    /** Gets the runtime alignment of a collection's keys. */ function getKeyAlign(info) {
        return 31 - Math.clz32(info >>> KEY_ALIGN_OFFSET & 31); // -1 if none
    }
    /** Allocates a new string in the module's memory and returns its retained pointer. */ function __allocString(str) {
        const length = str.length;
        const ptr = alloc(length << 1, STRING_ID);
        const U16 = new Uint16Array(memory.buffer);
        for(var i = 0, p = ptr >>> 1; i < length; ++i)U16[p + i] = str.charCodeAt(i);
        return ptr;
    }
    baseModule.__allocString = __allocString;
    /** Reads a string from the module's memory by its pointer. */ function __getString(ptr) {
        const buffer = memory.buffer;
        const id = new Uint32Array(buffer)[ptr + ID_OFFSET >>> 2];
        if (id !== STRING_ID) throw Error("not a string: " + ptr);
        return getStringImpl(buffer, ptr);
    }
    baseModule.__getString = __getString;
    /** Gets the view matching the specified alignment, signedness and floatness. */ function getView(alignLog2, signed, float) {
        const buffer = memory.buffer;
        if (float) switch(alignLog2){
            case 2:
                return new Float32Array(buffer);
            case 3:
                return new Float64Array(buffer);
        }
        else switch(alignLog2){
            case 0:
                return new (signed ? Int8Array : Uint8Array)(buffer);
            case 1:
                return new (signed ? Int16Array : Uint16Array)(buffer);
            case 2:
                return new (signed ? Int32Array : Uint32Array)(buffer);
            case 3:
                return new (signed ? BigInt64Array : BigUint64Array)(buffer);
        }
        throw Error("unsupported align: " + alignLog2);
    }
    /** Allocates a new array in the module's memory and returns its retained pointer. */ function __allocArray(id, values) {
        const info = getInfo(id);
        if (!(info & (ARRAYBUFFERVIEW | ARRAY))) throw Error("not an array: " + id + " @ " + info);
        const align = getValueAlign(info);
        const length = values.length;
        const buf = alloc(length << align, ARRAYBUFFER_ID);
        const arr = alloc(info & ARRAY ? ARRAY_SIZE : ARRAYBUFFERVIEW_SIZE, id);
        const U32 = new Uint32Array(memory.buffer);
        U32[arr + ARRAYBUFFERVIEW_BUFFER_OFFSET >>> 2] = retain(buf);
        U32[arr + ARRAYBUFFERVIEW_DATASTART_OFFSET >>> 2] = buf;
        U32[arr + ARRAYBUFFERVIEW_DATALENGTH_OFFSET >>> 2] = length << align;
        if (info & ARRAY) U32[arr + ARRAY_LENGTH_OFFSET >>> 2] = length;
        const view = getView(align, info & VAL_SIGNED, info & VAL_FLOAT);
        if (info & VAL_MANAGED) for(let i = 0; i < length; ++i)view[(buf >>> align) + i] = retain(values[i]);
        else view.set(values, buf >>> align);
        return arr;
    }
    baseModule.__allocArray = __allocArray;
    /** Gets a live view on an array's values in the module's memory. Infers the array type from RTTI. */ function __getArrayView(arr) {
        const U32 = new Uint32Array(memory.buffer);
        const id = U32[arr + ID_OFFSET >>> 2];
        const info = getInfo(id);
        if (!(info & ARRAYBUFFERVIEW)) throw Error("not an array: " + id);
        const align = getValueAlign(info);
        var buf = U32[arr + ARRAYBUFFERVIEW_DATASTART_OFFSET >>> 2];
        const length = info & ARRAY ? U32[arr + ARRAY_LENGTH_OFFSET >>> 2] : U32[buf + SIZE_OFFSET >>> 2] >>> align;
        return getView(align, info & VAL_SIGNED, info & VAL_FLOAT).subarray(buf >>>= align, buf + length);
    }
    baseModule.__getArrayView = __getArrayView;
    /** Copies an array's values from the module's memory. Infers the array type from RTTI. */ function __getArray(arr) {
        const input = __getArrayView(arr);
        const len = input.length;
        const out = new Array(len);
        for(let i = 0; i < len; i++)out[i] = input[i];
        return out;
    }
    baseModule.__getArray = __getArray;
    /** Copies an ArrayBuffer's value from the module's memory. */ function __getArrayBuffer(ptr) {
        const buffer = memory.buffer;
        const length = new Uint32Array(buffer)[ptr + SIZE_OFFSET >>> 2];
        return buffer.slice(ptr, ptr + length);
    }
    baseModule.__getArrayBuffer = __getArrayBuffer;
    /** Copies a typed array's values from the module's memory. */ function getTypedArray(Type, alignLog2, ptr) {
        return new Type(getTypedArrayView(Type, alignLog2, ptr));
    }
    /** Gets a live view on a typed array's values in the module's memory. */ function getTypedArrayView(Type, alignLog2, ptr) {
        const buffer = memory.buffer;
        const U32 = new Uint32Array(buffer);
        const bufPtr = U32[ptr + ARRAYBUFFERVIEW_DATASTART_OFFSET >>> 2];
        return new Type(buffer, bufPtr, U32[bufPtr + SIZE_OFFSET >>> 2] >>> alignLog2);
    }
    baseModule.__getInt8Array = getTypedArray.bind(null, Int8Array, 0);
    baseModule.__getInt8ArrayView = getTypedArrayView.bind(null, Int8Array, 0);
    baseModule.__getUint8Array = getTypedArray.bind(null, Uint8Array, 0);
    baseModule.__getUint8ArrayView = getTypedArrayView.bind(null, Uint8Array, 0);
    baseModule.__getUint8ClampedArray = getTypedArray.bind(null, Uint8ClampedArray, 0);
    baseModule.__getUint8ClampedArrayView = getTypedArrayView.bind(null, Uint8ClampedArray, 0);
    baseModule.__getInt16Array = getTypedArray.bind(null, Int16Array, 1);
    baseModule.__getInt16ArrayView = getTypedArrayView.bind(null, Int16Array, 1);
    baseModule.__getUint16Array = getTypedArray.bind(null, Uint16Array, 1);
    baseModule.__getUint16ArrayView = getTypedArrayView.bind(null, Uint16Array, 1);
    baseModule.__getInt32Array = getTypedArray.bind(null, Int32Array, 2);
    baseModule.__getInt32ArrayView = getTypedArrayView.bind(null, Int32Array, 2);
    baseModule.__getUint32Array = getTypedArray.bind(null, Uint32Array, 2);
    baseModule.__getUint32ArrayView = getTypedArrayView.bind(null, Uint32Array, 2);
    if (BIGINT) {
        baseModule.__getInt64Array = getTypedArray.bind(null, BigInt64Array, 3);
        baseModule.__getInt64ArrayView = getTypedArrayView.bind(null, BigInt64Array, 3);
        baseModule.__getUint64Array = getTypedArray.bind(null, BigUint64Array, 3);
        baseModule.__getUint64ArrayView = getTypedArrayView.bind(null, BigUint64Array, 3);
    }
    baseModule.__getFloat32Array = getTypedArray.bind(null, Float32Array, 2);
    baseModule.__getFloat32ArrayView = getTypedArrayView.bind(null, Float32Array, 2);
    baseModule.__getFloat64Array = getTypedArray.bind(null, Float64Array, 3);
    baseModule.__getFloat64ArrayView = getTypedArrayView.bind(null, Float64Array, 3);
    /** Tests whether an object is an instance of the class represented by the specified base id. */ function __instanceof(ptr, baseId) {
        const U32 = new Uint32Array(memory.buffer);
        var id = U32[ptr + ID_OFFSET >>> 2];
        if (id <= U32[rttiBase >>> 2]) {
            do if (id == baseId) return true;
            while (id = getBase(id))
        }
        return false;
    }
    baseModule.__instanceof = __instanceof;
    // Pull basic exports to baseModule so code in preInstantiate can use them
    baseModule.memory = baseModule.memory || memory;
    baseModule.table = baseModule.table || table;
    // Demangle exports and provide the usual utility on the prototype
    return demangle(rawExports, baseModule);
}
function isResponse(o) {
    return typeof Response !== "undefined" && o instanceof Response;
}
/** Asynchronously instantiates an AssemblyScript module from anything that can be instantiated. */ async function instantiate(source, imports) {
    if (isResponse(source = await source)) return instantiateStreaming(source, imports);
    return postInstantiate(preInstantiate(imports || (imports = {
    })), await WebAssembly.instantiate(source instanceof WebAssembly.Module ? source : await WebAssembly.compile(source), imports));
}
exports.instantiate = instantiate;
/** Synchronously instantiates an AssemblyScript module from a WebAssembly.Module or binary buffer. */ function instantiateSync(source, imports) {
    return postInstantiate(preInstantiate(imports || (imports = {
    })), new WebAssembly.Instance(source instanceof WebAssembly.Module ? source : new WebAssembly.Module(source), imports));
}
exports.instantiateSync = instantiateSync;
/** Asynchronously instantiates an AssemblyScript module from a response, i.e. as obtained by `fetch`. */ async function instantiateStreaming(source, imports) {
    if (!WebAssembly.instantiateStreaming) return instantiate(isResponse(source = await source) ? source.arrayBuffer() : source, imports);
    return postInstantiate(preInstantiate(imports || (imports = {
    })), (await WebAssembly.instantiateStreaming(source, imports)).instance);
}
exports.instantiateStreaming = instantiateStreaming;
/** Demangles an AssemblyScript module's exports to a friendly object structure. */ function demangle(exports, baseModule) {
    var module = baseModule ? Object.create(baseModule) : {
    };
    var setArgumentsLength = exports["__argumentsLength"] ? function(length) {
        exports["__argumentsLength"].value = length;
    } : exports["__setArgumentsLength"] || exports["__setargc"] || function() {
    };
    for(let internalName in exports){
        if (!Object.prototype.hasOwnProperty.call(exports, internalName)) continue;
        const elem = exports[internalName];
        let parts = internalName.split(".");
        let curr = module;
        while(parts.length > 1){
            let part = parts.shift();
            if (!Object.prototype.hasOwnProperty.call(curr, part)) curr[part] = {
            };
            curr = curr[part];
        }
        let name1 = parts[0];
        let hash = name1.indexOf("#");
        if (hash >= 0) {
            let className = name1.substring(0, hash);
            let classElem = curr[className];
            if (typeof classElem === "undefined" || !classElem.prototype) {
                let ctor = function(...args) {
                    return ctor.wrap(ctor.prototype.constructor(0, ...args));
                };
                ctor.prototype = {
                    valueOf: function valueOf() {
                        return this[THIS];
                    }
                };
                ctor.wrap = function(thisValue) {
                    return Object.create(ctor.prototype, {
                        [THIS]: {
                            value: thisValue,
                            writable: false
                        }
                    });
                };
                if (classElem) Object.getOwnPropertyNames(classElem).forEach((name)=>Object.defineProperty(ctor, name, Object.getOwnPropertyDescriptor(classElem, name))
                );
                curr[className] = ctor;
            }
            name1 = name1.substring(hash + 1);
            curr = curr[className].prototype;
            if (/^(get|set):/.test(name1)) {
                if (!Object.prototype.hasOwnProperty.call(curr, name1 = name1.substring(4))) {
                    let getter = exports[internalName.replace("set:", "get:")];
                    let setter = exports[internalName.replace("get:", "set:")];
                    Object.defineProperty(curr, name1, {
                        get: function() {
                            return getter(this[THIS]);
                        },
                        set: function(value) {
                            setter(this[THIS], value);
                        },
                        enumerable: true
                    });
                }
            } else if (name1 === 'constructor') (curr[name1] = (...args)=>{
                setArgumentsLength(args.length);
                return elem(...args);
            }).original = elem;
            else (curr[name1] = function(...args) {
                setArgumentsLength(args.length);
                return elem(this[THIS], ...args);
            }).original = elem;
        } else {
            if (/^(get|set):/.test(name1)) {
                if (!Object.prototype.hasOwnProperty.call(curr, name1 = name1.substring(4))) Object.defineProperty(curr, name1, {
                    get: exports[internalName.replace("set:", "get:")],
                    set: exports[internalName.replace("get:", "set:")],
                    enumerable: true
                });
            } else if (typeof elem === "function" && elem !== setArgumentsLength) (curr[name1] = (...args)=>{
                setArgumentsLength(args.length);
                return elem(...args);
            }).original = elem;
            else curr[name1] = elem;
        }
    }
    return module;
}
exports.demangle = demangle;

},{}],"2cwnx":[function(require,module,exports) {
'use strict';
var BufferList = require('bl/BufferList.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var BufferList__default = /*#__PURE__*/ _interopDefaultLegacy(BufferList);
async function* fixedSizeChunker(source, options) {
    let bl = new BufferList__default['default']();
    let currentLength = 0;
    let emitted = false;
    const maxChunkSize = options.maxChunkSize;
    for await (const buffer of source){
        bl.append(buffer);
        currentLength += buffer.length;
        while(currentLength >= maxChunkSize){
            yield bl.slice(0, maxChunkSize);
            emitted = true;
            if (maxChunkSize === bl.length) {
                bl = new BufferList__default['default']();
                currentLength = 0;
            } else {
                const newBl = new BufferList__default['default']();
                newBl.append(bl.shallowSlice(maxChunkSize));
                bl = newBl;
                currentLength -= maxChunkSize;
            }
        }
    }
    if (!emitted || currentLength) yield bl.slice(0, currentLength);
}
module.exports = fixedSizeChunker;

},{"bl/BufferList.js":"cK5XN"}],"eOfW1":[function(require,module,exports) {
'use strict';
var errCode = require('err-code');
var fromString = require('uint8arrays/from-string');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
async function* validateChunks(source) {
    for await (const content of source){
        if (content.length === undefined) throw errCode__default['default'](new Error('Content was invalid'), 'ERR_INVALID_CONTENT');
        if (typeof content === 'string' || content instanceof String) yield fromString.fromString(content.toString());
        else if (Array.isArray(content)) yield Uint8Array.from(content);
        else if (content instanceof Uint8Array) yield content;
        else throw errCode__default['default'](new Error('Content was invalid'), 'ERR_INVALID_CONTENT');
    }
}
module.exports = validateChunks;

},{"err-code":"eQvyh","uint8arrays/from-string":"lo45E"}],"hIgvs":[function(require,module,exports) {
'use strict';
var dirFlat = require('./dir-flat.js');
var flatToShard = require('./flat-to-shard.js');
var dir = require('./dir.js');
var toPathComponents = require('./utils/to-path-components.js');
async function addToTree(elem, tree, options) {
    const pathElems = toPathComponents(elem.path || '');
    const lastIndex = pathElems.length - 1;
    let parent = tree;
    let currentPath = '';
    for(let i = 0; i < pathElems.length; i++){
        const pathElem = pathElems[i];
        currentPath += `${currentPath ? '/' : ''}${pathElem}`;
        const last = i === lastIndex;
        parent.dirty = true;
        parent.cid = undefined;
        parent.size = undefined;
        if (last) {
            await parent.put(pathElem, elem);
            tree = await flatToShard(null, parent, options.shardSplitThreshold, options);
        } else {
            let dir$1 = await parent.get(pathElem);
            if (!dir$1 || !(dir$1 instanceof dir)) dir$1 = new dirFlat({
                root: false,
                dir: true,
                parent: parent,
                parentKey: pathElem,
                path: currentPath,
                dirty: true,
                flat: true,
                mtime: dir$1 && dir$1.unixfs && dir$1.unixfs.mtime,
                mode: dir$1 && dir$1.unixfs && dir$1.unixfs.mode
            }, options);
            await parent.put(pathElem, dir$1);
            parent = dir$1;
        }
    }
    return tree;
}
async function* flushAndYield(tree, blockstore) {
    if (!(tree instanceof dir)) {
        if (tree && tree.unixfs && tree.unixfs.isDirectory()) yield tree;
        return;
    }
    yield* tree.flush(blockstore);
}
async function* treeBuilder(source, block, options) {
    let tree = new dirFlat({
        root: true,
        dir: true,
        path: '',
        dirty: true,
        flat: true
    }, options);
    for await (const entry of source){
        if (!entry) continue;
        tree = await addToTree(entry, tree, options);
        if (!entry.unixfs || !entry.unixfs.isDirectory()) yield entry;
    }
    if (options.wrapWithDirectory) yield* flushAndYield(tree, block);
    else for await (const unwrapped of tree.eachChildSeries()){
        if (!unwrapped) continue;
        yield* flushAndYield(unwrapped.child, block);
    }
}
module.exports = treeBuilder;

},{"./dir-flat.js":"7nFBZ","./flat-to-shard.js":"bYfCB","./dir.js":"bnM6B","./utils/to-path-components.js":"2Qhil"}],"7nFBZ":[function(require,module,exports) {
'use strict';
var dagPb = require('@ipld/dag-pb');
var ipfsUnixfs = require('ipfs-unixfs');
var dir = require('./dir.js');
var persist = require('./utils/persist.js');
class DirFlat extends dir {
    constructor(props, options){
        super(props, options);
        this._children = {
        };
    }
    async put(name, value) {
        this.cid = undefined;
        this.size = undefined;
        this._children[name] = value;
    }
    get(name1) {
        return Promise.resolve(this._children[name1]);
    }
    childCount() {
        return Object.keys(this._children).length;
    }
    directChildrenCount() {
        return this.childCount();
    }
    onlyChild() {
        return this._children[Object.keys(this._children)[0]];
    }
    async *eachChildSeries() {
        const keys = Object.keys(this._children);
        for(let i = 0; i < keys.length; i++){
            const key = keys[i];
            yield {
                key: key,
                child: this._children[key]
            };
        }
    }
    async *flush(block) {
        const children = Object.keys(this._children);
        const links = [];
        for(let i = 0; i < children.length; i++){
            let child = this._children[children[i]];
            if (child instanceof dir) for await (const entry of child.flush(block)){
                child = entry;
                yield child;
            }
            if (child.size != null && child.cid) links.push({
                Name: children[i],
                Tsize: child.size,
                Hash: child.cid
            });
        }
        const unixfs = new ipfsUnixfs.UnixFS({
            type: 'directory',
            mtime: this.mtime,
            mode: this.mode
        });
        const node = {
            Data: unixfs.marshal(),
            Links: links
        };
        const buffer = dagPb.encode(dagPb.prepare(node));
        const cid = await persist(buffer, block, this.options);
        const size = buffer.length + node.Links.reduce((acc, curr)=>acc + (curr.Tsize == null ? 0 : curr.Tsize)
        , 0);
        this.cid = cid;
        this.size = size;
        yield {
            cid,
            unixfs,
            path: this.path,
            size
        };
    }
}
module.exports = DirFlat;

},{"@ipld/dag-pb":"e9gy2","ipfs-unixfs":"fttXc","./dir.js":"bnM6B","./utils/persist.js":"fagNy"}],"bnM6B":[function(require,module,exports) {
'use strict';
class Dir {
    constructor(props, options){
        this.options = options || {
        };
        this.root = props.root;
        this.dir = props.dir;
        this.path = props.path;
        this.dirty = props.dirty;
        this.flat = props.flat;
        this.parent = props.parent;
        this.parentKey = props.parentKey;
        this.unixfs = props.unixfs;
        this.mode = props.mode;
        this.mtime = props.mtime;
        this.cid = undefined;
        this.size = undefined;
    }
    async put(name, value) {
    }
    get(name1) {
        return Promise.resolve(this);
    }
    async *eachChildSeries() {
    }
    async *flush(blockstore) {
    }
}
module.exports = Dir;

},{}],"bYfCB":[function(require,module,exports) {
'use strict';
var dirSharded = require('./dir-sharded.js');
var dirFlat = require('./dir-flat.js');
async function flatToShard(child, dir, threshold, options) {
    let newDir = dir;
    if (dir instanceof dirFlat && dir.directChildrenCount() >= threshold) newDir = await convertToShard(dir, options);
    const parent = newDir.parent;
    if (parent) {
        if (newDir !== dir) {
            if (child) child.parent = newDir;
            if (!newDir.parentKey) throw new Error('No parent key found');
            await parent.put(newDir.parentKey, newDir);
        }
        return flatToShard(newDir, parent, threshold, options);
    }
    return newDir;
}
async function convertToShard(oldDir, options) {
    const newDir = new dirSharded({
        root: oldDir.root,
        dir: true,
        parent: oldDir.parent,
        parentKey: oldDir.parentKey,
        path: oldDir.path,
        dirty: oldDir.dirty,
        flat: false,
        mtime: oldDir.mtime,
        mode: oldDir.mode
    }, options);
    for await (const { key , child  } of oldDir.eachChildSeries())await newDir.put(key, child);
    return newDir;
}
module.exports = flatToShard;

},{"./dir-sharded.js":"bK5iG","./dir-flat.js":"7nFBZ"}],"bK5iG":[function(require,module,exports) {
'use strict';
var dagPb = require('@ipld/dag-pb');
var ipfsUnixfs = require('ipfs-unixfs');
var dir1 = require('./dir.js');
var persist = require('./utils/persist.js');
var hamtSharding = require('hamt-sharding');
class DirSharded extends dir1 {
    constructor(props, options1){
        super(props, options1);
        this._bucket = hamtSharding.createHAMT({
            hashFn: options1.hamtHashFn,
            bits: options1.hamtBucketBits
        });
    }
    async put(name, value1) {
        await this._bucket.put(name, value1);
    }
    get(name1) {
        return this._bucket.get(name1);
    }
    childCount() {
        return this._bucket.leafCount();
    }
    directChildrenCount() {
        return this._bucket.childrenCount();
    }
    onlyChild() {
        return this._bucket.onlyChild();
    }
    async *eachChildSeries() {
        for await (const { key , value  } of this._bucket.eachLeafSeries())yield {
            key,
            child: value
        };
    }
    async *flush(blockstore1) {
        for await (const entry of flush(this._bucket, blockstore1, this, this.options))yield {
            ...entry,
            path: this.path
        };
    }
}
async function* flush(bucket, blockstore, shardRoot, options) {
    const children = bucket._children;
    const links = [];
    let childrenSize = 0;
    for(let i = 0; i < children.length; i++){
        const child = children.get(i);
        if (!child) continue;
        const labelPrefix = i.toString(16).toUpperCase().padStart(2, '0');
        if (child instanceof hamtSharding.Bucket) {
            let shard;
            for await (const subShard of (await flush(child, blockstore, null, options)))shard = subShard;
            if (!shard) throw new Error('Could not flush sharded directory, no subshard found');
            links.push({
                Name: labelPrefix,
                Tsize: shard.size,
                Hash: shard.cid
            });
            childrenSize += shard.size;
        } else if (typeof child.value.flush === 'function') {
            const dir = child.value;
            let flushedDir;
            for await (const entry of dir.flush(blockstore)){
                flushedDir = entry;
                yield flushedDir;
            }
            const label = labelPrefix + child.key;
            links.push({
                Name: label,
                Tsize: flushedDir.size,
                Hash: flushedDir.cid
            });
            childrenSize += flushedDir.size;
        } else {
            const value = child.value;
            if (!value.cid) continue;
            const label = labelPrefix + child.key;
            const size = value.size;
            links.push({
                Name: label,
                Tsize: size,
                Hash: value.cid
            });
            childrenSize += size;
        }
    }
    const data = Uint8Array.from(children.bitField().reverse());
    const dir = new ipfsUnixfs.UnixFS({
        type: 'hamt-sharded-directory',
        data,
        fanout: bucket.tableSize(),
        hashType: options.hamtHashCode,
        mtime: shardRoot && shardRoot.mtime,
        mode: shardRoot && shardRoot.mode
    });
    const node = {
        Data: dir.marshal(),
        Links: links
    };
    const buffer = dagPb.encode(dagPb.prepare(node));
    const cid = await persist(buffer, blockstore, options);
    const size = buffer.length + childrenSize;
    yield {
        cid,
        unixfs: dir,
        size
    };
}
module.exports = DirSharded;

},{"@ipld/dag-pb":"e9gy2","ipfs-unixfs":"fttXc","./dir.js":"bnM6B","./utils/persist.js":"fagNy","hamt-sharding":"4VZAD"}],"4VZAD":[function(require,module,exports) {
'use strict';
const Bucket = require('./bucket');
const wrapHash = require('./consumable-hash');
/**
 * @typedef {object} UserBucketOptions
 * @property {(value: Uint8Array) => Promise<Uint8Array>} hashFn
 * @property {number} [bits=8]
 */ /**
 * @param {UserBucketOptions} options
 */ function createHAMT(options) {
    if (!options || !options.hashFn) throw new Error('please define an options.hashFn');
    const bucketOptions = {
        bits: options.bits || 8,
        hash: wrapHash(options.hashFn)
    };
    return new Bucket(bucketOptions);
}
module.exports = {
    createHAMT,
    Bucket
};

},{"./bucket":"jsL8t","./consumable-hash":"1DZ91"}],"jsL8t":[function(require,module,exports) {
'use strict';
// @ts-ignore
const SparseArray = require('sparse-array');
const { fromString: uint8ArrayFromString  } = require('uint8arrays/from-string');
/**
 * @typedef {import('./consumable-hash').InfiniteHash} InfiniteHash
 * @typedef {import('../').UserBucketOptions} UserBucketOptions
 */ /**
 * @template V
 * @typedef {object} BucketChild<V>
 * @property {string} key
 * @property {V} value
 * @property {InfiniteHash} hash
 */ /**
 * @template B
 *
 * @typedef {object} SA<B>
 * @property {number} length
 * @property {() => B[]} compactArray
 * @property {(i: number) => B} get
 * @property {(i: number, value: B) => void} set
 * @property {<A> (fn: (acc: A, curr: B, index: number) => A, initial: A) => B} reduce
 * @property {(fn: (item: B) => boolean) => B | undefined} find
 * @property {() => number[]} bitField
 * @property {(i: number) => void} unset
 */ /**
 * @template T
 *
 * @typedef {object} BucketPosition<T>
 * @property {Bucket<T>} bucket
 * @property {number} pos
 * @property {InfiniteHash} hash
 * @property {BucketChild<T>} [existingChild]
 */ /**
 * @typedef {object} BucketOptions
 * @property {number} bits
 * @property {(value: Uint8Array | InfiniteHash) => InfiniteHash} hash
 */ /**
 * @template T
 */ class Bucket {
    /**
   * @param {BucketOptions} options
   * @param {Bucket<T>} [parent]
   * @param {number} [posAtParent=0]
   */ constructor(options, parent, posAtParent = 0){
        this._options = options;
        this._popCount = 0;
        this._parent = parent;
        this._posAtParent = posAtParent;
        /** @type {SA<Bucket<T> | BucketChild<T>>} */ this._children = new SparseArray();
        /** @type {string | null} */ this.key = null;
    }
    /**
   * @param {string} key
   * @param {T} value
   */ async put(key, value) {
        const place = await this._findNewBucketAndPos(key);
        await place.bucket._putAt(place, key, value);
    }
    /**
   * @param {string} key
   */ async get(key1) {
        const child = await this._findChild(key1);
        if (child) return child.value;
    }
    /**
   * @param {string} key
   */ async del(key2) {
        const place = await this._findPlace(key2);
        const child = place.bucket._at(place.pos);
        if (child && child.key === key2) place.bucket._delAt(place.pos);
    }
    /**
   * @returns {number}
   */ leafCount() {
        const children = this._children.compactArray();
        return children.reduce((acc, child)=>{
            if (child instanceof Bucket) return acc + child.leafCount();
            return acc + 1;
        }, 0);
    }
    childrenCount() {
        return this._children.length;
    }
    onlyChild() {
        return this._children.get(0);
    }
    /**
   * @returns {Iterable<BucketChild<T>>}
   */ *eachLeafSeries() {
        const children = this._children.compactArray();
        for (const child of children)if (child instanceof Bucket) yield* child.eachLeafSeries();
        else yield child;
        // this is necessary because tsc requires a @return annotation as it
        // can't derive a return type due to the recursion, and eslint requires
        // a return statement when there is a @return annotation
        return [];
    }
    /**
   * @param {(value: BucketChild<T>, index: number) => T} map
   * @param {(reduced: any) => any} reduce
   */ serialize(map, reduce) {
        /** @type {T[]} */ const acc1 = [];
        // serialize to a custom non-sparse representation
        return reduce(this._children.reduce((acc, child, index)=>{
            if (child) {
                if (child instanceof Bucket) acc.push(child.serialize(map, reduce));
                else acc.push(map(child, index));
            }
            return acc;
        }, acc1));
    }
    /**
   * @param {(value: BucketChild<T>) => Promise<T[]>} asyncMap
   * @param {(reduced: any) => Promise<any>} asyncReduce
   */ asyncTransform(asyncMap1, asyncReduce1) {
        return asyncTransformBucket(this, asyncMap1, asyncReduce1);
    }
    toJSON() {
        return this.serialize(mapNode, reduceNodes);
    }
    prettyPrint() {
        return JSON.stringify(this.toJSON(), null, '  ');
    }
    tableSize() {
        return Math.pow(2, this._options.bits);
    }
    /**
   * @param {string} key
   * @returns {Promise<BucketChild<T> | undefined>}
   */ async _findChild(key3) {
        const result = await this._findPlace(key3);
        const child = result.bucket._at(result.pos);
        if (child instanceof Bucket) // should not be possible, this._findPlace should always
        // return a location for a child, not a bucket
        return undefined;
        if (child && child.key === key3) return child;
    }
    /**
   * @param {string | InfiniteHash} key
   * @returns {Promise<BucketPosition<T>>}
   */ async _findPlace(key4) {
        const hashValue = this._options.hash(typeof key4 === 'string' ? uint8ArrayFromString(key4) : key4);
        const index = await hashValue.take(this._options.bits);
        const child = this._children.get(index);
        if (child instanceof Bucket) return child._findPlace(hashValue);
        return {
            bucket: this,
            pos: index,
            hash: hashValue,
            existingChild: child
        };
    }
    /**
   * @param {string | InfiniteHash} key
   * @returns {Promise<BucketPosition<T>>}
   */ async _findNewBucketAndPos(key5) {
        const place = await this._findPlace(key5);
        if (place.existingChild && place.existingChild.key !== key5) {
            // conflict
            const bucket = new Bucket(this._options, place.bucket, place.pos);
            place.bucket._putObjectAt(place.pos, bucket);
            // put the previous value
            const newPlace = await bucket._findPlace(place.existingChild.hash);
            newPlace.bucket._putAt(newPlace, place.existingChild.key, place.existingChild.value);
            return bucket._findNewBucketAndPos(place.hash);
        }
        // no conflict, we found the place
        return place;
    }
    /**
   * @param {BucketPosition<T>} place
   * @param {string} key
   * @param {T} value
   */ _putAt(place, key6, value1) {
        this._putObjectAt(place.pos, {
            key: key6,
            value: value1,
            hash: place.hash
        });
    }
    /**
   * @param {number} pos
   * @param {Bucket<T> | BucketChild<T>} object
   */ _putObjectAt(pos, object) {
        if (!this._children.get(pos)) this._popCount++;
        this._children.set(pos, object);
    }
    /**
   * @param {number} pos
   */ _delAt(pos1) {
        if (pos1 === -1) throw new Error('Invalid position');
        if (this._children.get(pos1)) this._popCount--;
        this._children.unset(pos1);
        this._level();
    }
    _level() {
        if (this._parent && this._popCount <= 1) {
            if (this._popCount === 1) {
                // remove myself from parent, replacing me with my only child
                const onlyChild = this._children.find(exists);
                if (onlyChild && !(onlyChild instanceof Bucket)) {
                    const hash = onlyChild.hash;
                    hash.untake(this._options.bits);
                    const place = {
                        pos: this._posAtParent,
                        hash: hash,
                        bucket: this._parent
                    };
                    this._parent._putAt(place, onlyChild.key, onlyChild.value);
                }
            } else this._parent._delAt(this._posAtParent);
        }
    }
    /**
   * @param {number} index
   * @returns {BucketChild<T> | Bucket<T> | undefined}
   */ _at(index) {
        return this._children.get(index);
    }
}
/**
 * @param {any} o
 */ function exists(o) {
    return Boolean(o);
}
/**
 *
 * @param {*} node
 * @param {number} index
 */ function mapNode(node, index) {
    return node.key;
}
/**
 * @param {*} nodes
 */ function reduceNodes(nodes) {
    return nodes;
}
/**
 * @template T
 *
 * @param {Bucket<T>} bucket
 * @param {(value: BucketChild<T>) => Promise<T[]>} asyncMap
 * @param {(reduced: any) => Promise<any>} asyncReduce
 */ async function asyncTransformBucket(bucket, asyncMap, asyncReduce) {
    const output = [];
    for (const child of bucket._children.compactArray())if (child instanceof Bucket) await asyncTransformBucket(child, asyncMap, asyncReduce);
    else {
        const mappedChildren = await asyncMap(child);
        output.push({
            bitField: bucket._children.bitField(),
            children: mappedChildren
        });
    }
    return asyncReduce(output);
}
module.exports = Bucket;

},{"sparse-array":"eR6J4","uint8arrays/from-string":"lo45E"}],"eR6J4":[function(require,module,exports) {
'use strict';
// JS treats subjects of bitwise operators as SIGNED 32 bit numbers,
// which means the maximum amount of bits we can store inside each byte
// is 7..
const BITS_PER_BYTE = 7;
module.exports = class SparseArray {
    constructor(){
        this._bitArrays = [];
        this._data = [];
        this._length = 0;
        this._changedLength = false;
        this._changedData = false;
    }
    set(index, value) {
        let pos = this._internalPositionFor(index, false);
        if (value === undefined) // unsetting
        {
            if (pos !== -1) {
                // remove item from bit array and array itself
                this._unsetInternalPos(pos);
                this._unsetBit(index);
                this._changedLength = true;
                this._changedData = true;
            }
        } else {
            let needsSort = false;
            if (pos === -1) {
                pos = this._data.length;
                this._setBit(index);
                this._changedData = true;
            } else needsSort = true;
            this._setInternalPos(pos, index, value, needsSort);
            this._changedLength = true;
        }
    }
    unset(index1) {
        this.set(index1, undefined);
    }
    get(index2) {
        this._sortData();
        const pos = this._internalPositionFor(index2, true);
        if (pos === -1) return undefined;
        return this._data[pos][1];
    }
    push(value1) {
        this.set(this.length, value1);
        return this.length;
    }
    get length() {
        this._sortData();
        if (this._changedLength) {
            const last = this._data[this._data.length - 1];
            this._length = last ? last[0] + 1 : 0;
            this._changedLength = false;
        }
        return this._length;
    }
    forEach(iterator) {
        let i = 0;
        while(i < this.length){
            iterator(this.get(i), i, this);
            i++;
        }
    }
    map(iterator1) {
        let i = 0;
        let mapped = new Array(this.length);
        while(i < this.length){
            mapped[i] = iterator1(this.get(i), i, this);
            i++;
        }
        return mapped;
    }
    reduce(reducer, initialValue) {
        let i = 0;
        let acc = initialValue;
        while(i < this.length){
            const value = this.get(i);
            acc = reducer(acc, value, i);
            i++;
        }
        return acc;
    }
    find(finder) {
        let i = 0, found, last;
        while(i < this.length && !found){
            last = this.get(i);
            found = finder(last);
            i++;
        }
        return found ? last : undefined;
    }
    _internalPositionFor(index3, noCreate) {
        const bytePos = this._bytePosFor(index3, noCreate);
        if (bytePos >= this._bitArrays.length) return -1;
        const byte = this._bitArrays[bytePos];
        const bitPos = index3 - bytePos * BITS_PER_BYTE;
        const exists = (byte & 1 << bitPos) > 0;
        if (!exists) return -1;
        const previousPopCount = this._bitArrays.slice(0, bytePos).reduce(popCountReduce, 0);
        const mask = ~(4294967295 << bitPos + 1);
        const bytePopCount = popCount(byte & mask);
        const arrayPos = previousPopCount + bytePopCount - 1;
        return arrayPos;
    }
    _bytePosFor(index4, noCreate1) {
        const bytePos = Math.floor(index4 / BITS_PER_BYTE);
        const targetLength = bytePos + 1;
        while(!noCreate1 && this._bitArrays.length < targetLength)this._bitArrays.push(0);
        return bytePos;
    }
    _setBit(index5) {
        const bytePos = this._bytePosFor(index5, false);
        this._bitArrays[bytePos] |= 1 << index5 - bytePos * BITS_PER_BYTE;
    }
    _unsetBit(index6) {
        const bytePos = this._bytePosFor(index6, false);
        this._bitArrays[bytePos] &= ~(1 << index6 - bytePos * BITS_PER_BYTE);
    }
    _setInternalPos(pos, index7, value2, needsSort) {
        const data = this._data;
        const elem = [
            index7,
            value2
        ];
        if (needsSort) {
            this._sortData();
            data[pos] = elem;
        } else {
            // new element. just shove it into the array
            // but be nice about where we shove it
            // in order to make sorting it later easier
            if (data.length) {
                if (data[data.length - 1][0] >= index7) data.push(elem);
                else if (data[0][0] <= index7) data.unshift(elem);
                else {
                    const randomIndex = Math.round(data.length / 2);
                    this._data = data.slice(0, randomIndex).concat(elem).concat(data.slice(randomIndex));
                }
            } else this._data.push(elem);
            this._changedData = true;
            this._changedLength = true;
        }
    }
    _unsetInternalPos(pos1) {
        this._data.splice(pos1, 1);
    }
    _sortData() {
        if (this._changedData) this._data.sort(sortInternal);
        this._changedData = false;
    }
    bitField() {
        const bytes = [];
        let pendingBitsForResultingByte = 8;
        let pendingBitsForNewByte = 0;
        let resultingByte = 0;
        let newByte;
        const pending = this._bitArrays.slice();
        while(pending.length || pendingBitsForNewByte){
            if (pendingBitsForNewByte === 0) {
                newByte = pending.shift();
                pendingBitsForNewByte = 7;
            }
            const usingBits = Math.min(pendingBitsForNewByte, pendingBitsForResultingByte);
            const mask = ~(255 << usingBits);
            const masked = newByte & mask;
            resultingByte |= masked << 8 - pendingBitsForResultingByte;
            newByte = newByte >>> usingBits;
            pendingBitsForNewByte -= usingBits;
            pendingBitsForResultingByte -= usingBits;
            if (!pendingBitsForResultingByte || !pendingBitsForNewByte && !pending.length) {
                bytes.push(resultingByte);
                resultingByte = 0;
                pendingBitsForResultingByte = 8;
            }
        }
        // remove trailing zeroes
        for(var i = bytes.length - 1; i > 0; i--){
            const value = bytes[i];
            if (value === 0) bytes.pop();
            else break;
        }
        return bytes;
    }
    compactArray() {
        this._sortData();
        return this._data.map(valueOnly);
    }
};
function popCountReduce(count, byte) {
    return count + popCount(byte);
}
function popCount(_v) {
    let v = _v;
    v = v - (v >> 1 & 1431655765) // reuse input as temporary
    ;
    v = (v & 858993459) + (v >> 2 & 858993459) // temp
    ;
    return (v + (v >> 4) & 252645135) * 16843009 >> 24;
}
function sortInternal(a, b) {
    return a[0] - b[0];
}
function valueOnly(elem) {
    return elem[1];
}

},{}],"1DZ91":[function(require,module,exports) {
'use strict';
const ConsumableBuffer = require('./consumable-buffer');
const { concat: uint8ArrayConcat  } = require('uint8arrays/concat');
/**
 * @param {(value: Uint8Array) => Promise<Uint8Array>} hashFn
 */ function wrapHash(hashFn) {
    /**
   * @param {InfiniteHash | Uint8Array} value
   */ function hashing(value) {
        if (value instanceof InfiniteHash) // already a hash. return it
        return value;
        else return new InfiniteHash(value, hashFn);
    }
    return hashing;
}
class InfiniteHash {
    /**
   *
   * @param {Uint8Array} value
   * @param {(value: Uint8Array) => Promise<Uint8Array>} hashFn
   */ constructor(value, hashFn){
        if (!(value instanceof Uint8Array)) throw new Error('can only hash Uint8Arrays');
        this._value = value;
        this._hashFn = hashFn;
        this._depth = -1;
        this._availableBits = 0;
        this._currentBufferIndex = 0;
        /** @type {ConsumableBuffer[]} */ this._buffers = [];
    }
    /**
   * @param {number} bits
   */ async take(bits) {
        let pendingBits = bits;
        while(this._availableBits < pendingBits)await this._produceMoreBits();
        let result = 0;
        while(pendingBits > 0){
            const hash = this._buffers[this._currentBufferIndex];
            const available = Math.min(hash.availableBits(), pendingBits);
            const took = hash.take(available);
            result = (result << available) + took;
            pendingBits -= available;
            this._availableBits -= available;
            if (hash.availableBits() === 0) this._currentBufferIndex++;
        }
        return result;
    }
    /**
   * @param {number} bits
   */ untake(bits1) {
        let pendingBits = bits1;
        while(pendingBits > 0){
            const hash = this._buffers[this._currentBufferIndex];
            const availableForUntake = Math.min(hash.totalBits() - hash.availableBits(), pendingBits);
            hash.untake(availableForUntake);
            pendingBits -= availableForUntake;
            this._availableBits += availableForUntake;
            if (this._currentBufferIndex > 0 && hash.totalBits() === hash.availableBits()) {
                this._depth--;
                this._currentBufferIndex--;
            }
        }
    }
    async _produceMoreBits() {
        this._depth++;
        const value = this._depth ? uint8ArrayConcat([
            this._value,
            Uint8Array.from([
                this._depth
            ])
        ]) : this._value;
        const hashValue = await this._hashFn(value);
        const buffer = new ConsumableBuffer(hashValue);
        this._buffers.push(buffer);
        this._availableBits += buffer.availableBits();
    }
}
module.exports = wrapHash;
module.exports.InfiniteHash = InfiniteHash;

},{"./consumable-buffer":"hPNI7","uint8arrays/concat":"fLIrL"}],"hPNI7":[function(require,module,exports) {
'use strict';
const START_MASKS = [
    255,
    254,
    252,
    248,
    240,
    224,
    192,
    128
];
const STOP_MASKS = [
    1,
    3,
    7,
    15,
    31,
    63,
    127,
    255
];
module.exports = class ConsumableBuffer {
    /**
   * @param {Uint8Array} value
   */ constructor(value){
        this._value = value;
        this._currentBytePos = value.length - 1;
        this._currentBitPos = 7;
    }
    availableBits() {
        return this._currentBitPos + 1 + this._currentBytePos * 8;
    }
    totalBits() {
        return this._value.length * 8;
    }
    /**
   * @param {number} bits
   */ take(bits) {
        let pendingBits = bits;
        let result = 0;
        while(pendingBits && this._haveBits()){
            const byte = this._value[this._currentBytePos];
            const availableBits = this._currentBitPos + 1;
            const taking = Math.min(availableBits, pendingBits);
            const value = byteBitsToInt(byte, availableBits - taking, taking);
            result = (result << taking) + value;
            pendingBits -= taking;
            this._currentBitPos -= taking;
            if (this._currentBitPos < 0) {
                this._currentBitPos = 7;
                this._currentBytePos--;
            }
        }
        return result;
    }
    /**
   * @param {number} bits
   */ untake(bits1) {
        this._currentBitPos += bits1;
        while(this._currentBitPos > 7){
            this._currentBitPos -= 8;
            this._currentBytePos += 1;
        }
    }
    _haveBits() {
        return this._currentBytePos >= 0;
    }
};
/**
 * @param {number} byte
 * @param {number} start
 * @param {number} length
 */ function byteBitsToInt(byte, start, length) {
    const mask = maskFor(start, length);
    return (byte & mask) >>> start;
}
/**
 * @param {number} start
 * @param {number} length
 */ function maskFor(start, length) {
    return START_MASKS[start] & STOP_MASKS[Math.min(length + start - 1, 7)];
}

},{}],"2Qhil":[function(require,module,exports) {
'use strict';
const toPathComponents = (path = '')=>{
    return (path.trim().match(/([^\\^/]|\\\/)+/g) || []).filter(Boolean);
};
module.exports = toPathComponents;

},{}],"43xHp":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var normaliseContent = require('./normalise-content.js');
var normalise = require('./normalise.js');
function normaliseInput(input) {
    return normalise.normalise(input, normaliseContent.normaliseContent);
}
exports.normaliseInput = normaliseInput;

},{"./normalise-content.js":"9wfsd","./normalise.js":"1enfJ"}],"9wfsd":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var errCode = require('err-code');
var fromString = require('uint8arrays/from-string');
var browserStreamToIt = require('browser-readablestream-to-it');
var blobToIt = require('blob-to-it');
var itPeekable = require('it-peekable');
var all = require('it-all');
var map = require('it-map');
var utils = require('./utils.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
var browserStreamToIt__default = /*#__PURE__*/ _interopDefaultLegacy(browserStreamToIt);
var blobToIt__default = /*#__PURE__*/ _interopDefaultLegacy(blobToIt);
var itPeekable__default = /*#__PURE__*/ _interopDefaultLegacy(itPeekable);
var all__default = /*#__PURE__*/ _interopDefaultLegacy(all);
var map__default = /*#__PURE__*/ _interopDefaultLegacy(map);
async function normaliseContent(input) {
    return toAsyncGenerator(input);
}
async function* toAsyncGenerator(input) {
    if (utils.isBytes(input)) {
        yield toBytes(input);
        return;
    }
    if (typeof input === 'string' || input instanceof String) {
        yield toBytes(input.toString());
        return;
    }
    if (utils.isBlob(input)) {
        yield* blobToIt__default['default'](input);
        return;
    }
    if (utils.isReadableStream(input)) input = browserStreamToIt__default['default'](input);
    if (Symbol.iterator in input || Symbol.asyncIterator in input) {
        const peekable = itPeekable__default['default'](input);
        const { value , done  } = await peekable.peek();
        if (done) {
            yield* [];
            return;
        }
        peekable.push(value);
        if (Number.isInteger(value)) {
            yield Uint8Array.from(await all__default['default'](peekable));
            return;
        }
        if (utils.isBytes(value) || typeof value === 'string' || value instanceof String) {
            yield* map__default['default'](peekable, toBytes);
            return;
        }
    }
    throw errCode__default['default'](new Error(`Unexpected input: ${input}`), 'ERR_UNEXPECTED_INPUT');
}
function toBytes(chunk) {
    if (chunk instanceof Uint8Array) return chunk;
    if (ArrayBuffer.isView(chunk)) return new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength);
    if (chunk instanceof ArrayBuffer) return new Uint8Array(chunk);
    if (Array.isArray(chunk)) return Uint8Array.from(chunk);
    return fromString.fromString(chunk.toString());
}
exports.normaliseContent = normaliseContent;

},{"err-code":"eQvyh","uint8arrays/from-string":"lo45E","browser-readablestream-to-it":"86Z8e","blob-to-it":"4kgAP","it-peekable":"kGyHM","it-all":"hynpN","it-map":"dOmp3","./utils.js":"c7UnV"}],"86Z8e":[function(require,module,exports) {
'use strict';
/**
 * Turns a browser readable stream into an async iterable. Async iteration over
 * returned iterable will lock give stream, preventing any other consumer from
 * acquiring a reader. The lock will be released if iteration loop is broken. To
 * prevent stream cancelling optional `{ preventCancel: true }` could be passed
 * as a second argument.
 * @template T
 * @param {ReadableStream<T>} stream
 * @param {Object} [options]
 * @param {boolean} [options.preventCancel=boolean]
 * @returns {AsyncIterable<T>}
 */ async function* browserReadableStreamToIt(stream, options = {
}) {
    const reader = stream.getReader();
    try {
        while(true){
            const result = await reader.read();
            if (result.done) return;
            yield result.value;
        }
    } finally{
        if (options.preventCancel !== true) reader.cancel();
        reader.releaseLock();
    }
}
module.exports = browserReadableStreamToIt;

},{}],"4kgAP":[function(require,module,exports) {
/* eslint-env browser */ 'use strict';
const browserReadableStreamToIt = require('browser-readablestream-to-it');
/**
 * @param {Blob} blob
 * @returns {AsyncIterable<Uint8Array>}
 */ function blobToIt(blob) {
    if (typeof blob.stream === 'function') // @ts-ignore missing some properties
    return browserReadableStreamToIt(blob.stream());
    // firefox < 69 does not support blob.stream()
    // @ts-ignore - response.body is optional, but in practice it's a stream.
    return browserReadableStreamToIt(new Response(blob).body);
}
module.exports = blobToIt;

},{"browser-readablestream-to-it":"86Z8e"}],"kGyHM":[function(require,module,exports) {
'use strict';
/**
 * @template T
 * @typedef {Object} Peek
 * @property {() => IteratorResult<T, void>} peek
 */ /**
 * @template T
 * @typedef {Object} AsyncPeek
 * @property {() => Promise<IteratorResult<T, void>>} peek
 */ /**
 * @template T
 * @typedef {Object} Push
 * @property {(value:T) => void} push
 */ /**
 * @template T
 * @typedef {Iterable<T> & Peek<T> & Push<T> & Iterator<T>} Peekable<T>
 */ /**
 * @template T
 * @typedef {AsyncIterable<T> & AsyncPeek<T> & Push<T> & AsyncIterator<T>} AsyncPeekable<T>
 */ /**
 * @template {Iterable<any> | AsyncIterable<any>} I
 * @param {I} iterable
 * @returns {I extends Iterable<infer T>
 *  ? Peekable<T>
 *  : I extends AsyncIterable<infer T>
 *  ? AsyncPeekable<T>
 *  : never
 * }
 */ function peekableIterator(iterable) {
    // @ts-ignore
    const [iterator, symbol] = iterable[Symbol.asyncIterator] ? [
        iterable[Symbol.asyncIterator](),
        Symbol.asyncIterator
    ] : [
        iterable[Symbol.iterator](),
        Symbol.iterator
    ];
    /** @type {any[]} */ const queue = [];
    // @ts-ignore
    return {
        peek: ()=>{
            return iterator.next();
        },
        push: (value)=>{
            queue.push(value);
        },
        next: ()=>{
            if (queue.length) return {
                done: false,
                value: queue.shift()
            };
            return iterator.next();
        },
        [symbol] () {
            return this;
        }
    };
}
module.exports = peekableIterator;

},{}],"c7UnV":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
function isBytes(obj) {
    return ArrayBuffer.isView(obj) || obj instanceof ArrayBuffer;
}
function isBlob(obj) {
    return obj.constructor && (obj.constructor.name === 'Blob' || obj.constructor.name === 'File') && typeof obj.stream === 'function';
}
function isFileObject(obj) {
    return typeof obj === 'object' && (obj.path || obj.content);
}
const isReadableStream = (value)=>value && typeof value.getReader === 'function'
;
exports.isBlob = isBlob;
exports.isBytes = isBytes;
exports.isFileObject = isFileObject;
exports.isReadableStream = isReadableStream;

},{}],"1enfJ":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var errCode = require('err-code');
var browserStreamToIt = require('browser-readablestream-to-it');
var itPeekable = require('it-peekable');
var map = require('it-map');
var utils = require('./utils.js');
var ipfsUnixfs = require('ipfs-unixfs');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
var browserStreamToIt__default = /*#__PURE__*/ _interopDefaultLegacy(browserStreamToIt);
var itPeekable__default = /*#__PURE__*/ _interopDefaultLegacy(itPeekable);
var map__default = /*#__PURE__*/ _interopDefaultLegacy(map);
async function* normalise(input, normaliseContent) {
    if (input === null || input === undefined) throw errCode__default['default'](new Error(`Unexpected input: ${input}`), 'ERR_UNEXPECTED_INPUT');
    if (typeof input === 'string' || input instanceof String) {
        yield toFileObject(input.toString(), normaliseContent);
        return;
    }
    if (utils.isBytes(input) || utils.isBlob(input)) {
        yield toFileObject(input, normaliseContent);
        return;
    }
    if (utils.isReadableStream(input)) input = browserStreamToIt__default['default'](input);
    if (Symbol.iterator in input || Symbol.asyncIterator in input) {
        const peekable = itPeekable__default['default'](input);
        const { value: value1 , done  } = await peekable.peek();
        if (done) {
            yield* [];
            return;
        }
        peekable.push(value1);
        if (Number.isInteger(value1) || utils.isBytes(value1)) {
            yield toFileObject(peekable, normaliseContent);
            return;
        }
        if (value1._readableState) {
            yield* map__default['default'](peekable, (value)=>toFileObject({
                    content: value
                }, normaliseContent)
            );
            return;
        }
        if (utils.isFileObject(value1) || utils.isBlob(value1) || typeof value1 === 'string' || value1 instanceof String) {
            yield* map__default['default'](peekable, (value)=>toFileObject(value, normaliseContent)
            );
            return;
        }
        if (value1[Symbol.iterator] || value1[Symbol.asyncIterator] || utils.isReadableStream(value1)) {
            yield* map__default['default'](peekable, (value)=>toFileObject(value, normaliseContent)
            );
            return;
        }
    }
    if (utils.isFileObject(input)) {
        yield toFileObject(input, normaliseContent);
        return;
    }
    throw errCode__default['default'](new Error('Unexpected input: ' + typeof input), 'ERR_UNEXPECTED_INPUT');
}
async function toFileObject(input, normaliseContent) {
    const { path , mode , mtime , content  } = input;
    const file = {
        path: path || '',
        mode: ipfsUnixfs.parseMode(mode),
        mtime: ipfsUnixfs.parseMtime(mtime)
    };
    if (content) file.content = await normaliseContent(content);
    else if (!path) file.content = await normaliseContent(input);
    return file;
}
exports.normalise = normalise;

},{"err-code":"eQvyh","browser-readablestream-to-it":"86Z8e","it-peekable":"kGyHM","it-map":"dOmp3","./utils.js":"c7UnV","ipfs-unixfs":"fttXc"}],"9ToCa":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
const parseChunkerString = (chunker)=>{
    if (!chunker) return {
        chunker: 'fixed'
    };
    else if (chunker.startsWith('size-')) {
        const sizeStr = chunker.split('-')[1];
        const size = parseInt(sizeStr);
        if (isNaN(size)) throw new Error('Chunker parameter size must be an integer');
        return {
            chunker: 'fixed',
            maxChunkSize: size
        };
    } else if (chunker.startsWith('rabin')) return {
        chunker: 'rabin',
        ...parseRabinString(chunker)
    };
    else throw new Error(`Unrecognized chunker option: ${chunker}`);
};
const parseRabinString = (chunker)=>{
    const options = {
    };
    const parts = chunker.split('-');
    switch(parts.length){
        case 1:
            options.avgChunkSize = 262144;
            break;
        case 2:
            options.avgChunkSize = parseChunkSize(parts[1], 'avg');
            break;
        case 4:
            options.minChunkSize = parseChunkSize(parts[1], 'min');
            options.avgChunkSize = parseChunkSize(parts[2], 'avg');
            options.maxChunkSize = parseChunkSize(parts[3], 'max');
            break;
        default:
            throw new Error('Incorrect chunker format (expected "rabin" "rabin-[avg]" or "rabin-[min]-[avg]-[max]"');
    }
    return options;
};
const parseChunkSize = (str, name)=>{
    const size = parseInt(str);
    if (isNaN(size)) throw new Error(`Chunker parameter ${name} must be an integer`);
    return size;
};
exports.parseChunkSize = parseChunkSize;
exports.parseChunkerString = parseChunkerString;
exports.parseRabinString = parseRabinString;

},{}],"kwiZz":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var ipfsUnixfsExporter = require('ipfs-unixfs-exporter');
var utils = require('../utils.js');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
var cid = require('multiformats/cid');
function createCat({ repo , preload  }) {
    async function* cat(ipfsPath, options = {
    }) {
        ipfsPath = utils.normalizeCidPath(ipfsPath);
        if (options.preload !== false) {
            const pathComponents = ipfsPath.split('/');
            preload(cid.CID.parse(pathComponents[0]));
        }
        const file = await ipfsUnixfsExporter.exporter(ipfsPath, repo.blocks, options);
        if (file.type === 'directory') throw new Error('this dag node is a directory');
        if (!file.content) throw new Error('this dag node has no content');
        yield* file.content(options);
    }
    return withTimeoutOption.withTimeoutOption(cat);
}
exports.createCat = createCat;

},{"ipfs-unixfs-exporter":"Ufvxm","../utils.js":"4LLx8","ipfs-core-utils/with-timeout-option":"5AiVw","multiformats/cid":"fJJnW"}],"Ufvxm":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var errCode = require('err-code');
var cid1 = require('multiformats/cid');
var index = require('./resolvers/index.js');
var last = require('it-last');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
var last__default = /*#__PURE__*/ _interopDefaultLegacy(last);
const toPathComponents = (path = '')=>{
    return (path.trim().match(/([^\\^/]|\\\/)+/g) || []).filter(Boolean);
};
const cidAndRest = (path)=>{
    if (path instanceof Uint8Array) return {
        cid: cid1.CID.decode(path),
        toResolve: []
    };
    const cid$1 = cid1.CID.asCID(path);
    if (cid$1) return {
        cid: cid$1,
        toResolve: []
    };
    if (typeof path === 'string') {
        if (path.indexOf('/ipfs/') === 0) path = path.substring(6);
        const output = toPathComponents(path);
        return {
            cid: cid1.CID.parse(output[0]),
            toResolve: output.slice(1)
        };
    }
    throw errCode__default['default'](new Error(`Unknown path type ${path}`), 'ERR_BAD_PATH');
};
async function* walkPath(path, blockstore, options = {
}) {
    let { cid , toResolve  } = cidAndRest(path);
    let name = cid.toString();
    let entryPath = name;
    const startingDepth = toResolve.length;
    while(true){
        const result = await index(cid, name, entryPath, toResolve, startingDepth, blockstore, options);
        if (!result.entry && !result.next) throw errCode__default['default'](new Error(`Could not resolve ${path}`), 'ERR_NOT_FOUND');
        if (result.entry) yield result.entry;
        if (!result.next) return;
        toResolve = result.next.toResolve;
        cid = result.next.cid;
        name = result.next.name;
        entryPath = result.next.path;
    }
}
async function exporter(path, blockstore, options = {
}) {
    const result = await last__default['default'](walkPath(path, blockstore, options));
    if (!result) throw errCode__default['default'](new Error(`Could not resolve ${path}`), 'ERR_NOT_FOUND');
    return result;
}
async function* recursive(path, blockstore, options1 = {
}) {
    const node1 = await exporter(path, blockstore, options1);
    if (!node1) return;
    yield node1;
    if (node1.type === 'directory') for await (const child of recurse(node1, options1))yield child;
    async function* recurse(node, options) {
        for await (const file of node.content(options)){
            yield file;
            if (file instanceof Uint8Array) continue;
            if (file.type === 'directory') yield* recurse(file, options);
        }
    }
}
exports.exporter = exporter;
exports.recursive = recursive;
exports.walkPath = walkPath;

},{"err-code":"eQvyh","multiformats/cid":"fJJnW","./resolvers/index.js":"f9cLT","it-last":"7VTHF"}],"f9cLT":[function(require,module,exports) {
'use strict';
var errCode = require('err-code');
var dagPb = require('@ipld/dag-pb');
var dagCbor = require('@ipld/dag-cbor');
var raw = require('multiformats/codecs/raw');
var identity = require('multiformats/hashes/identity');
var index = require('./unixfs-v1/index.js');
var raw$1 = require('./raw.js');
var dagCbor$1 = require('./dag-cbor.js');
var identity$1 = require('./identity.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n['default'] = e;
    return Object.freeze(n);
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
var dagPb__namespace = /*#__PURE__*/ _interopNamespace(dagPb);
var dagCbor__namespace = /*#__PURE__*/ _interopNamespace(dagCbor);
var raw__namespace = /*#__PURE__*/ _interopNamespace(raw);
const resolvers = {
    [dagPb__namespace.code]: index,
    [raw__namespace.code]: raw$1,
    [dagCbor__namespace.code]: dagCbor$1,
    [identity.identity.code]: identity$1
};
function resolve(cid, name, path, toResolve, depth, blockstore, options) {
    const resolver = resolvers[cid.code];
    if (!resolver) throw errCode__default['default'](new Error(`No resolver for code ${cid.code}`), 'ERR_NO_RESOLVER');
    return resolver(cid, name, path, toResolve, resolve, depth, blockstore, options);
}
module.exports = resolve;

},{"err-code":"eQvyh","@ipld/dag-pb":"e9gy2","@ipld/dag-cbor":"kSG7F","multiformats/codecs/raw":"dkcyY","multiformats/hashes/identity":"7Cndu","./unixfs-v1/index.js":"SgUjh","./raw.js":"jIBBI","./dag-cbor.js":"gKtmA","./identity.js":"gr2fC"}],"SgUjh":[function(require,module,exports) {
'use strict';
var errCode = require('err-code');
var ipfsUnixfs = require('ipfs-unixfs');
var findCidInShard = require('../../utils/find-cid-in-shard.js');
var dagPb = require('@ipld/dag-pb');
var file = require('./content/file.js');
var directory = require('./content/directory.js');
var hamtShardedDirectory = require('./content/hamt-sharded-directory.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
const findLinkCid = (node, name)=>{
    const link1 = node.Links.find((link)=>link.Name === name
    );
    return link1 && link1.Hash;
};
const contentExporters = {
    raw: file,
    file: file,
    directory: directory,
    'hamt-sharded-directory': hamtShardedDirectory,
    metadata: (cid, node, unixfs, path, resolve, depth, blockstore)=>{
        return ()=>[]
        ;
    },
    symlink: (cid, node, unixfs, path, resolve, depth, blockstore)=>{
        return ()=>[]
        ;
    }
};
const unixFsResolver = async (cid, name, path, toResolve, resolve, depth, blockstore, options)=>{
    const block = await blockstore.get(cid, options);
    const node = dagPb.decode(block);
    let unixfs;
    let next;
    if (!name) name = cid.toString();
    if (node.Data == null) throw errCode__default['default'](new Error('no data in PBNode'), 'ERR_NOT_UNIXFS');
    try {
        unixfs = ipfsUnixfs.UnixFS.unmarshal(node.Data);
    } catch (err) {
        throw errCode__default['default'](err, 'ERR_NOT_UNIXFS');
    }
    if (!path) path = name;
    if (toResolve.length) {
        let linkCid;
        if (unixfs && unixfs.type === 'hamt-sharded-directory') linkCid = await findCidInShard(node, toResolve[0], blockstore);
        else linkCid = findLinkCid(node, toResolve[0]);
        if (!linkCid) throw errCode__default['default'](new Error('file does not exist'), 'ERR_NOT_FOUND');
        const nextName = toResolve.shift();
        const nextPath = `${path}/${nextName}`;
        next = {
            cid: linkCid,
            toResolve,
            name: nextName || '',
            path: nextPath
        };
    }
    return {
        entry: {
            type: unixfs.isDirectory() ? 'directory' : 'file',
            name,
            path,
            cid,
            content: contentExporters[unixfs.type](cid, node, unixfs, path, resolve, depth, blockstore),
            unixfs,
            depth,
            node,
            size: unixfs.fileSize()
        },
        next
    };
};
module.exports = unixFsResolver;

},{"err-code":"eQvyh","ipfs-unixfs":"fttXc","../../utils/find-cid-in-shard.js":"hhvwS","@ipld/dag-pb":"e9gy2","./content/file.js":"6AJ98","./content/directory.js":"1ylUp","./content/hamt-sharded-directory.js":"fWrIK"}],"hhvwS":[function(require,module,exports) {
'use strict';
var hamtSharding = require('hamt-sharding');
var dagPb = require('@ipld/dag-pb');
var murmur3 = require('@multiformats/murmur3');
const hashFn = async function(buf) {
    return (await murmur3.murmur3128.encode(buf)).slice(0, 8).reverse();
};
const addLinksToHamtBucket = (links, bucket, rootBucket)=>{
    return Promise.all(links.map((link)=>{
        if (link.Name == null) throw new Error('Unexpected Link without a Name');
        if (link.Name.length === 2) {
            const pos = parseInt(link.Name, 16);
            return bucket._putObjectAt(pos, new hamtSharding.Bucket({
                hash: rootBucket._options.hash,
                bits: rootBucket._options.bits
            }, bucket, pos));
        }
        return rootBucket.put(link.Name.substring(2), true);
    }));
};
const toPrefix = (position)=>{
    return position.toString(16).toUpperCase().padStart(2, '0').substring(0, 2);
};
const toBucketPath = (position)=>{
    let bucket = position.bucket;
    const path = [];
    while(bucket._parent){
        path.push(bucket);
        bucket = bucket._parent;
    }
    path.push(bucket);
    return path.reverse();
};
const findShardCid = async (node, name, blockstore, context, options)=>{
    if (!context) {
        const rootBucket = hamtSharding.createHAMT({
            hashFn
        });
        context = {
            rootBucket,
            hamtDepth: 1,
            lastBucket: rootBucket
        };
    }
    await addLinksToHamtBucket(node.Links, context.lastBucket, context.rootBucket);
    const position = await context.rootBucket._findNewBucketAndPos(name);
    let prefix = toPrefix(position.pos);
    const bucketPath = toBucketPath(position);
    if (bucketPath.length > context.hamtDepth) {
        context.lastBucket = bucketPath[context.hamtDepth];
        prefix = toPrefix(context.lastBucket._posAtParent);
    }
    const link1 = node.Links.find((link)=>{
        if (link.Name == null) return false;
        const entryPrefix = link.Name.substring(0, 2);
        const entryName = link.Name.substring(2);
        if (entryPrefix !== prefix) return false;
        if (entryName && entryName !== name) return false;
        return true;
    });
    if (!link1) return null;
    if (link1.Name != null && link1.Name.substring(2) === name) return link1.Hash;
    context.hamtDepth++;
    const block = await blockstore.get(link1.Hash, options);
    node = dagPb.decode(block);
    return findShardCid(node, name, blockstore, context, options);
};
module.exports = findShardCid;

},{"hamt-sharding":"4VZAD","@ipld/dag-pb":"e9gy2","@multiformats/murmur3":"dDuFh"}],"6AJ98":[function(require,module,exports) {
'use strict';
var extractDataFromBlock = require('../../../utils/extract-data-from-block.js');
var validateOffsetAndLength = require('../../../utils/validate-offset-and-length.js');
var ipfsUnixfs = require('ipfs-unixfs');
var errCode = require('err-code');
var dagPb = require('@ipld/dag-pb');
var dagCbor = require('@ipld/dag-cbor');
var raw = require('multiformats/codecs/raw');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n['default'] = e;
    return Object.freeze(n);
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
var dagPb__namespace = /*#__PURE__*/ _interopNamespace(dagPb);
var dagCbor__namespace = /*#__PURE__*/ _interopNamespace(dagCbor);
var raw__namespace = /*#__PURE__*/ _interopNamespace(raw);
async function* emitBytes(blockstore, node, start, end, streamPosition = 0, options) {
    if (node instanceof Uint8Array) {
        const buf = extractDataFromBlock(node, streamPosition, start, end);
        if (buf.length) yield buf;
        streamPosition += buf.length;
        return streamPosition;
    }
    if (node.Data == null) throw errCode__default['default'](new Error('no data in PBNode'), 'ERR_NOT_UNIXFS');
    let file;
    try {
        file = ipfsUnixfs.UnixFS.unmarshal(node.Data);
    } catch (err) {
        throw errCode__default['default'](err, 'ERR_NOT_UNIXFS');
    }
    if (file.data && file.data.length) {
        const buf = extractDataFromBlock(file.data, streamPosition, start, end);
        if (buf.length) yield buf;
        streamPosition += file.data.length;
    }
    let childStart = streamPosition;
    for(let i = 0; i < node.Links.length; i++){
        const childLink = node.Links[i];
        const childEnd = streamPosition + file.blockSizes[i];
        if (start >= childStart && start < childEnd || end > childStart && end <= childEnd || start < childStart && end > childEnd) {
            const block = await blockstore.get(childLink.Hash, {
                signal: options.signal
            });
            let child;
            switch(childLink.Hash.code){
                case dagPb__namespace.code:
                    child = await dagPb__namespace.decode(block);
                    break;
                case raw__namespace.code:
                    child = block;
                    break;
                case dagCbor__namespace.code:
                    child = await dagCbor__namespace.decode(block);
                    break;
                default:
                    throw Error(`Unsupported codec: ${childLink.Hash.code}`);
            }
            for await (const buf of emitBytes(blockstore, child, start, end, streamPosition, options)){
                streamPosition += buf.length;
                yield buf;
            }
        }
        streamPosition = childEnd;
        childStart = childEnd + 1;
    }
}
const fileContent = (cid, node, unixfs, path, resolve, depth, blockstore)=>{
    function yieldFileContent(options = {
    }) {
        const fileSize = unixfs.fileSize();
        if (fileSize === undefined) throw new Error('File was a directory');
        const { offset , length  } = validateOffsetAndLength(fileSize, options.offset, options.length);
        const start = offset;
        const end = offset + length;
        return emitBytes(blockstore, node, start, end, 0, options);
    }
    return yieldFileContent;
};
module.exports = fileContent;

},{"../../../utils/extract-data-from-block.js":"gLSTs","../../../utils/validate-offset-and-length.js":"6HRVJ","ipfs-unixfs":"fttXc","err-code":"eQvyh","@ipld/dag-pb":"e9gy2","@ipld/dag-cbor":"kSG7F","multiformats/codecs/raw":"dkcyY"}],"gLSTs":[function(require,module,exports) {
'use strict';
function extractDataFromBlock(block, blockStart, requestedStart, requestedEnd) {
    const blockLength = block.length;
    const blockEnd = blockStart + blockLength;
    if (requestedStart >= blockEnd || requestedEnd < blockStart) return new Uint8Array(0);
    if (requestedEnd >= blockStart && requestedEnd < blockEnd) block = block.slice(0, requestedEnd - blockStart);
    if (requestedStart >= blockStart && requestedStart < blockEnd) block = block.slice(requestedStart - blockStart);
    return block;
}
module.exports = extractDataFromBlock;

},{}],"6HRVJ":[function(require,module,exports) {
'use strict';
var errCode = require('err-code');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
const validateOffsetAndLength = (size, offset, length)=>{
    if (!offset) offset = 0;
    if (offset < 0) throw errCode__default['default'](new Error('Offset must be greater than or equal to 0'), 'ERR_INVALID_PARAMS');
    if (offset > size) throw errCode__default['default'](new Error('Offset must be less than the file size'), 'ERR_INVALID_PARAMS');
    if (!length && length !== 0) length = size - offset;
    if (length < 0) throw errCode__default['default'](new Error('Length must be greater than or equal to 0'), 'ERR_INVALID_PARAMS');
    if (offset + length > size) length = size - offset;
    return {
        offset,
        length
    };
};
module.exports = validateOffsetAndLength;

},{"err-code":"eQvyh"}],"1ylUp":[function(require,module,exports) {
'use strict';
const directoryContent = (cid, node, unixfs, path, resolve, depth, blockstore)=>{
    async function* yieldDirectoryContent(options = {
    }) {
        const offset = options.offset || 0;
        const length = options.length || node.Links.length;
        const links = node.Links.slice(offset, length);
        for (const link of links){
            const result = await resolve(link.Hash, link.Name || '', `${path}/${link.Name || ''}`, [], depth + 1, blockstore, options);
            if (result.entry) yield result.entry;
        }
    }
    return yieldDirectoryContent;
};
module.exports = directoryContent;

},{}],"fWrIK":[function(require,module,exports) {
'use strict';
var dagPb = require('@ipld/dag-pb');
const hamtShardedDirectoryContent = (cid, node, unixfs, path, resolve, depth, blockstore)=>{
    function yieldHamtDirectoryContent(options = {
    }) {
        return listDirectory(node, path, resolve, depth, blockstore, options);
    }
    return yieldHamtDirectoryContent;
};
async function* listDirectory(node, path, resolve, depth, blockstore, options) {
    const links = node.Links;
    for (const link of links){
        const name = link.Name != null ? link.Name.substring(2) : null;
        if (name) {
            const result = await resolve(link.Hash, name, `${path}/${name}`, [], depth + 1, blockstore, options);
            yield result.entry;
        } else {
            const block = await blockstore.get(link.Hash);
            node = dagPb.decode(block);
            for await (const file of listDirectory(node, path, resolve, depth, blockstore, options))yield file;
        }
    }
}
module.exports = hamtShardedDirectoryContent;

},{"@ipld/dag-pb":"e9gy2"}],"jIBBI":[function(require,module,exports) {
'use strict';
var errCode = require('err-code');
var extractDataFromBlock = require('../utils/extract-data-from-block.js');
var validateOffsetAndLength = require('../utils/validate-offset-and-length.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
const rawContent = (node)=>{
    async function* contentGenerator(options = {
    }) {
        const { offset , length  } = validateOffsetAndLength(node.length, options.offset, options.length);
        yield extractDataFromBlock(node, 0, offset, offset + length);
    }
    return contentGenerator;
};
const resolve = async (cid, name, path, toResolve, resolve, depth, blockstore, options)=>{
    if (toResolve.length) throw errCode__default['default'](new Error(`No link named ${path} found in raw node ${cid}`), 'ERR_NOT_FOUND');
    const block = await blockstore.get(cid, options);
    return {
        entry: {
            type: 'raw',
            name,
            path,
            cid,
            content: rawContent(block),
            depth,
            size: block.length,
            node: block
        }
    };
};
module.exports = resolve;

},{"err-code":"eQvyh","../utils/extract-data-from-block.js":"gLSTs","../utils/validate-offset-and-length.js":"6HRVJ"}],"gKtmA":[function(require,module,exports) {
'use strict';
var cid = require('multiformats/cid');
var errCode = require('err-code');
var dagCbor = require('@ipld/dag-cbor');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n['default'] = e;
    return Object.freeze(n);
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
var dagCbor__namespace = /*#__PURE__*/ _interopNamespace(dagCbor);
const resolve = async (cid$1, name, path, toResolve, resolve, depth, blockstore, options)=>{
    const block = await blockstore.get(cid$1);
    const object = dagCbor__namespace.decode(block);
    let subObject = object;
    let subPath = path;
    while(toResolve.length){
        const prop = toResolve[0];
        if (prop in subObject) {
            toResolve.shift();
            subPath = `${subPath}/${prop}`;
            const subObjectCid = cid.CID.asCID(subObject[prop]);
            if (subObjectCid) return {
                entry: {
                    type: 'object',
                    name,
                    path,
                    cid: cid$1,
                    node: block,
                    depth,
                    size: block.length,
                    content: async function*() {
                        yield object;
                    }
                },
                next: {
                    cid: subObjectCid,
                    name: prop,
                    path: subPath,
                    toResolve
                }
            };
            subObject = subObject[prop];
        } else throw errCode__default['default'](new Error(`No property named ${prop} found in cbor node ${cid$1}`), 'ERR_NO_PROP');
    }
    return {
        entry: {
            type: 'object',
            name,
            path,
            cid: cid$1,
            node: block,
            depth,
            size: block.length,
            content: async function*() {
                yield object;
            }
        }
    };
};
module.exports = resolve;

},{"multiformats/cid":"fJJnW","err-code":"eQvyh","@ipld/dag-cbor":"kSG7F"}],"gr2fC":[function(require,module,exports) {
'use strict';
var errCode = require('err-code');
var extractDataFromBlock = require('../utils/extract-data-from-block.js');
var validateOffsetAndLength = require('../utils/validate-offset-and-length.js');
var mh = require('multiformats/hashes/digest');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n['default'] = e;
    return Object.freeze(n);
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
var mh__namespace = /*#__PURE__*/ _interopNamespace(mh);
const rawContent = (node)=>{
    async function* contentGenerator(options = {
    }) {
        const { offset , length  } = validateOffsetAndLength(node.length, options.offset, options.length);
        yield extractDataFromBlock(node, 0, offset, offset + length);
    }
    return contentGenerator;
};
const resolve = async (cid, name, path, toResolve, resolve, depth, blockstore, options)=>{
    if (toResolve.length) throw errCode__default['default'](new Error(`No link named ${path} found in raw node ${cid}`), 'ERR_NOT_FOUND');
    const buf = await mh__namespace.decode(cid.multihash.bytes);
    return {
        entry: {
            type: 'identity',
            name,
            path,
            cid,
            content: rawContent(buf.digest),
            depth,
            size: buf.digest.length,
            node: buf.digest
        }
    };
};
module.exports = resolve;

},{"err-code":"eQvyh","../utils/extract-data-from-block.js":"gLSTs","../utils/validate-offset-and-length.js":"6HRVJ","multiformats/hashes/digest":"fkA58"}],"2cO9x":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var ipfsUnixfsExporter = require('ipfs-unixfs-exporter');
var errCode = require('err-code');
var utils = require('../utils.js');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
var cid = require('multiformats/cid');
var itTar = require('it-tar');
var itPipe = require('it-pipe');
var Pako = require('pako');
var map = require('it-map');
var toBuffer = require('it-to-buffer');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
var Pako__default = /*#__PURE__*/ _interopDefaultLegacy(Pako);
var map__default = /*#__PURE__*/ _interopDefaultLegacy(map);
var toBuffer__default = /*#__PURE__*/ _interopDefaultLegacy(toBuffer);
const DEFAULT_COMPRESSION_LEVEL = 6;
function createGet({ repo , preload  }) {
    async function* get(ipfsPath, options = {
    }) {
        if (options.compressionLevel < 0 || options.compressionLevel > 9) throw errCode__default['default'](new Error('Compression level must be between 1 and 9'), 'ERR_INVALID_PARAMS');
        if (options.preload !== false) {
            let pathComponents;
            try {
                pathComponents = utils.normalizeCidPath(ipfsPath).split('/');
            } catch (err) {
                throw errCode__default['default'](err, 'ERR_INVALID_PATH');
            }
            preload(cid.CID.parse(pathComponents[0]));
        }
        const ipfsPathOrCid = cid.CID.asCID(ipfsPath) || ipfsPath;
        const file = await ipfsUnixfsExporter.exporter(ipfsPathOrCid, repo.blocks, options);
        if (file.type === 'file' || file.type === 'raw') {
            const args = [];
            if (!options.compress || options.archive === true) args.push([
                {
                    header: {
                        name: file.path,
                        mode: file.type === 'file' && file.unixfs.mode,
                        mtime: file.type === 'file' && file.unixfs.mtime ? new Date(file.unixfs.mtime.secs * 1000) : undefined,
                        size: file.size,
                        type: 'file'
                    },
                    body: file.content()
                }
            ], itTar.pack(), (source)=>map__default['default'](source, (buf)=>buf.slice()
                )
            );
            else args.push(file.content);
            if (options.compress) args.push(async function*(source) {
                const buf = await toBuffer__default['default'](source);
                yield Pako__default['default'].gzip(buf, {
                    level: options.compressionLevel || DEFAULT_COMPRESSION_LEVEL
                });
            });
            yield* itPipe.pipe(...args);
            return;
        }
        if (file.type === 'directory') {
            const args = [
                ipfsUnixfsExporter.recursive(ipfsPathOrCid, repo.blocks, options),
                async function*(source) {
                    for await (const entry of source){
                        const output = {
                            header: {
                                name: entry.path,
                                size: entry.size
                            }
                        };
                        if (entry.type === 'file') {
                            output.header.type = 'file';
                            output.header.mode = entry.unixfs.mode != null ? entry.unixfs.mode : undefined;
                            output.header.mtime = entry.unixfs.mtime ? new Date(entry.unixfs.mtime.secs * 1000) : undefined;
                            output.body = entry.content();
                        } else if (entry.type === 'raw') {
                            output.header.type = 'file';
                            output.body = entry.content();
                        } else if (entry.type === 'directory') {
                            output.header.type = 'directory';
                            output.header.mode = entry.unixfs.mode != null ? entry.unixfs.mode : undefined;
                            output.header.mtime = entry.unixfs.mtime ? new Date(entry.unixfs.mtime.secs * 1000) : undefined;
                        } else throw errCode__default['default'](new Error('Not a UnixFS node'), 'ERR_NOT_UNIXFS');
                        yield output;
                    }
                },
                itTar.pack(),
                (source)=>map__default['default'](source, (buf)=>buf.slice()
                    )
            ];
            if (options.compress) {
                if (!options.archive) throw errCode__default['default'](new Error('file is not regular'), 'ERR_INVALID_PATH');
                if (options.compress) args.push(async function*(source) {
                    const buf = await toBuffer__default['default'](source);
                    yield Pako__default['default'].gzip(buf, {
                        level: options.compressionLevel || DEFAULT_COMPRESSION_LEVEL
                    });
                });
            }
            yield* itPipe.pipe(...args);
            return;
        }
        throw errCode__default['default'](new Error('Not a UnixFS node'), 'ERR_NOT_UNIXFS');
    }
    return withTimeoutOption.withTimeoutOption(get);
}
exports.createGet = createGet;

},{"ipfs-unixfs-exporter":"Ufvxm","err-code":"eQvyh","../utils.js":"4LLx8","ipfs-core-utils/with-timeout-option":"5AiVw","multiformats/cid":"fJJnW","it-tar":"geJxH","it-pipe":"4jukm","pako":"jntDO","it-map":"dOmp3","it-to-buffer":"fQrKG"}],"geJxH":[function(require,module,exports) {
exports.extract = require('./extract');
exports.pack = require('./pack');

},{"./extract":"Y9CkC","./pack":"gSaNp"}],"Y9CkC":[function(require,module,exports) {
const defer = require('p-defer');
const Headers = require('./extract-headers');
const LteReader = require('./lte-reader');
function getPadding(size) {
    size &= 511;
    return size && 512 - size;
}
async function discardPadding(reader, size) {
    const overflow = getPadding(size);
    if (overflow) await reader.next(overflow);
}
module.exports = (options)=>{
    options = options || {
    };
    options.highWaterMark = options.highWaterMark || 16384;
    return (source)=>(async function*() {
            const reader = LteReader(source);
            let gnuLongPath, gnuLongLinkPath, paxGlobal, pax;
            try {
                while(true){
                    let headerBytes;
                    try {
                        const { done , value  } = await reader.next(512);
                        if (done) return;
                        headerBytes = value;
                    } catch (err) {
                        // Is ok, this is the end of the stream!
                        if (err.code === 'ERR_UNDER_READ') return;
                        throw err;
                    }
                    const header = Headers.decode(headerBytes, options.filenameEncoding);
                    if (!header) continue;
                    if (header.type === 'gnu-long-path') {
                        const { done , value: gnuLongPathBytes  } = await reader.next(header.size);
                        if (done) return;
                        gnuLongPath = Headers.decodeLongPath(gnuLongPathBytes, options.filenameEncoding);
                        await discardPadding(reader, header.size);
                        continue;
                    }
                    if (header.type === 'gnu-long-link-path') {
                        const { done , value: gnuLongLinkPathBytes  } = await reader.next(header.size);
                        if (done) return;
                        gnuLongLinkPath = Headers.decodeLongPath(gnuLongLinkPathBytes, options.filenameEncoding);
                        await discardPadding(reader, header.size);
                        continue;
                    }
                    if (header.type === 'pax-global-header') {
                        const { done , value: paxGlobalBytes  } = await reader.next(header.size);
                        if (done) return;
                        paxGlobal = Headers.decodePax(paxGlobalBytes, options.filenameEncoding);
                        await discardPadding(reader, header.size);
                        continue;
                    }
                    if (header.type === 'pax-header') {
                        const { done , value: paxBytes  } = await reader.next(header.size);
                        if (done) return;
                        pax = Headers.decodePax(paxBytes, options.filenameEncoding);
                        if (paxGlobal) pax = {
                            ...paxGlobal,
                            ...pax
                        };
                        await discardPadding(reader, header.size);
                        continue;
                    }
                    if (gnuLongPath) {
                        header.name = gnuLongPath;
                        gnuLongPath = null;
                    }
                    if (gnuLongLinkPath) {
                        header.linkname = gnuLongLinkPath;
                        gnuLongLinkPath = null;
                    }
                    if (pax) {
                        if (pax.path) header.name = pax.path;
                        if (pax.linkpath) header.linkname = pax.linkpath;
                        if (pax.size) header.size = parseInt(pax.size, 10);
                        header.pax = pax;
                        pax = null;
                    }
                    if (!header.size || header.type === 'directory') {
                        yield {
                            header,
                            body: (async function*() {
                            })()
                        };
                        continue;
                    }
                    let bytesRemaining = header.size;
                    const bodyConsumed = defer();
                    // Prefetch the first chunk.
                    // This allows us to stream entries for small files from the tar without
                    // explicitly streaming the body of each.
                    const firstChunk = await reader.nextLte(Math.min(bytesRemaining, options.highWaterMark));
                    bytesRemaining -= firstChunk.value.length;
                    if (!bytesRemaining) bodyConsumed.resolve();
                    const body = async function*() {
                        try {
                            yield firstChunk.value;
                            while(bytesRemaining){
                                const { done , value  } = await reader.nextLte(bytesRemaining);
                                if (done) {
                                    bytesRemaining = 0;
                                    return;
                                }
                                bytesRemaining -= value.length;
                                yield value;
                            }
                        } finally{
                            bodyConsumed.resolve();
                        }
                    }();
                    yield {
                        header,
                        body
                    };
                    // Wait for the body to be consumed
                    await bodyConsumed.promise;
                    // Incase the body was not consumed entirely...
                    if (bytesRemaining) {
                        for await (const _ of body); // eslint-disable-line no-unused-vars,no-empty
                    }
                    await discardPadding(reader, header.size);
                }
            } finally{
                await reader.return();
            }
        })()
    ;
};

},{"p-defer":"gZqcC","./extract-headers":"fiCYz","./lte-reader":"9RBrG"}],"fiCYz":[function(require,module,exports) {
const { Buffer  } = require('buffer');
const BufferList = require('bl/BufferList');
const ZERO_OFFSET = '0'.charCodeAt(0);
const USTAR_MAGIC = Buffer.from('ustar\x00', 'binary');
const GNU_MAGIC = Buffer.from('ustar\x20', 'binary');
const GNU_VER = Buffer.from('\x20\x00', 'binary');
const MAGIC_OFFSET = 257;
const VERSION_OFFSET = 263;
const clamp = function(index, len, defaultValue) {
    if (typeof index !== 'number') return defaultValue;
    index = ~~index // Coerce to integer.
    ;
    if (index >= len) return len;
    if (index >= 0) return index;
    index += len;
    if (index >= 0) return index;
    return 0;
};
const toType = function(flag) {
    switch(flag){
        case 0:
            return 'file';
        case 1:
            return 'link';
        case 2:
            return 'symlink';
        case 3:
            return 'character-device';
        case 4:
            return 'block-device';
        case 5:
            return 'directory';
        case 6:
            return 'fifo';
        case 7:
            return 'contiguous-file';
        case 72:
            return 'pax-header';
        case 55:
            return 'pax-global-header';
        case 27:
            return 'gnu-long-link-path';
        case 28:
        case 30:
            return 'gnu-long-path';
    }
    return null;
};
const indexOf = function(block, num, offset, end) {
    for(; offset < end; offset++){
        if (block.get(offset) === num) return offset;
    }
    return end;
};
const cksum = function(block) {
    let sum = 256;
    for(let i = 0; i < 148; i++)sum += block.get(i);
    for(let j = 156; j < 512; j++)sum += block.get(j);
    return sum;
};
/* Copied from the node-tar repo and modified to meet
 * tar-stream coding standard.
 *
 * Source: https://github.com/npm/node-tar/blob/51b6627a1f357d2eb433e7378e5f05e83b7aa6cd/lib/header.js#L349
 */ function parse256(buf) {
    // first byte MUST be either 80 or FF
    // 80 for positive, FF for 2's comp
    let positive;
    if (buf.get(0) === 128) positive = true;
    else if (buf.get(0) === 255) positive = false;
    else return null;
    // build up a base-256 tuple from the least sig to the highest
    let zero = false;
    const tuple = [];
    for(let i = buf.length - 1; i > 0; i--){
        const byte = buf.get(i);
        if (positive) tuple.push(byte);
        else if (zero && byte === 0) tuple.push(0);
        else if (zero) {
            zero = false;
            tuple.push(256 - byte);
        } else tuple.push(255 - byte);
    }
    let sum = 0;
    const l = tuple.length;
    for(let i1 = 0; i1 < l; i1++)sum += tuple[i1] * Math.pow(256, i1);
    return positive ? sum : -1 * sum;
}
const decodeOct = function(val, offset, length) {
    val = val.shallowSlice(offset, offset + length);
    offset = 0;
    // If prefixed with 0x80 then parse as a base-256 integer
    if (val.get(offset) & 128) return parse256(val);
    else {
        // Older versions of tar can prefix with spaces
        while(offset < val.length && val.get(offset) === 32)offset++;
        const end = clamp(indexOf(val, 32, offset, val.length), val.length, val.length);
        while(offset < end && val.get(offset) === 0)offset++;
        if (end === offset) return 0;
        return parseInt(val.shallowSlice(offset, end).toString(), 8);
    }
};
const decodeStr = function(val, offset, length, encoding) {
    return val.shallowSlice(offset, indexOf(val, 0, offset, offset + length)).toString(encoding);
};
exports.decodeLongPath = function(buf, encoding) {
    buf = BufferList.isBufferList(buf) ? buf : new BufferList(buf);
    return decodeStr(buf, 0, buf.length, encoding);
};
exports.decodePax = function(buf) {
    buf = BufferList.isBufferList(buf) ? buf : new BufferList(buf);
    const result = {
    };
    while(buf.length){
        let i = 0;
        while(i < buf.length && buf.get(i) !== 32)i++;
        const len = parseInt(buf.shallowSlice(0, i).toString(), 10);
        if (!len) return result;
        const b = buf.shallowSlice(i + 1, len - 1).toString();
        const keyIndex = b.indexOf('=');
        if (keyIndex === -1) return result;
        result[b.slice(0, keyIndex)] = b.slice(keyIndex + 1);
        buf = buf.shallowSlice(len);
    }
    return result;
};
exports.decode = function(buf, filenameEncoding) {
    buf = BufferList.isBufferList(buf) ? buf : new BufferList(buf);
    let typeflag = buf.get(156) === 0 ? 0 : buf.get(156) - ZERO_OFFSET;
    let name = decodeStr(buf, 0, 100, filenameEncoding);
    const mode = decodeOct(buf, 100, 8);
    const uid = decodeOct(buf, 108, 8);
    const gid = decodeOct(buf, 116, 8);
    const size = decodeOct(buf, 124, 12);
    const mtime = decodeOct(buf, 136, 12);
    const type = toType(typeflag);
    const linkname = buf.get(157) === 0 ? null : decodeStr(buf, 157, 100, filenameEncoding);
    const uname = decodeStr(buf, 265, 32);
    const gname = decodeStr(buf, 297, 32);
    const devmajor = decodeOct(buf, 329, 8);
    const devminor = decodeOct(buf, 337, 8);
    const c = cksum(buf);
    // checksum is still initial value if header was null.
    if (c === 256) return null;
    // valid checksum
    if (c !== decodeOct(buf, 148, 8)) throw new Error('Invalid tar header. Maybe the tar is corrupted or it needs to be gunzipped?');
    if (USTAR_MAGIC.compare(buf.slice(MAGIC_OFFSET, MAGIC_OFFSET + 6)) === 0) // ustar (posix) format.
    // prepend prefix, if present.
    {
        if (buf.get(345)) name = decodeStr(buf, 345, 155, filenameEncoding) + '/' + name;
    } else if (GNU_MAGIC.compare(buf.slice(MAGIC_OFFSET, MAGIC_OFFSET + 6)) === 0 && GNU_VER.compare(buf.slice(VERSION_OFFSET, VERSION_OFFSET + 2)) === 0) ;
    else throw new Error('Invalid tar header: unknown format.');
    // to support old tar versions that use trailing / to indicate dirs
    if (typeflag === 0 && name && name[name.length - 1] === '/') typeflag = 5;
    return {
        name: name,
        mode: mode,
        uid: uid,
        gid: gid,
        size: size,
        mtime: new Date(1000 * mtime),
        type: type,
        linkname: linkname,
        uname: uname,
        gname: gname,
        devmajor: devmajor,
        devminor: devminor
    };
};

},{"buffer":"eKea5","bl/BufferList":"cK5XN"}],"9RBrG":[function(require,module,exports) {
const BufferList = require('bl/BufferList');
const Reader = require('it-reader');
module.exports = function LteReader(source) {
    const reader = Reader(source);
    let overflow;
    const lteReader = {
        [Symbol.asyncIterator]: ()=>lteReader
        ,
        async next (bytes) {
            if (overflow) {
                let value;
                if (bytes == null || overflow.length === bytes) {
                    value = overflow;
                    overflow = null;
                } else if (overflow.length > bytes) {
                    value = overflow.shallowSlice(0, bytes);
                    overflow = overflow.shallowSlice(bytes);
                } else if (overflow.length < bytes) {
                    const { value: nextValue , done  } = await reader.next(bytes - overflow.length);
                    if (done) throw Object.assign(new Error(`stream ended before ${bytes - overflow.length} bytes became available`), {
                        code: 'ERR_UNDER_READ'
                    });
                    value = new BufferList([
                        overflow,
                        nextValue
                    ]);
                    overflow = null;
                }
                return {
                    value
                };
            }
            return reader.next(bytes);
        },
        async nextLte (bytes) {
            let { done , value  } = await lteReader.next();
            if (done) return {
                done
            };
            if (value.length <= bytes) return {
                value
            };
            value = BufferList.isBufferList(value) ? value : new BufferList(value);
            if (overflow) overflow.append(value.shallowSlice(bytes));
            else overflow = value.shallowSlice(bytes);
            return {
                value: value.shallowSlice(0, bytes)
            };
        },
        return () {
            return reader.return();
        }
    };
    return lteReader;
};

},{"bl/BufferList":"cK5XN","it-reader":"8Ef74"}],"8Ef74":[function(require,module,exports) {
const BufferList = require('bl/BufferList');
module.exports = (source)=>{
    const reader = async function*() {
        let bytes = yield // Allows us to receive 8 when reader.next(8) is called
        ;
        let bl = new BufferList();
        for await (const chunk of source){
            if (!bytes) {
                bytes = yield bl.append(chunk);
                bl = new BufferList();
                continue;
            }
            bl.append(chunk);
            while(bl.length >= bytes){
                const data = bl.shallowSlice(0, bytes);
                bl.consume(bytes);
                bytes = yield data;
                // If we no longer want a specific byte length, we yield the rest now
                if (!bytes) {
                    if (bl.length) {
                        bytes = yield bl;
                        bl = new BufferList();
                    }
                    break; // bytes is null and/or no more buffer to yield
                }
            }
        }
        // Consumer wants more bytes but the source has ended and our buffer
        // is not big enough to satisfy.
        if (bytes) throw Object.assign(new Error(`stream ended before ${bytes} bytes became available`), {
            code: 'ERR_UNDER_READ',
            buffer: bl
        });
    }();
    reader.next();
    return reader;
};

},{"bl/BufferList":"cK5XN"}],"gSaNp":[function(require,module,exports) {
const { Buffer  } = require('buffer');
const BufferList = require('bl/BufferList');
const { S_IFMT , S_IFBLK , S_IFCHR , S_IFDIR , S_IFIFO , S_IFLNK  } = require('iso-constants');
const concat = require('it-concat');
const Headers = require('./pack-headers');
const DMODE = parseInt('755', 8);
const FMODE = parseInt('644', 8);
const END_OF_TAR = Buffer.alloc(1024);
function modeToType(mode) {
    switch(mode & S_IFMT){
        case S_IFBLK:
            return 'block-device';
        case S_IFCHR:
            return 'character-device';
        case S_IFDIR:
            return 'directory';
        case S_IFIFO:
            return 'fifo';
        case S_IFLNK:
            return 'symlink';
    }
    return 'file';
}
function getPadding(size) {
    size &= 511;
    if (size) return new BufferList(END_OF_TAR.slice(0, 512 - size));
}
function encode(header) {
    if (!header.pax) {
        const encoded = Headers.encode(header);
        if (encoded) return encoded;
    }
    return encodePax(header);
}
function encodePax(header) {
    const paxHeader = Headers.encodePax({
        name: header.name,
        linkname: header.linkname,
        pax: header.pax
    });
    const newHeader = {
        name: 'PaxHeader',
        mode: header.mode,
        uid: header.uid,
        gid: header.gid,
        size: paxHeader.length,
        mtime: header.mtime,
        type: 'pax-header',
        linkname: header.linkname && 'PaxHeader',
        uname: header.uname,
        gname: header.gname,
        devmajor: header.devmajor,
        devminor: header.devminor
    };
    return new BufferList([
        Headers.encode(newHeader),
        paxHeader,
        getPadding(paxHeader.length),
        Headers.encode({
            ...newHeader,
            size: header.size,
            type: header.type
        })
    ]);
}
module.exports = ()=>async function*(source) {
        for await (let { header , body  } of source){
            if (!header.size || header.type === 'symlink') header.size = 0;
            if (!header.type) header.type = modeToType(header.mode);
            if (!header.mode) header.mode = header.type === 'directory' ? DMODE : FMODE;
            if (!header.uid) header.uid = 0;
            if (!header.gid) header.gid = 0;
            if (!header.mtime) header.mtime = new Date();
            if (typeof body === 'string') body = Buffer.from(body);
            if (Buffer.isBuffer(body) || BufferList.isBufferList(body)) {
                header.size = body.length;
                yield new BufferList([
                    encode(header),
                    body,
                    getPadding(header.size)
                ]);
                continue;
            }
            if (header.type === 'symlink' && !header.linkname) {
                header.linkname = (await concat(body)).toString();
                yield encode(header);
                continue;
            }
            yield encode(header);
            if (header.type !== 'file' && header.type !== 'contiguous-file') continue;
            let written = 0;
            for await (const chunk of body){
                written += chunk.length;
                yield BufferList.isBufferList(chunk) ? chunk : new BufferList(chunk);
            }
            if (written !== header.size) throw new Error('size mismatch');
            const overflow = getPadding(header.size);
            if (overflow) yield overflow;
        }
        yield new BufferList(END_OF_TAR);
    }
;

},{"buffer":"eKea5","bl/BufferList":"cK5XN","iso-constants":"cRPpS","it-concat":"1MwF2","./pack-headers":"6vZoE"}],"cRPpS":[function(require,module,exports) {
'use strict';
module.exports = {
    'RTLD_LAZY': 1,
    'RTLD_NOW': 2,
    'RTLD_GLOBAL': 256,
    'RTLD_LOCAL': 0,
    'RTLD_DEEPBIND': 8,
    'E2BIG': 7,
    'EACCES': 13,
    'EADDRINUSE': 98,
    'EADDRNOTAVAIL': 99,
    'EAFNOSUPPORT': 97,
    'EAGAIN': 11,
    'EALREADY': 114,
    'EBADF': 9,
    'EBADMSG': 74,
    'EBUSY': 16,
    'ECANCELED': 125,
    'ECHILD': 10,
    'ECONNABORTED': 103,
    'ECONNREFUSED': 111,
    'ECONNRESET': 104,
    'EDEADLK': 35,
    'EDESTADDRREQ': 89,
    'EDOM': 33,
    'EDQUOT': 122,
    'EEXIST': 17,
    'EFAULT': 14,
    'EFBIG': 27,
    'EHOSTUNREACH': 113,
    'EIDRM': 43,
    'EILSEQ': 84,
    'EINPROGRESS': 115,
    'EINTR': 4,
    'EINVAL': 22,
    'EIO': 5,
    'EISCONN': 106,
    'EISDIR': 21,
    'ELOOP': 40,
    'EMFILE': 24,
    'EMLINK': 31,
    'EMSGSIZE': 90,
    'EMULTIHOP': 72,
    'ENAMETOOLONG': 36,
    'ENETDOWN': 100,
    'ENETRESET': 102,
    'ENETUNREACH': 101,
    'ENFILE': 23,
    'ENOBUFS': 105,
    'ENODATA': 61,
    'ENODEV': 19,
    'ENOENT': 2,
    'ENOEXEC': 8,
    'ENOLCK': 37,
    'ENOLINK': 67,
    'ENOMEM': 12,
    'ENOMSG': 42,
    'ENOPROTOOPT': 92,
    'ENOSPC': 28,
    'ENOSR': 63,
    'ENOSTR': 60,
    'ENOSYS': 38,
    'ENOTCONN': 107,
    'ENOTDIR': 20,
    'ENOTEMPTY': 39,
    'ENOTSOCK': 88,
    'ENOTSUP': 95,
    'ENOTTY': 25,
    'ENXIO': 6,
    'EOPNOTSUPP': 95,
    'EOVERFLOW': 75,
    'EPERM': 1,
    'EPIPE': 32,
    'EPROTO': 71,
    'EPROTONOSUPPORT': 93,
    'EPROTOTYPE': 91,
    'ERANGE': 34,
    'EROFS': 30,
    'ESPIPE': 29,
    'ESRCH': 3,
    'ESTALE': 116,
    'ETIME': 62,
    'ETIMEDOUT': 110,
    'ETXTBSY': 26,
    'EWOULDBLOCK': 11,
    'EXDEV': 18,
    'PRIORITY_LOW': 19,
    'PRIORITY_BELOW_NORMAL': 10,
    'PRIORITY_NORMAL': 0,
    'PRIORITY_ABOVE_NORMAL': -7,
    'PRIORITY_HIGH': -14,
    'PRIORITY_HIGHEST': -20,
    'SIGHUP': 1,
    'SIGINT': 2,
    'SIGQUIT': 3,
    'SIGILL': 4,
    'SIGTRAP': 5,
    'SIGABRT': 6,
    'SIGIOT': 6,
    'SIGBUS': 7,
    'SIGFPE': 8,
    'SIGKILL': 9,
    'SIGUSR1': 10,
    'SIGSEGV': 11,
    'SIGUSR2': 12,
    'SIGPIPE': 13,
    'SIGALRM': 14,
    'SIGTERM': 15,
    'SIGCHLD': 17,
    'SIGSTKFLT': 16,
    'SIGCONT': 18,
    'SIGSTOP': 19,
    'SIGTSTP': 20,
    'SIGTTIN': 21,
    'SIGTTOU': 22,
    'SIGURG': 23,
    'SIGXCPU': 24,
    'SIGXFSZ': 25,
    'SIGVTALRM': 26,
    'SIGPROF': 27,
    'SIGWINCH': 28,
    'SIGIO': 29,
    'SIGPOLL': 29,
    'SIGPWR': 30,
    'SIGSYS': 31,
    'SIGUNUSED': 31,
    'UV_FS_SYMLINK_DIR': 1,
    'UV_FS_SYMLINK_JUNCTION': 2,
    'O_RDONLY': 0,
    'O_WRONLY': 1,
    'O_RDWR': 2,
    'UV_DIRENT_UNKNOWN': 0,
    'UV_DIRENT_FILE': 1,
    'UV_DIRENT_DIR': 2,
    'UV_DIRENT_LINK': 3,
    'UV_DIRENT_FIFO': 4,
    'UV_DIRENT_SOCKET': 5,
    'UV_DIRENT_CHAR': 6,
    'UV_DIRENT_BLOCK': 7,
    'S_IFMT': 61440,
    'S_IFREG': 32768,
    'S_IFDIR': 16384,
    'S_IFCHR': 8192,
    'S_IFBLK': 24576,
    'S_IFIFO': 4096,
    'S_IFLNK': 40960,
    'S_IFSOCK': 49152,
    'O_CREAT': 64,
    'O_EXCL': 128,
    'UV_FS_O_FILEMAP': 0,
    'O_NOCTTY': 256,
    'O_TRUNC': 512,
    'O_APPEND': 1024,
    'O_DIRECTORY': 65536,
    'O_NOATIME': 262144,
    'O_NOFOLLOW': 131072,
    'O_SYNC': 1052672,
    'O_DSYNC': 4096,
    'O_DIRECT': 16384,
    'O_NONBLOCK': 2048,
    'S_IRWXU': 448,
    'S_IRUSR': 256,
    'S_IWUSR': 128,
    'S_IXUSR': 64,
    'S_IRWXG': 56,
    'S_IRGRP': 32,
    'S_IWGRP': 16,
    'S_IXGRP': 8,
    'S_IRWXO': 7,
    'S_IROTH': 4,
    'S_IWOTH': 2,
    'S_IXOTH': 1,
    'F_OK': 0,
    'R_OK': 4,
    'W_OK': 2,
    'X_OK': 1,
    'UV_FS_COPYFILE_EXCL': 1,
    'COPYFILE_EXCL': 1,
    'UV_FS_COPYFILE_FICLONE': 2,
    'COPYFILE_FICLONE': 2,
    'UV_FS_COPYFILE_FICLONE_FORCE': 4,
    'COPYFILE_FICLONE_FORCE': 4,
    'OPENSSL_VERSION_NUMBER': 269488319,
    'SSL_OP_ALL': 2147485780,
    'SSL_OP_ALLOW_NO_DHE_KEX': 1024,
    'SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION': 262144,
    'SSL_OP_CIPHER_SERVER_PREFERENCE': 4194304,
    'SSL_OP_CISCO_ANYCONNECT': 32768,
    'SSL_OP_COOKIE_EXCHANGE': 8192,
    'SSL_OP_CRYPTOPRO_TLSEXT_BUG': 2147483648,
    'SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS': 2048,
    'SSL_OP_EPHEMERAL_RSA': 0,
    'SSL_OP_LEGACY_SERVER_CONNECT': 4,
    'SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER': 0,
    'SSL_OP_MICROSOFT_SESS_ID_BUG': 0,
    'SSL_OP_MSIE_SSLV2_RSA_PADDING': 0,
    'SSL_OP_NETSCAPE_CA_DN_BUG': 0,
    'SSL_OP_NETSCAPE_CHALLENGE_BUG': 0,
    'SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG': 0,
    'SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG': 0,
    'SSL_OP_NO_COMPRESSION': 131072,
    'SSL_OP_NO_ENCRYPT_THEN_MAC': 524288,
    'SSL_OP_NO_QUERY_MTU': 4096,
    'SSL_OP_NO_RENEGOTIATION': 1073741824,
    'SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION': 65536,
    'SSL_OP_NO_SSLv2': 0,
    'SSL_OP_NO_SSLv3': 33554432,
    'SSL_OP_NO_TICKET': 16384,
    'SSL_OP_NO_TLSv1': 67108864,
    'SSL_OP_NO_TLSv1_1': 268435456,
    'SSL_OP_NO_TLSv1_2': 134217728,
    'SSL_OP_NO_TLSv1_3': 536870912,
    'SSL_OP_PKCS1_CHECK_1': 0,
    'SSL_OP_PKCS1_CHECK_2': 0,
    'SSL_OP_PRIORITIZE_CHACHA': 2097152,
    'SSL_OP_SINGLE_DH_USE': 0,
    'SSL_OP_SINGLE_ECDH_USE': 0,
    'SSL_OP_SSLEAY_080_CLIENT_DH_BUG': 0,
    'SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG': 0,
    'SSL_OP_TLS_BLOCK_PADDING_BUG': 0,
    'SSL_OP_TLS_D5_BUG': 0,
    'SSL_OP_TLS_ROLLBACK_BUG': 8388608,
    'ENGINE_METHOD_RSA': 1,
    'ENGINE_METHOD_DSA': 2,
    'ENGINE_METHOD_DH': 4,
    'ENGINE_METHOD_RAND': 8,
    'ENGINE_METHOD_EC': 2048,
    'ENGINE_METHOD_CIPHERS': 64,
    'ENGINE_METHOD_DIGESTS': 128,
    'ENGINE_METHOD_PKEY_METHS': 512,
    'ENGINE_METHOD_PKEY_ASN1_METHS': 1024,
    'ENGINE_METHOD_ALL': 65535,
    'ENGINE_METHOD_NONE': 0,
    'DH_CHECK_P_NOT_SAFE_PRIME': 2,
    'DH_CHECK_P_NOT_PRIME': 1,
    'DH_UNABLE_TO_CHECK_GENERATOR': 4,
    'DH_NOT_SUITABLE_GENERATOR': 8,
    'ALPN_ENABLED': 1,
    'RSA_PKCS1_PADDING': 1,
    'RSA_SSLV23_PADDING': 2,
    'RSA_NO_PADDING': 3,
    'RSA_PKCS1_OAEP_PADDING': 4,
    'RSA_X931_PADDING': 5,
    'RSA_PKCS1_PSS_PADDING': 6,
    'RSA_PSS_SALTLEN_DIGEST': -1,
    'RSA_PSS_SALTLEN_MAX_SIGN': -2,
    'RSA_PSS_SALTLEN_AUTO': -2,
    'defaultCoreCipherList': 'TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA256:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!SRP:!CAMELLIA',
    'TLS1_VERSION': 769,
    'TLS1_1_VERSION': 770,
    'TLS1_2_VERSION': 771,
    'TLS1_3_VERSION': 772,
    'POINT_CONVERSION_COMPRESSED': 2,
    'POINT_CONVERSION_UNCOMPRESSED': 4,
    'POINT_CONVERSION_HYBRID': 6
};

},{}],"1MwF2":[function(require,module,exports) {
const BufferList = require('bl/BufferList');
const TypeDefault = {
    string: ()=>''
    ,
    buffer: ()=>BufferList()
};
module.exports = async (source, options)=>{
    options = options || {
    };
    if (options.type && !TypeDefault[options.type]) throw new Error(`invalid type "${options.type}"`);
    let res, type;
    for await (const chunk of source){
        if (!res) {
            type = options.type || (typeof chunk === 'string' ? 'string' : 'buffer');
            res = TypeDefault[type]();
        }
        if (type === 'string') res += chunk;
        else res.append(chunk);
    }
    return res || TypeDefault[options.type || 'buffer']();
};

},{"bl/BufferList":"cK5XN"}],"6vZoE":[function(require,module,exports) {
const { Buffer  } = require('buffer');
const alloc = Buffer.alloc;
const ZEROS = '0000000000000000000';
const SEVENS = '7777777777777777777';
const ZERO_OFFSET = '0'.charCodeAt(0);
const USTAR_MAGIC = Buffer.from('ustar\x00', 'binary');
const USTAR_VER = Buffer.from('00', 'binary');
const MASK = parseInt('7777', 8);
const MAGIC_OFFSET = 257;
const VERSION_OFFSET = 263;
const toTypeflag = function(flag) {
    switch(flag){
        case 'file':
            return 0;
        case 'link':
            return 1;
        case 'symlink':
            return 2;
        case 'character-device':
            return 3;
        case 'block-device':
            return 4;
        case 'directory':
            return 5;
        case 'fifo':
            return 6;
        case 'contiguous-file':
            return 7;
        case 'pax-header':
            return 72;
    }
    return 0;
};
const cksum = function(block) {
    let sum = 256;
    for(let i = 0; i < 148; i++)sum += block[i];
    for(let j = 156; j < 512; j++)sum += block[j];
    return sum;
};
const encodeOct = function(val, n) {
    val = val.toString(8);
    if (val.length > n) return SEVENS.slice(0, n) + ' ';
    else return ZEROS.slice(0, n - val.length) + val + ' ';
};
const addLength = function(str) {
    const len = Buffer.byteLength(str);
    let digits = Math.floor(Math.log(len) / Math.log(10)) + 1;
    if (len + digits >= Math.pow(10, digits)) digits++;
    return len + digits + str;
};
exports.encodePax = function(opts) {
    let result = '';
    if (opts.name) result += addLength(' path=' + opts.name + '\n');
    if (opts.linkname) result += addLength(' linkpath=' + opts.linkname + '\n');
    const pax = opts.pax;
    if (pax) for(const key in pax)result += addLength(' ' + key + '=' + pax[key] + '\n');
    return Buffer.from(result);
};
exports.encode = function(opts) {
    const buf = alloc(512);
    let name = opts.name;
    let prefix = '';
    if (opts.typeflag === 5 && name[name.length - 1] !== '/') name += '/';
    if (Buffer.byteLength(name) !== name.length) return null // utf-8
    ;
    while(Buffer.byteLength(name) > 100){
        const i = name.indexOf('/');
        if (i === -1) return null;
        prefix += prefix ? '/' + name.slice(0, i) : name.slice(0, i);
        name = name.slice(i + 1);
    }
    if (Buffer.byteLength(name) > 100 || Buffer.byteLength(prefix) > 155) return null;
    if (opts.linkname && Buffer.byteLength(opts.linkname) > 100) return null;
    buf.write(name);
    buf.write(encodeOct(opts.mode & MASK, 6), 100);
    buf.write(encodeOct(opts.uid, 6), 108);
    buf.write(encodeOct(opts.gid, 6), 116);
    buf.write(encodeOct(opts.size, 11), 124);
    buf.write(encodeOct(opts.mtime.getTime() / 1000 | 0, 11), 136);
    buf[156] = ZERO_OFFSET + toTypeflag(opts.type);
    if (opts.linkname) buf.write(opts.linkname, 157);
    USTAR_MAGIC.copy(buf, MAGIC_OFFSET);
    USTAR_VER.copy(buf, VERSION_OFFSET);
    if (opts.uname) buf.write(opts.uname, 265);
    if (opts.gname) buf.write(opts.gname, 297);
    buf.write(encodeOct(opts.devmajor || 0, 6), 329);
    buf.write(encodeOct(opts.devminor || 0, 6), 337);
    if (prefix) buf.write(prefix, 345);
    buf.write(encodeOct(cksum(buf), 6), 148);
    return buf;
};

},{"buffer":"eKea5"}],"jntDO":[function(require,module,exports) {
// Top level file is just a mixin of submodules & constants
'use strict';
var assign = require('./lib/utils/common').assign;
var deflate = require('./lib/deflate');
var inflate = require('./lib/inflate');
var constants = require('./lib/zlib/constants');
var pako = {
};
assign(pako, deflate, inflate, constants);
module.exports = pako;

},{"./lib/utils/common":"2FpJl","./lib/deflate":"y5tSb","./lib/inflate":"gcpcv","./lib/zlib/constants":"dfW1p"}],"2FpJl":[function(require,module,exports) {
'use strict';
var TYPED_OK = typeof Uint8Array !== 'undefined' && typeof Uint16Array !== 'undefined' && typeof Int32Array !== 'undefined';
function _has(obj, key) {
    return Object.prototype.hasOwnProperty.call(obj, key);
}
exports.assign = function(obj /*from1, from2, from3, ...*/ ) {
    var sources = Array.prototype.slice.call(arguments, 1);
    while(sources.length){
        var source = sources.shift();
        if (!source) continue;
        if (typeof source !== 'object') throw new TypeError(source + 'must be non-object');
        for(var p in source)if (_has(source, p)) obj[p] = source[p];
    }
    return obj;
};
// reduce buffer size, avoiding mem copy
exports.shrinkBuf = function(buf, size) {
    if (buf.length === size) return buf;
    if (buf.subarray) return buf.subarray(0, size);
    buf.length = size;
    return buf;
};
var fnTyped = {
    arraySet: function(dest, src, src_offs, len, dest_offs) {
        if (src.subarray && dest.subarray) {
            dest.set(src.subarray(src_offs, src_offs + len), dest_offs);
            return;
        }
        // Fallback to ordinary array
        for(var i = 0; i < len; i++)dest[dest_offs + i] = src[src_offs + i];
    },
    // Join array of chunks to single array.
    flattenChunks: function(chunks) {
        var i, l, len, pos, chunk, result;
        // calculate data length
        len = 0;
        for(i = 0, l = chunks.length; i < l; i++)len += chunks[i].length;
        // join chunks
        result = new Uint8Array(len);
        pos = 0;
        for(i = 0, l = chunks.length; i < l; i++){
            chunk = chunks[i];
            result.set(chunk, pos);
            pos += chunk.length;
        }
        return result;
    }
};
var fnUntyped = {
    arraySet: function(dest, src, src_offs, len, dest_offs) {
        for(var i = 0; i < len; i++)dest[dest_offs + i] = src[src_offs + i];
    },
    // Join array of chunks to single array.
    flattenChunks: function(chunks) {
        return [].concat.apply([], chunks);
    }
};
// Enable/Disable typed arrays use, for testing
//
exports.setTyped = function(on) {
    if (on) {
        exports.Buf8 = Uint8Array;
        exports.Buf16 = Uint16Array;
        exports.Buf32 = Int32Array;
        exports.assign(exports, fnTyped);
    } else {
        exports.Buf8 = Array;
        exports.Buf16 = Array;
        exports.Buf32 = Array;
        exports.assign(exports, fnUntyped);
    }
};
exports.setTyped(TYPED_OK);

},{}],"y5tSb":[function(require,module,exports) {
'use strict';
var zlib_deflate = require('./zlib/deflate');
var utils = require('./utils/common');
var strings = require('./utils/strings');
var msg = require('./zlib/messages');
var ZStream = require('./zlib/zstream');
var toString = Object.prototype.toString;
/* Public constants ==========================================================*/ /* ===========================================================================*/ var Z_NO_FLUSH = 0;
var Z_FINISH = 4;
var Z_OK = 0;
var Z_STREAM_END = 1;
var Z_SYNC_FLUSH = 2;
var Z_DEFAULT_COMPRESSION = -1;
var Z_DEFAULT_STRATEGY = 0;
var Z_DEFLATED = 8;
/* ===========================================================================*/ /**
 * class Deflate
 *
 * Generic JS-style wrapper for zlib calls. If you don't need
 * streaming behaviour - use more simple functions: [[deflate]],
 * [[deflateRaw]] and [[gzip]].
 **/ /* internal
 * Deflate.chunks -> Array
 *
 * Chunks of output data, if [[Deflate#onData]] not overridden.
 **/ /**
 * Deflate.result -> Uint8Array|Array
 *
 * Compressed result, generated by default [[Deflate#onData]]
 * and [[Deflate#onEnd]] handlers. Filled after you push last chunk
 * (call [[Deflate#push]] with `Z_FINISH` / `true` param)  or if you
 * push a chunk with explicit flush (call [[Deflate#push]] with
 * `Z_SYNC_FLUSH` param).
 **/ /**
 * Deflate.err -> Number
 *
 * Error code after deflate finished. 0 (Z_OK) on success.
 * You will not need it in real life, because deflate errors
 * are possible only on wrong options or bad `onData` / `onEnd`
 * custom handlers.
 **/ /**
 * Deflate.msg -> String
 *
 * Error message, if [[Deflate.err]] != 0
 **/ /**
 * new Deflate(options)
 * - options (Object): zlib deflate options.
 *
 * Creates new deflator instance with specified params. Throws exception
 * on bad params. Supported options:
 *
 * - `level`
 * - `windowBits`
 * - `memLevel`
 * - `strategy`
 * - `dictionary`
 *
 * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)
 * for more information on these.
 *
 * Additional options, for internal needs:
 *
 * - `chunkSize` - size of generated data chunks (16K by default)
 * - `raw` (Boolean) - do raw deflate
 * - `gzip` (Boolean) - create gzip wrapper
 * - `to` (String) - if equal to 'string', then result will be "binary string"
 *    (each char code [0..255])
 * - `header` (Object) - custom header for gzip
 *   - `text` (Boolean) - true if compressed data believed to be text
 *   - `time` (Number) - modification time, unix timestamp
 *   - `os` (Number) - operation system code
 *   - `extra` (Array) - array of bytes with extra data (max 65536)
 *   - `name` (String) - file name (binary string)
 *   - `comment` (String) - comment (binary string)
 *   - `hcrc` (Boolean) - true if header crc should be added
 *
 * ##### Example:
 *
 * ```javascript
 * var pako = require('pako')
 *   , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9])
 *   , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]);
 *
 * var deflate = new pako.Deflate({ level: 3});
 *
 * deflate.push(chunk1, false);
 * deflate.push(chunk2, true);  // true -> last chunk
 *
 * if (deflate.err) { throw new Error(deflate.err); }
 *
 * console.log(deflate.result);
 * ```
 **/ function Deflate(options) {
    if (!(this instanceof Deflate)) return new Deflate(options);
    this.options = utils.assign({
        level: Z_DEFAULT_COMPRESSION,
        method: Z_DEFLATED,
        chunkSize: 16384,
        windowBits: 15,
        memLevel: 8,
        strategy: Z_DEFAULT_STRATEGY,
        to: ''
    }, options || {
    });
    var opt = this.options;
    if (opt.raw && opt.windowBits > 0) opt.windowBits = -opt.windowBits;
    else if (opt.gzip && opt.windowBits > 0 && opt.windowBits < 16) opt.windowBits += 16;
    this.err = 0; // error code, if happens (0 = Z_OK)
    this.msg = ''; // error message
    this.ended = false; // used to avoid multiple onEnd() calls
    this.chunks = []; // chunks of compressed data
    this.strm = new ZStream();
    this.strm.avail_out = 0;
    var status = zlib_deflate.deflateInit2(this.strm, opt.level, opt.method, opt.windowBits, opt.memLevel, opt.strategy);
    if (status !== Z_OK) throw new Error(msg[status]);
    if (opt.header) zlib_deflate.deflateSetHeader(this.strm, opt.header);
    if (opt.dictionary) {
        var dict;
        // Convert data if needed
        if (typeof opt.dictionary === 'string') // If we need to compress text, change encoding to utf8.
        dict = strings.string2buf(opt.dictionary);
        else if (toString.call(opt.dictionary) === '[object ArrayBuffer]') dict = new Uint8Array(opt.dictionary);
        else dict = opt.dictionary;
        status = zlib_deflate.deflateSetDictionary(this.strm, dict);
        if (status !== Z_OK) throw new Error(msg[status]);
        this._dict_set = true;
    }
}
/**
 * Deflate#push(data[, mode]) -> Boolean
 * - data (Uint8Array|Array|ArrayBuffer|String): input data. Strings will be
 *   converted to utf8 byte sequence.
 * - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes.
 *   See constants. Skipped or `false` means Z_NO_FLUSH, `true` means Z_FINISH.
 *
 * Sends input data to deflate pipe, generating [[Deflate#onData]] calls with
 * new compressed chunks. Returns `true` on success. The last data block must have
 * mode Z_FINISH (or `true`). That will flush internal pending buffers and call
 * [[Deflate#onEnd]]. For interim explicit flushes (without ending the stream) you
 * can use mode Z_SYNC_FLUSH, keeping the compression context.
 *
 * On fail call [[Deflate#onEnd]] with error code and return false.
 *
 * We strongly recommend to use `Uint8Array` on input for best speed (output
 * array format is detected automatically). Also, don't skip last param and always
 * use the same type in your code (boolean or number). That will improve JS speed.
 *
 * For regular `Array`-s make sure all elements are [0..255].
 *
 * ##### Example
 *
 * ```javascript
 * push(chunk, false); // push one of data chunks
 * ...
 * push(chunk, true);  // push last chunk
 * ```
 **/ Deflate.prototype.push = function(data, mode) {
    var strm = this.strm;
    var chunkSize = this.options.chunkSize;
    var status, _mode;
    if (this.ended) return false;
    _mode = mode === ~~mode ? mode : mode === true ? Z_FINISH : Z_NO_FLUSH;
    // Convert data if needed
    if (typeof data === 'string') // If we need to compress text, change encoding to utf8.
    strm.input = strings.string2buf(data);
    else if (toString.call(data) === '[object ArrayBuffer]') strm.input = new Uint8Array(data);
    else strm.input = data;
    strm.next_in = 0;
    strm.avail_in = strm.input.length;
    do {
        if (strm.avail_out === 0) {
            strm.output = new utils.Buf8(chunkSize);
            strm.next_out = 0;
            strm.avail_out = chunkSize;
        }
        status = zlib_deflate.deflate(strm, _mode); /* no bad return value */ 
        if (status !== Z_STREAM_END && status !== Z_OK) {
            this.onEnd(status);
            this.ended = true;
            return false;
        }
        if (strm.avail_out === 0 || strm.avail_in === 0 && (_mode === Z_FINISH || _mode === Z_SYNC_FLUSH)) {
            if (this.options.to === 'string') this.onData(strings.buf2binstring(utils.shrinkBuf(strm.output, strm.next_out)));
            else this.onData(utils.shrinkBuf(strm.output, strm.next_out));
        }
    }while ((strm.avail_in > 0 || strm.avail_out === 0) && status !== Z_STREAM_END)
    // Finalize on the last chunk.
    if (_mode === Z_FINISH) {
        status = zlib_deflate.deflateEnd(this.strm);
        this.onEnd(status);
        this.ended = true;
        return status === Z_OK;
    }
    // callback interim results if Z_SYNC_FLUSH.
    if (_mode === Z_SYNC_FLUSH) {
        this.onEnd(Z_OK);
        strm.avail_out = 0;
        return true;
    }
    return true;
};
/**
 * Deflate#onData(chunk) -> Void
 * - chunk (Uint8Array|Array|String): output data. Type of array depends
 *   on js engine support. When string output requested, each chunk
 *   will be string.
 *
 * By default, stores data blocks in `chunks[]` property and glue
 * those in `onEnd`. Override this handler, if you need another behaviour.
 **/ Deflate.prototype.onData = function(chunk) {
    this.chunks.push(chunk);
};
/**
 * Deflate#onEnd(status) -> Void
 * - status (Number): deflate status. 0 (Z_OK) on success,
 *   other if not.
 *
 * Called once after you tell deflate that the input stream is
 * complete (Z_FINISH) or should be flushed (Z_SYNC_FLUSH)
 * or if an error happened. By default - join collected chunks,
 * free memory and fill `results` / `err` properties.
 **/ Deflate.prototype.onEnd = function(status) {
    // On success - join
    if (status === Z_OK) {
        if (this.options.to === 'string') this.result = this.chunks.join('');
        else this.result = utils.flattenChunks(this.chunks);
    }
    this.chunks = [];
    this.err = status;
    this.msg = this.strm.msg;
};
/**
 * deflate(data[, options]) -> Uint8Array|Array|String
 * - data (Uint8Array|Array|String): input data to compress.
 * - options (Object): zlib deflate options.
 *
 * Compress `data` with deflate algorithm and `options`.
 *
 * Supported options are:
 *
 * - level
 * - windowBits
 * - memLevel
 * - strategy
 * - dictionary
 *
 * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)
 * for more information on these.
 *
 * Sugar (options):
 *
 * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify
 *   negative windowBits implicitly.
 * - `to` (String) - if equal to 'string', then result will be "binary string"
 *    (each char code [0..255])
 *
 * ##### Example:
 *
 * ```javascript
 * var pako = require('pako')
 *   , data = Uint8Array([1,2,3,4,5,6,7,8,9]);
 *
 * console.log(pako.deflate(data));
 * ```
 **/ function deflate(input, options) {
    var deflator = new Deflate(options);
    deflator.push(input, true);
    // That will never happens, if you don't cheat with options :)
    if (deflator.err) throw deflator.msg || msg[deflator.err];
    return deflator.result;
}
/**
 * deflateRaw(data[, options]) -> Uint8Array|Array|String
 * - data (Uint8Array|Array|String): input data to compress.
 * - options (Object): zlib deflate options.
 *
 * The same as [[deflate]], but creates raw data, without wrapper
 * (header and adler32 crc).
 **/ function deflateRaw(input, options) {
    options = options || {
    };
    options.raw = true;
    return deflate(input, options);
}
/**
 * gzip(data[, options]) -> Uint8Array|Array|String
 * - data (Uint8Array|Array|String): input data to compress.
 * - options (Object): zlib deflate options.
 *
 * The same as [[deflate]], but create gzip wrapper instead of
 * deflate one.
 **/ function gzip(input, options) {
    options = options || {
    };
    options.gzip = true;
    return deflate(input, options);
}
exports.Deflate = Deflate;
exports.deflate = deflate;
exports.deflateRaw = deflateRaw;
exports.gzip = gzip;

},{"./zlib/deflate":"lXfaV","./utils/common":"2FpJl","./utils/strings":"eOURD","./zlib/messages":"4MwdS","./zlib/zstream":"8r8Eg"}],"lXfaV":[function(require,module,exports) {
'use strict';
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
//   claim that you wrote the original software. If you use this software
//   in a product, an acknowledgment in the product documentation would be
//   appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
//   misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
var utils = require('../utils/common');
var trees = require('./trees');
var adler32 = require('./adler32');
var crc32 = require('./crc32');
var msg = require('./messages');
/* Public constants ==========================================================*/ /* ===========================================================================*/ /* Allowed flush values; see deflate() and inflate() below for details */ var Z_NO_FLUSH = 0;
var Z_PARTIAL_FLUSH = 1;
//var Z_SYNC_FLUSH    = 2;
var Z_FULL_FLUSH = 3;
var Z_FINISH = 4;
var Z_BLOCK = 5;
//var Z_TREES         = 6;
/* Return codes for the compression/decompression functions. Negative values
 * are errors, positive values are used for special but normal events.
 */ var Z_OK = 0;
var Z_STREAM_END = 1;
//var Z_NEED_DICT     = 2;
//var Z_ERRNO         = -1;
var Z_STREAM_ERROR = -2;
var Z_DATA_ERROR = -3;
//var Z_MEM_ERROR     = -4;
var Z_BUF_ERROR = -5;
//var Z_VERSION_ERROR = -6;
/* compression levels */ //var Z_NO_COMPRESSION      = 0;
//var Z_BEST_SPEED          = 1;
//var Z_BEST_COMPRESSION    = 9;
var Z_DEFAULT_COMPRESSION = -1;
var Z_FILTERED = 1;
var Z_HUFFMAN_ONLY = 2;
var Z_RLE = 3;
var Z_FIXED = 4;
var Z_DEFAULT_STRATEGY = 0;
/* Possible values of the data_type field (though see inflate()) */ //var Z_BINARY              = 0;
//var Z_TEXT                = 1;
//var Z_ASCII               = 1; // = Z_TEXT
var Z_UNKNOWN = 2;
/* The deflate compression method */ var Z_DEFLATED = 8;
/*============================================================================*/ var MAX_MEM_LEVEL = 9;
/* Maximum value for memLevel in deflateInit2 */ var MAX_WBITS = 15;
/* 32K LZ77 window */ var DEF_MEM_LEVEL = 8;
var LENGTH_CODES = 29;
/* number of length codes, not counting the special END_BLOCK code */ var LITERALS = 256;
/* number of literal bytes 0..255 */ var L_CODES = LITERALS + 1 + LENGTH_CODES;
/* number of Literal or Length codes, including the END_BLOCK code */ var D_CODES = 30;
/* number of distance codes */ var BL_CODES = 19;
/* number of codes used to transfer the bit lengths */ var HEAP_SIZE = 2 * L_CODES + 1;
/* maximum heap size */ var MAX_BITS = 15;
/* All codes must not exceed MAX_BITS bits */ var MIN_MATCH = 3;
var MAX_MATCH = 258;
var MIN_LOOKAHEAD = MAX_MATCH + MIN_MATCH + 1;
var PRESET_DICT = 32;
var INIT_STATE = 42;
var EXTRA_STATE = 69;
var NAME_STATE = 73;
var COMMENT_STATE = 91;
var HCRC_STATE = 103;
var BUSY_STATE = 113;
var FINISH_STATE = 666;
var BS_NEED_MORE = 1; /* block not completed, need more input or more output */ 
var BS_BLOCK_DONE = 2; /* block flush performed */ 
var BS_FINISH_STARTED = 3; /* finish started, need only more output at next deflate */ 
var BS_FINISH_DONE = 4; /* finish done, accept no more input or output */ 
var OS_CODE = 3; // Unix :) . Don't detect, use this default.
function err(strm, errorCode) {
    strm.msg = msg[errorCode];
    return errorCode;
}
function rank(f) {
    return (f << 1) - (f > 4 ? 9 : 0);
}
function zero(buf) {
    var len = buf.length;
    while(--len >= 0)buf[len] = 0;
}
/* =========================================================================
 * Flush as much pending output as possible. All deflate() output goes
 * through this function so some applications may wish to modify it
 * to avoid allocating a large strm->output buffer and copying into it.
 * (See also read_buf()).
 */ function flush_pending(strm) {
    var s = strm.state;
    //_tr_flush_bits(s);
    var len = s.pending;
    if (len > strm.avail_out) len = strm.avail_out;
    if (len === 0) return;
    utils.arraySet(strm.output, s.pending_buf, s.pending_out, len, strm.next_out);
    strm.next_out += len;
    s.pending_out += len;
    strm.total_out += len;
    strm.avail_out -= len;
    s.pending -= len;
    if (s.pending === 0) s.pending_out = 0;
}
function flush_block_only(s, last) {
    trees._tr_flush_block(s, s.block_start >= 0 ? s.block_start : -1, s.strstart - s.block_start, last);
    s.block_start = s.strstart;
    flush_pending(s.strm);
}
function put_byte(s, b) {
    s.pending_buf[s.pending++] = b;
}
/* =========================================================================
 * Put a short in the pending buffer. The 16-bit value is put in MSB order.
 * IN assertion: the stream state is correct and there is enough room in
 * pending_buf.
 */ function putShortMSB(s, b) {
    //  put_byte(s, (Byte)(b >> 8));
    //  put_byte(s, (Byte)(b & 0xff));
    s.pending_buf[s.pending++] = b >>> 8 & 255;
    s.pending_buf[s.pending++] = b & 255;
}
/* ===========================================================================
 * Read a new buffer from the current input stream, update the adler32
 * and total number of bytes read.  All deflate() input goes through
 * this function so some applications may wish to modify it to avoid
 * allocating a large strm->input buffer and copying from it.
 * (See also flush_pending()).
 */ function read_buf(strm, buf, start, size) {
    var len = strm.avail_in;
    if (len > size) len = size;
    if (len === 0) return 0;
    strm.avail_in -= len;
    // zmemcpy(buf, strm->next_in, len);
    utils.arraySet(buf, strm.input, strm.next_in, len, start);
    if (strm.state.wrap === 1) strm.adler = adler32(strm.adler, buf, len, start);
    else if (strm.state.wrap === 2) strm.adler = crc32(strm.adler, buf, len, start);
    strm.next_in += len;
    strm.total_in += len;
    return len;
}
/* ===========================================================================
 * Set match_start to the longest match starting at the given string and
 * return its length. Matches shorter or equal to prev_length are discarded,
 * in which case the result is equal to prev_length and match_start is
 * garbage.
 * IN assertions: cur_match is the head of the hash chain for the current
 *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
 * OUT assertion: the match length is not greater than s->lookahead.
 */ function longest_match(s, cur_match) {
    var chain_length = s.max_chain_length; /* max hash chain length */ 
    var scan = s.strstart; /* current string */ 
    var match; /* matched string */ 
    var len; /* length of current match */ 
    var best_len = s.prev_length; /* best match length so far */ 
    var nice_match = s.nice_match; /* stop if match long enough */ 
    var limit = s.strstart > s.w_size - MIN_LOOKAHEAD ? s.strstart - (s.w_size - MIN_LOOKAHEAD) : 0 /*NIL*/ ;
    var _win = s.window; // shortcut
    var wmask = s.w_mask;
    var prev = s.prev;
    /* Stop when cur_match becomes <= limit. To simplify the code,
   * we prevent matches with the string of window index 0.
   */ var strend = s.strstart + MAX_MATCH;
    var scan_end1 = _win[scan + best_len - 1];
    var scan_end = _win[scan + best_len];
    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
   * It is easy to get rid of this optimization if necessary.
   */ // Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
    /* Do not waste too much time if we already have a good match: */ if (s.prev_length >= s.good_match) chain_length >>= 2;
    /* Do not look for matches beyond the end of the input. This is necessary
   * to make deflate deterministic.
   */ if (nice_match > s.lookahead) nice_match = s.lookahead;
    // Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
    do {
        // Assert(cur_match < s->strstart, "no future");
        match = cur_match;
        /* Skip to next match if the match length cannot increase
     * or if the match length is less than 2.  Note that the checks below
     * for insufficient lookahead only occur occasionally for performance
     * reasons.  Therefore uninitialized memory will be accessed, and
     * conditional jumps will be made that depend on those values.
     * However the length of the match is limited to the lookahead, so
     * the output of deflate is not affected by the uninitialized values.
     */ if (_win[match + best_len] !== scan_end || _win[match + best_len - 1] !== scan_end1 || _win[match] !== _win[scan] || _win[++match] !== _win[scan + 1]) continue;
        /* The check at best_len-1 can be removed because it will be made
     * again later. (This heuristic is not always a win.)
     * It is not necessary to compare scan[2] and match[2] since they
     * are always equal when the other bytes match, given that
     * the hash keys are equal and that HASH_BITS >= 8.
     */ scan += 2;
        match++;
        // Assert(*scan == *match, "match[2]?");
        /* We check for insufficient lookahead only every 8th comparison;
     * the 256th check will be made at strstart+258.
     */ do ;
        while (_win[++scan] === _win[++match] && _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && scan < strend)
        // Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
        len = MAX_MATCH - (strend - scan);
        scan = strend - MAX_MATCH;
        if (len > best_len) {
            s.match_start = cur_match;
            best_len = len;
            if (len >= nice_match) break;
            scan_end1 = _win[scan + best_len - 1];
            scan_end = _win[scan + best_len];
        }
    }while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length !== 0)
    if (best_len <= s.lookahead) return best_len;
    return s.lookahead;
}
/* ===========================================================================
 * Fill the window when the lookahead becomes insufficient.
 * Updates strstart and lookahead.
 *
 * IN assertion: lookahead < MIN_LOOKAHEAD
 * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
 *    At least one byte has been read, or avail_in == 0; reads are
 *    performed for at least two bytes (required for the zip translate_eol
 *    option -- not supported here).
 */ function fill_window(s) {
    var _w_size = s.w_size;
    var p, n, m, more, str;
    //Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead");
    do {
        more = s.window_size - s.lookahead - s.strstart;
        // JS ints have 32 bit, block below not needed
        /* Deal with !@#$% 64K limit: */ //if (sizeof(int) <= 2) {
        //    if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
        //        more = wsize;
        //
        //  } else if (more == (unsigned)(-1)) {
        //        /* Very unlikely, but possible on 16 bit machine if
        //         * strstart == 0 && lookahead == 1 (input done a byte at time)
        //         */
        //        more--;
        //    }
        //}
        /* If the window is almost full and there is insufficient lookahead,
     * move the upper half to the lower one to make room in the upper half.
     */ if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD)) {
            utils.arraySet(s.window, s.window, _w_size, _w_size, 0);
            s.match_start -= _w_size;
            s.strstart -= _w_size;
            /* we now have strstart >= MAX_DIST */ s.block_start -= _w_size;
            /* Slide the hash table (could be avoided with 32 bit values
       at the expense of memory usage). We slide even when level == 0
       to keep the hash table consistent if we switch back to level > 0
       later. (Using level 0 permanently is not an optimal usage of
       zlib, so we don't care about this pathological case.)
       */ n = s.hash_size;
            p = n;
            do {
                m = s.head[--p];
                s.head[p] = m >= _w_size ? m - _w_size : 0;
            }while (--n)
            n = _w_size;
            p = n;
            do {
                m = s.prev[--p];
                s.prev[p] = m >= _w_size ? m - _w_size : 0;
            /* If n is not on any hash chain, prev[n] is garbage but
         * its value will never be used.
         */ }while (--n)
            more += _w_size;
        }
        if (s.strm.avail_in === 0) break;
        /* If there was no sliding:
     *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
     *    more == window_size - lookahead - strstart
     * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
     * => more >= window_size - 2*WSIZE + 2
     * In the BIG_MEM or MMAP case (not yet supported),
     *   window_size == input_size + MIN_LOOKAHEAD  &&
     *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
     * Otherwise, window_size == 2*WSIZE so more >= 2.
     * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
     */ //Assert(more >= 2, "more < 2");
        n = read_buf(s.strm, s.window, s.strstart + s.lookahead, more);
        s.lookahead += n;
        /* Initialize the hash value now that we have some input: */ if (s.lookahead + s.insert >= MIN_MATCH) {
            str = s.strstart - s.insert;
            s.ins_h = s.window[str];
            /* UPDATE_HASH(s, s->ins_h, s->window[str + 1]); */ s.ins_h = (s.ins_h << s.hash_shift ^ s.window[str + 1]) & s.hash_mask;
            //#if MIN_MATCH != 3
            //        Call update_hash() MIN_MATCH-3 more times
            //#endif
            while(s.insert){
                /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */ s.ins_h = (s.ins_h << s.hash_shift ^ s.window[str + MIN_MATCH - 1]) & s.hash_mask;
                s.prev[str & s.w_mask] = s.head[s.ins_h];
                s.head[s.ins_h] = str;
                str++;
                s.insert--;
                if (s.lookahead + s.insert < MIN_MATCH) break;
            }
        }
    /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
     * but this is not important since only literal bytes will be emitted.
     */ }while (s.lookahead < MIN_LOOKAHEAD && s.strm.avail_in !== 0)
/* If the WIN_INIT bytes after the end of the current data have never been
   * written, then zero those bytes in order to avoid memory check reports of
   * the use of uninitialized (or uninitialised as Julian writes) bytes by
   * the longest match routines.  Update the high water mark for the next
   * time through here.  WIN_INIT is set to MAX_MATCH since the longest match
   * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.
   */ //  if (s.high_water < s.window_size) {
//    var curr = s.strstart + s.lookahead;
//    var init = 0;
//
//    if (s.high_water < curr) {
//      /* Previous high water mark below current data -- zero WIN_INIT
//       * bytes or up to end of window, whichever is less.
//       */
//      init = s.window_size - curr;
//      if (init > WIN_INIT)
//        init = WIN_INIT;
//      zmemzero(s->window + curr, (unsigned)init);
//      s->high_water = curr + init;
//    }
//    else if (s->high_water < (ulg)curr + WIN_INIT) {
//      /* High water mark at or above current data, but below current data
//       * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
//       * to end of window, whichever is less.
//       */
//      init = (ulg)curr + WIN_INIT - s->high_water;
//      if (init > s->window_size - s->high_water)
//        init = s->window_size - s->high_water;
//      zmemzero(s->window + s->high_water, (unsigned)init);
//      s->high_water += init;
//    }
//  }
//
//  Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
//    "not enough room for search");
}
/* ===========================================================================
 * Copy without compression as much as possible from the input stream, return
 * the current block state.
 * This function does not insert new strings in the dictionary since
 * uncompressible data is probably not useful. This function is used
 * only for the level=0 compression option.
 * NOTE: this function should be optimized to avoid extra copying from
 * window to pending_buf.
 */ function deflate_stored(s, flush) {
    /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
   * to pending_buf_size, and each stored block has a 5 byte header:
   */ var max_block_size = 65535;
    if (max_block_size > s.pending_buf_size - 5) max_block_size = s.pending_buf_size - 5;
    /* Copy as much as possible from input to output: */ for(;;){
        /* Fill the window as much as possible: */ if (s.lookahead <= 1) {
            //Assert(s->strstart < s->w_size+MAX_DIST(s) ||
            //  s->block_start >= (long)s->w_size, "slide too late");
            //      if (!(s.strstart < s.w_size + (s.w_size - MIN_LOOKAHEAD) ||
            //        s.block_start >= s.w_size)) {
            //        throw  new Error("slide too late");
            //      }
            fill_window(s);
            if (s.lookahead === 0 && flush === Z_NO_FLUSH) return BS_NEED_MORE;
            if (s.lookahead === 0) break;
        /* flush the current block */ }
        //Assert(s->block_start >= 0L, "block gone");
        //    if (s.block_start < 0) throw new Error("block gone");
        s.strstart += s.lookahead;
        s.lookahead = 0;
        /* Emit a stored block if pending_buf will be full: */ var max_start = s.block_start + max_block_size;
        if (s.strstart === 0 || s.strstart >= max_start) {
            /* strstart == 0 is possible when wraparound on 16-bit machine */ s.lookahead = s.strstart - max_start;
            s.strstart = max_start;
            /*** FLUSH_BLOCK(s, 0); ***/ flush_block_only(s, false);
            if (s.strm.avail_out === 0) return BS_NEED_MORE;
        /***/ }
        /* Flush if we may have to slide, otherwise block_start may become
     * negative and the data will be gone:
     */ if (s.strstart - s.block_start >= s.w_size - MIN_LOOKAHEAD) {
            /*** FLUSH_BLOCK(s, 0); ***/ flush_block_only(s, false);
            if (s.strm.avail_out === 0) return BS_NEED_MORE;
        /***/ }
    }
    s.insert = 0;
    if (flush === Z_FINISH) {
        /*** FLUSH_BLOCK(s, 1); ***/ flush_block_only(s, true);
        if (s.strm.avail_out === 0) return BS_FINISH_STARTED;
        /***/ return BS_FINISH_DONE;
    }
    if (s.strstart > s.block_start) {
        /*** FLUSH_BLOCK(s, 0); ***/ flush_block_only(s, false);
        if (s.strm.avail_out === 0) return BS_NEED_MORE;
    /***/ }
    return BS_NEED_MORE;
}
/* ===========================================================================
 * Compress as much as possible from the input stream, return the current
 * block state.
 * This function does not perform lazy evaluation of matches and inserts
 * new strings in the dictionary only for unmatched strings or for short
 * matches. It is used only for the fast compression options.
 */ function deflate_fast(s, flush) {
    var hash_head; /* head of the hash chain */ 
    var bflush; /* set if current block must be flushed */ 
    for(;;){
        /* Make sure that we always have enough lookahead, except
     * at the end of the input file. We need MAX_MATCH bytes
     * for the next match, plus MIN_MATCH bytes to insert the
     * string following the next match.
     */ if (s.lookahead < MIN_LOOKAHEAD) {
            fill_window(s);
            if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) return BS_NEED_MORE;
            if (s.lookahead === 0) break; /* flush the current block */ 
        }
        /* Insert the string window[strstart .. strstart+2] in the
     * dictionary, and set hash_head to the head of the hash chain:
     */ hash_head = 0 /*NIL*/ ;
        if (s.lookahead >= MIN_MATCH) {
            /*** INSERT_STRING(s, s.strstart, hash_head); ***/ s.ins_h = (s.ins_h << s.hash_shift ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;
            hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
            s.head[s.ins_h] = s.strstart;
        /***/ }
        /* Find the longest match, discarding those <= prev_length.
     * At this point we have always match_length < MIN_MATCH
     */ if (hash_head !== 0 /*NIL*/  && s.strstart - hash_head <= s.w_size - MIN_LOOKAHEAD) /* To simplify the code, we prevent matches with the string
       * of window index 0 (in particular we have to avoid a match
       * of the string with itself at the start of the input file).
       */ s.match_length = longest_match(s, hash_head);
        if (s.match_length >= MIN_MATCH) {
            // check_match(s, s.strstart, s.match_start, s.match_length); // for debug only
            /*** _tr_tally_dist(s, s.strstart - s.match_start,
                     s.match_length - MIN_MATCH, bflush); ***/ bflush = trees._tr_tally(s, s.strstart - s.match_start, s.match_length - MIN_MATCH);
            s.lookahead -= s.match_length;
            /* Insert new strings in the hash table only if the match length
       * is not too large. This saves time but degrades compression.
       */ if (s.match_length <= s.max_lazy_match /*max_insert_length*/  && s.lookahead >= MIN_MATCH) {
                s.match_length--; /* string at strstart already in table */ 
                do {
                    s.strstart++;
                    /*** INSERT_STRING(s, s.strstart, hash_head); ***/ s.ins_h = (s.ins_h << s.hash_shift ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;
                    hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
                    s.head[s.ins_h] = s.strstart;
                /***/ /* strstart never exceeds WSIZE-MAX_MATCH, so there are
           * always MIN_MATCH bytes ahead.
           */ }while (--s.match_length !== 0)
                s.strstart++;
            } else {
                s.strstart += s.match_length;
                s.match_length = 0;
                s.ins_h = s.window[s.strstart];
                /* UPDATE_HASH(s, s.ins_h, s.window[s.strstart+1]); */ s.ins_h = (s.ins_h << s.hash_shift ^ s.window[s.strstart + 1]) & s.hash_mask;
            //#if MIN_MATCH != 3
            //                Call UPDATE_HASH() MIN_MATCH-3 more times
            //#endif
            /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
         * matter since it will be recomputed at next deflate call.
         */ }
        } else {
            /* No match, output a literal byte */ //Tracevv((stderr,"%c", s.window[s.strstart]));
            /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ bflush = trees._tr_tally(s, 0, s.window[s.strstart]);
            s.lookahead--;
            s.strstart++;
        }
        if (bflush) {
            /*** FLUSH_BLOCK(s, 0); ***/ flush_block_only(s, false);
            if (s.strm.avail_out === 0) return BS_NEED_MORE;
        /***/ }
    }
    s.insert = s.strstart < MIN_MATCH - 1 ? s.strstart : MIN_MATCH - 1;
    if (flush === Z_FINISH) {
        /*** FLUSH_BLOCK(s, 1); ***/ flush_block_only(s, true);
        if (s.strm.avail_out === 0) return BS_FINISH_STARTED;
        /***/ return BS_FINISH_DONE;
    }
    if (s.last_lit) {
        /*** FLUSH_BLOCK(s, 0); ***/ flush_block_only(s, false);
        if (s.strm.avail_out === 0) return BS_NEED_MORE;
    /***/ }
    return BS_BLOCK_DONE;
}
/* ===========================================================================
 * Same as above, but achieves better compression. We use a lazy
 * evaluation for matches: a match is finally adopted only if there is
 * no better match at the next window position.
 */ function deflate_slow(s, flush) {
    var hash_head; /* head of hash chain */ 
    var bflush; /* set if current block must be flushed */ 
    var max_insert;
    /* Process the input block. */ for(;;){
        /* Make sure that we always have enough lookahead, except
     * at the end of the input file. We need MAX_MATCH bytes
     * for the next match, plus MIN_MATCH bytes to insert the
     * string following the next match.
     */ if (s.lookahead < MIN_LOOKAHEAD) {
            fill_window(s);
            if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) return BS_NEED_MORE;
            if (s.lookahead === 0) break;
             /* flush the current block */ 
        }
        /* Insert the string window[strstart .. strstart+2] in the
     * dictionary, and set hash_head to the head of the hash chain:
     */ hash_head = 0 /*NIL*/ ;
        if (s.lookahead >= MIN_MATCH) {
            /*** INSERT_STRING(s, s.strstart, hash_head); ***/ s.ins_h = (s.ins_h << s.hash_shift ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;
            hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
            s.head[s.ins_h] = s.strstart;
        /***/ }
        /* Find the longest match, discarding those <= prev_length.
     */ s.prev_length = s.match_length;
        s.prev_match = s.match_start;
        s.match_length = MIN_MATCH - 1;
        if (hash_head !== 0 /*NIL*/  && s.prev_length < s.max_lazy_match && s.strstart - hash_head <= s.w_size - MIN_LOOKAHEAD) {
            /* To simplify the code, we prevent matches with the string
       * of window index 0 (in particular we have to avoid a match
       * of the string with itself at the start of the input file).
       */ s.match_length = longest_match(s, hash_head);
            /* longest_match() sets match_start */ if (s.match_length <= 5 && (s.strategy === Z_FILTERED || s.match_length === MIN_MATCH && s.strstart - s.match_start > 4096 /*TOO_FAR*/ )) /* If prev_match is also MIN_MATCH, match_start is garbage
         * but we will ignore the current match anyway.
         */ s.match_length = MIN_MATCH - 1;
        }
        /* If there was a match at the previous step and the current
     * match is not better, output the previous match:
     */ if (s.prev_length >= MIN_MATCH && s.match_length <= s.prev_length) {
            max_insert = s.strstart + s.lookahead - MIN_MATCH;
            /* Do not insert strings in hash table beyond this. */ //check_match(s, s.strstart-1, s.prev_match, s.prev_length);
            /***_tr_tally_dist(s, s.strstart - 1 - s.prev_match,
                     s.prev_length - MIN_MATCH, bflush);***/ bflush = trees._tr_tally(s, s.strstart - 1 - s.prev_match, s.prev_length - MIN_MATCH);
            /* Insert in hash table all strings up to the end of the match.
       * strstart-1 and strstart are already inserted. If there is not
       * enough lookahead, the last two strings are not inserted in
       * the hash table.
       */ s.lookahead -= s.prev_length - 1;
            s.prev_length -= 2;
            do if (++s.strstart <= max_insert) {
                /*** INSERT_STRING(s, s.strstart, hash_head); ***/ s.ins_h = (s.ins_h << s.hash_shift ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;
                hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
                s.head[s.ins_h] = s.strstart;
            /***/ }
            while (--s.prev_length !== 0)
            s.match_available = 0;
            s.match_length = MIN_MATCH - 1;
            s.strstart++;
            if (bflush) {
                /*** FLUSH_BLOCK(s, 0); ***/ flush_block_only(s, false);
                if (s.strm.avail_out === 0) return BS_NEED_MORE;
            /***/ }
        } else if (s.match_available) {
            /* If there was no match at the previous position, output a
       * single literal. If there was a match but the current match
       * is longer, truncate the previous match to a single literal.
       */ //Tracevv((stderr,"%c", s->window[s->strstart-1]));
            /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ bflush = trees._tr_tally(s, 0, s.window[s.strstart - 1]);
            if (bflush) /*** FLUSH_BLOCK_ONLY(s, 0) ***/ flush_block_only(s, false);
            s.strstart++;
            s.lookahead--;
            if (s.strm.avail_out === 0) return BS_NEED_MORE;
        } else {
            /* There is no previous match to compare with, wait for
       * the next step to decide.
       */ s.match_available = 1;
            s.strstart++;
            s.lookahead--;
        }
    }
    //Assert (flush != Z_NO_FLUSH, "no flush?");
    if (s.match_available) {
        //Tracevv((stderr,"%c", s->window[s->strstart-1]));
        /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ bflush = trees._tr_tally(s, 0, s.window[s.strstart - 1]);
        s.match_available = 0;
    }
    s.insert = s.strstart < MIN_MATCH - 1 ? s.strstart : MIN_MATCH - 1;
    if (flush === Z_FINISH) {
        /*** FLUSH_BLOCK(s, 1); ***/ flush_block_only(s, true);
        if (s.strm.avail_out === 0) return BS_FINISH_STARTED;
        /***/ return BS_FINISH_DONE;
    }
    if (s.last_lit) {
        /*** FLUSH_BLOCK(s, 0); ***/ flush_block_only(s, false);
        if (s.strm.avail_out === 0) return BS_NEED_MORE;
    /***/ }
    return BS_BLOCK_DONE;
}
/* ===========================================================================
 * For Z_RLE, simply look for runs of bytes, generate matches only of distance
 * one.  Do not maintain a hash table.  (It will be regenerated if this run of
 * deflate switches away from Z_RLE.)
 */ function deflate_rle(s, flush) {
    var bflush; /* set if current block must be flushed */ 
    var prev; /* byte at distance one to match */ 
    var scan, strend; /* scan goes up to strend for length of run */ 
    var _win = s.window;
    for(;;){
        /* Make sure that we always have enough lookahead, except
     * at the end of the input file. We need MAX_MATCH bytes
     * for the longest run, plus one for the unrolled loop.
     */ if (s.lookahead <= MAX_MATCH) {
            fill_window(s);
            if (s.lookahead <= MAX_MATCH && flush === Z_NO_FLUSH) return BS_NEED_MORE;
            if (s.lookahead === 0) break;
             /* flush the current block */ 
        }
        /* See how many times the previous byte repeats */ s.match_length = 0;
        if (s.lookahead >= MIN_MATCH && s.strstart > 0) {
            scan = s.strstart - 1;
            prev = _win[scan];
            if (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan]) {
                strend = s.strstart + MAX_MATCH;
                do ;
                while (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan] && scan < strend)
                s.match_length = MAX_MATCH - (strend - scan);
                if (s.match_length > s.lookahead) s.match_length = s.lookahead;
            }
        //Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan");
        }
        /* Emit match if have run of MIN_MATCH or longer, else emit literal */ if (s.match_length >= MIN_MATCH) {
            //check_match(s, s.strstart, s.strstart - 1, s.match_length);
            /*** _tr_tally_dist(s, 1, s.match_length - MIN_MATCH, bflush); ***/ bflush = trees._tr_tally(s, 1, s.match_length - MIN_MATCH);
            s.lookahead -= s.match_length;
            s.strstart += s.match_length;
            s.match_length = 0;
        } else {
            /* No match, output a literal byte */ //Tracevv((stderr,"%c", s->window[s->strstart]));
            /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ bflush = trees._tr_tally(s, 0, s.window[s.strstart]);
            s.lookahead--;
            s.strstart++;
        }
        if (bflush) {
            /*** FLUSH_BLOCK(s, 0); ***/ flush_block_only(s, false);
            if (s.strm.avail_out === 0) return BS_NEED_MORE;
        /***/ }
    }
    s.insert = 0;
    if (flush === Z_FINISH) {
        /*** FLUSH_BLOCK(s, 1); ***/ flush_block_only(s, true);
        if (s.strm.avail_out === 0) return BS_FINISH_STARTED;
        /***/ return BS_FINISH_DONE;
    }
    if (s.last_lit) {
        /*** FLUSH_BLOCK(s, 0); ***/ flush_block_only(s, false);
        if (s.strm.avail_out === 0) return BS_NEED_MORE;
    /***/ }
    return BS_BLOCK_DONE;
}
/* ===========================================================================
 * For Z_HUFFMAN_ONLY, do not look for matches.  Do not maintain a hash table.
 * (It will be regenerated if this run of deflate switches away from Huffman.)
 */ function deflate_huff(s, flush) {
    var bflush; /* set if current block must be flushed */ 
    for(;;){
        /* Make sure that we have a literal to write. */ if (s.lookahead === 0) {
            fill_window(s);
            if (s.lookahead === 0) {
                if (flush === Z_NO_FLUSH) return BS_NEED_MORE;
                break; /* flush the current block */ 
            }
        }
        /* Output a literal byte */ s.match_length = 0;
        //Tracevv((stderr,"%c", s->window[s->strstart]));
        /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ bflush = trees._tr_tally(s, 0, s.window[s.strstart]);
        s.lookahead--;
        s.strstart++;
        if (bflush) {
            /*** FLUSH_BLOCK(s, 0); ***/ flush_block_only(s, false);
            if (s.strm.avail_out === 0) return BS_NEED_MORE;
        /***/ }
    }
    s.insert = 0;
    if (flush === Z_FINISH) {
        /*** FLUSH_BLOCK(s, 1); ***/ flush_block_only(s, true);
        if (s.strm.avail_out === 0) return BS_FINISH_STARTED;
        /***/ return BS_FINISH_DONE;
    }
    if (s.last_lit) {
        /*** FLUSH_BLOCK(s, 0); ***/ flush_block_only(s, false);
        if (s.strm.avail_out === 0) return BS_NEED_MORE;
    /***/ }
    return BS_BLOCK_DONE;
}
/* Values for max_lazy_match, good_match and max_chain_length, depending on
 * the desired pack level (0..9). The values given below have been tuned to
 * exclude worst case performance for pathological files. Better values may be
 * found for specific files.
 */ function Config(good_length, max_lazy, nice_length, max_chain, func) {
    this.good_length = good_length;
    this.max_lazy = max_lazy;
    this.nice_length = nice_length;
    this.max_chain = max_chain;
    this.func = func;
}
var configuration_table;
configuration_table = [
    /*      good lazy nice chain */ new Config(0, 0, 0, 0, deflate_stored),
    /* 0 store only */ new Config(4, 4, 8, 4, deflate_fast),
    /* 1 max speed, no lazy matches */ new Config(4, 5, 16, 8, deflate_fast),
    /* 2 */ new Config(4, 6, 32, 32, deflate_fast),
    /* 3 */ new Config(4, 4, 16, 16, deflate_slow),
    /* 4 lazy matches */ new Config(8, 16, 32, 32, deflate_slow),
    /* 5 */ new Config(8, 16, 128, 128, deflate_slow),
    /* 6 */ new Config(8, 32, 128, 256, deflate_slow),
    /* 7 */ new Config(32, 128, 258, 1024, deflate_slow),
    /* 8 */ new Config(32, 258, 258, 4096, deflate_slow)
];
/* ===========================================================================
 * Initialize the "longest match" routines for a new zlib stream
 */ function lm_init(s) {
    s.window_size = 2 * s.w_size;
    /*** CLEAR_HASH(s); ***/ zero(s.head); // Fill with NIL (= 0);
    /* Set the default configuration parameters:
   */ s.max_lazy_match = configuration_table[s.level].max_lazy;
    s.good_match = configuration_table[s.level].good_length;
    s.nice_match = configuration_table[s.level].nice_length;
    s.max_chain_length = configuration_table[s.level].max_chain;
    s.strstart = 0;
    s.block_start = 0;
    s.lookahead = 0;
    s.insert = 0;
    s.match_length = s.prev_length = MIN_MATCH - 1;
    s.match_available = 0;
    s.ins_h = 0;
}
function DeflateState() {
    this.strm = null; /* pointer back to this zlib stream */ 
    this.status = 0; /* as the name implies */ 
    this.pending_buf = null; /* output still pending */ 
    this.pending_buf_size = 0; /* size of pending_buf */ 
    this.pending_out = 0; /* next pending byte to output to the stream */ 
    this.pending = 0; /* nb of bytes in the pending buffer */ 
    this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */ 
    this.gzhead = null; /* gzip header information to write */ 
    this.gzindex = 0; /* where in extra, name, or comment */ 
    this.method = Z_DEFLATED; /* can only be DEFLATED */ 
    this.last_flush = -1; /* value of flush param for previous deflate call */ 
    this.w_size = 0; /* LZ77 window size (32K by default) */ 
    this.w_bits = 0; /* log2(w_size)  (8..16) */ 
    this.w_mask = 0; /* w_size - 1 */ 
    this.window = null;
    /* Sliding window. Input bytes are read into the second half of the window,
   * and move to the first half later to keep a dictionary of at least wSize
   * bytes. With this organization, matches are limited to a distance of
   * wSize-MAX_MATCH bytes, but this ensures that IO is always
   * performed with a length multiple of the block size.
   */ this.window_size = 0;
    /* Actual size of window: 2*wSize, except when the user input buffer
   * is directly used as sliding window.
   */ this.prev = null;
    /* Link to older string with same hash index. To limit the size of this
   * array to 64K, this link is maintained only for the last 32K strings.
   * An index in this array is thus a window index modulo 32K.
   */ this.head = null; /* Heads of the hash chains or NIL. */ 
    this.ins_h = 0; /* hash index of string to be inserted */ 
    this.hash_size = 0; /* number of elements in hash table */ 
    this.hash_bits = 0; /* log2(hash_size) */ 
    this.hash_mask = 0; /* hash_size-1 */ 
    this.hash_shift = 0;
    /* Number of bits by which ins_h must be shifted at each input
   * step. It must be such that after MIN_MATCH steps, the oldest
   * byte no longer takes part in the hash key, that is:
   *   hash_shift * MIN_MATCH >= hash_bits
   */ this.block_start = 0;
    /* Window position at the beginning of the current output block. Gets
   * negative when the window is moved backwards.
   */ this.match_length = 0; /* length of best match */ 
    this.prev_match = 0; /* previous match */ 
    this.match_available = 0; /* set if previous match exists */ 
    this.strstart = 0; /* start of string to insert */ 
    this.match_start = 0; /* start of matching string */ 
    this.lookahead = 0; /* number of valid bytes ahead in window */ 
    this.prev_length = 0;
    /* Length of the best match at previous step. Matches not greater than this
   * are discarded. This is used in the lazy match evaluation.
   */ this.max_chain_length = 0;
    /* To speed up deflation, hash chains are never searched beyond this
   * length.  A higher limit improves compression ratio but degrades the
   * speed.
   */ this.max_lazy_match = 0;
    /* Attempt to find a better match only when the current match is strictly
   * smaller than this value. This mechanism is used only for compression
   * levels >= 4.
   */ // That's alias to max_lazy_match, don't use directly
    //this.max_insert_length = 0;
    /* Insert new strings in the hash table only if the match length is not
   * greater than this length. This saves time but degrades compression.
   * max_insert_length is used only for compression levels <= 3.
   */ this.level = 0; /* compression level (1..9) */ 
    this.strategy = 0; /* favor or force Huffman coding*/ 
    this.good_match = 0;
    /* Use a faster search when the previous match is longer than this */ this.nice_match = 0; /* Stop searching when current match exceeds this */ 
    /* used by trees.c: */ /* Didn't use ct_data typedef below to suppress compiler warning */ // struct ct_data_s dyn_ltree[HEAP_SIZE];   /* literal and length tree */
    // struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
    // struct ct_data_s bl_tree[2*BL_CODES+1];  /* Huffman tree for bit lengths */
    // Use flat array of DOUBLE size, with interleaved fata,
    // because JS does not support effective
    this.dyn_ltree = new utils.Buf16(HEAP_SIZE * 2);
    this.dyn_dtree = new utils.Buf16((2 * D_CODES + 1) * 2);
    this.bl_tree = new utils.Buf16((2 * BL_CODES + 1) * 2);
    zero(this.dyn_ltree);
    zero(this.dyn_dtree);
    zero(this.bl_tree);
    this.l_desc = null; /* desc. for literal tree */ 
    this.d_desc = null; /* desc. for distance tree */ 
    this.bl_desc = null; /* desc. for bit length tree */ 
    //ush bl_count[MAX_BITS+1];
    this.bl_count = new utils.Buf16(MAX_BITS + 1);
    /* number of codes at each bit length for an optimal tree */ //int heap[2*L_CODES+1];      /* heap used to build the Huffman trees */
    this.heap = new utils.Buf16(2 * L_CODES + 1); /* heap used to build the Huffman trees */ 
    zero(this.heap);
    this.heap_len = 0; /* number of elements in the heap */ 
    this.heap_max = 0; /* element of largest frequency */ 
    /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
   * The same heap array is used to build all trees.
   */ this.depth = new utils.Buf16(2 * L_CODES + 1); //uch depth[2*L_CODES+1];
    zero(this.depth);
    /* Depth of each subtree used as tie breaker for trees of equal frequency
   */ this.l_buf = 0; /* buffer index for literals or lengths */ 
    this.lit_bufsize = 0;
    /* Size of match buffer for literals/lengths.  There are 4 reasons for
   * limiting lit_bufsize to 64K:
   *   - frequencies can be kept in 16 bit counters
   *   - if compression is not successful for the first block, all input
   *     data is still in the window so we can still emit a stored block even
   *     when input comes from standard input.  (This can also be done for
   *     all blocks if lit_bufsize is not greater than 32K.)
   *   - if compression is not successful for a file smaller than 64K, we can
   *     even emit a stored file instead of a stored block (saving 5 bytes).
   *     This is applicable only for zip (not gzip or zlib).
   *   - creating new Huffman trees less frequently may not provide fast
   *     adaptation to changes in the input data statistics. (Take for
   *     example a binary file with poorly compressible code followed by
   *     a highly compressible string table.) Smaller buffer sizes give
   *     fast adaptation but have of course the overhead of transmitting
   *     trees more frequently.
   *   - I can't count above 4
   */ this.last_lit = 0; /* running index in l_buf */ 
    this.d_buf = 0;
    /* Buffer index for distances. To simplify the code, d_buf and l_buf have
   * the same number of elements. To use different lengths, an extra flag
   * array would be necessary.
   */ this.opt_len = 0; /* bit length of current block with optimal trees */ 
    this.static_len = 0; /* bit length of current block with static trees */ 
    this.matches = 0; /* number of string matches in current block */ 
    this.insert = 0; /* bytes at end of window left to insert */ 
    this.bi_buf = 0;
    /* Output buffer. bits are inserted starting at the bottom (least
   * significant bits).
   */ this.bi_valid = 0;
/* Number of valid bits in bi_buf.  All bits above the last valid bit
   * are always zero.
   */ // Used for window memory init. We safely ignore it for JS. That makes
// sense only for pointers and memory check tools.
//this.high_water = 0;
/* High water mark offset in window for initialized bytes -- bytes above
   * this are set to zero in order to avoid memory check warnings when
   * longest match routines access bytes past the input.  This is then
   * updated to the new high water mark.
   */ }
function deflateResetKeep(strm) {
    var s;
    if (!strm || !strm.state) return err(strm, Z_STREAM_ERROR);
    strm.total_in = strm.total_out = 0;
    strm.data_type = Z_UNKNOWN;
    s = strm.state;
    s.pending = 0;
    s.pending_out = 0;
    if (s.wrap < 0) s.wrap = -s.wrap;
    s.status = s.wrap ? INIT_STATE : BUSY_STATE;
    strm.adler = s.wrap === 2 ? 0 // crc32(0, Z_NULL, 0)
     : 1; // adler32(0, Z_NULL, 0)
    s.last_flush = Z_NO_FLUSH;
    trees._tr_init(s);
    return Z_OK;
}
function deflateReset(strm) {
    var ret = deflateResetKeep(strm);
    if (ret === Z_OK) lm_init(strm.state);
    return ret;
}
function deflateSetHeader(strm, head) {
    if (!strm || !strm.state) return Z_STREAM_ERROR;
    if (strm.state.wrap !== 2) return Z_STREAM_ERROR;
    strm.state.gzhead = head;
    return Z_OK;
}
function deflateInit2(strm, level, method, windowBits, memLevel, strategy) {
    if (!strm) return Z_STREAM_ERROR;
    var wrap = 1;
    if (level === Z_DEFAULT_COMPRESSION) level = 6;
    if (windowBits < 0) {
        wrap = 0;
        windowBits = -windowBits;
    } else if (windowBits > 15) {
        wrap = 2; /* write gzip wrapper instead */ 
        windowBits -= 16;
    }
    if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method !== Z_DEFLATED || windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) return err(strm, Z_STREAM_ERROR);
    if (windowBits === 8) windowBits = 9;
    /* until 256-byte window bug fixed */ var s = new DeflateState();
    strm.state = s;
    s.strm = strm;
    s.wrap = wrap;
    s.gzhead = null;
    s.w_bits = windowBits;
    s.w_size = 1 << s.w_bits;
    s.w_mask = s.w_size - 1;
    s.hash_bits = memLevel + 7;
    s.hash_size = 1 << s.hash_bits;
    s.hash_mask = s.hash_size - 1;
    s.hash_shift = ~~((s.hash_bits + MIN_MATCH - 1) / MIN_MATCH);
    s.window = new utils.Buf8(s.w_size * 2);
    s.head = new utils.Buf16(s.hash_size);
    s.prev = new utils.Buf16(s.w_size);
    // Don't need mem init magic for JS.
    //s.high_water = 0;  /* nothing written to s->window yet */
    s.lit_bufsize = 1 << memLevel + 6; /* 16K elements by default */ 
    s.pending_buf_size = s.lit_bufsize * 4;
    //overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
    //s->pending_buf = (uchf *) overlay;
    s.pending_buf = new utils.Buf8(s.pending_buf_size);
    // It is offset from `s.pending_buf` (size is `s.lit_bufsize * 2`)
    //s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
    s.d_buf = 1 * s.lit_bufsize;
    //s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
    s.l_buf = 3 * s.lit_bufsize;
    s.level = level;
    s.strategy = strategy;
    s.method = method;
    return deflateReset(strm);
}
function deflateInit(strm, level) {
    return deflateInit2(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
}
function deflate(strm, flush) {
    var old_flush, s;
    var beg, val; // for gzip header write only
    if (!strm || !strm.state || flush > Z_BLOCK || flush < 0) return strm ? err(strm, Z_STREAM_ERROR) : Z_STREAM_ERROR;
    s = strm.state;
    if (!strm.output || !strm.input && strm.avail_in !== 0 || s.status === FINISH_STATE && flush !== Z_FINISH) return err(strm, strm.avail_out === 0 ? Z_BUF_ERROR : Z_STREAM_ERROR);
    s.strm = strm; /* just in case */ 
    old_flush = s.last_flush;
    s.last_flush = flush;
    /* Write the header */ if (s.status === INIT_STATE) {
        if (s.wrap === 2) {
            strm.adler = 0; //crc32(0L, Z_NULL, 0);
            put_byte(s, 31);
            put_byte(s, 139);
            put_byte(s, 8);
            if (!s.gzhead) {
                put_byte(s, 0);
                put_byte(s, 0);
                put_byte(s, 0);
                put_byte(s, 0);
                put_byte(s, 0);
                put_byte(s, s.level === 9 ? 2 : s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ? 4 : 0);
                put_byte(s, OS_CODE);
                s.status = BUSY_STATE;
            } else {
                put_byte(s, (s.gzhead.text ? 1 : 0) + (s.gzhead.hcrc ? 2 : 0) + (!s.gzhead.extra ? 0 : 4) + (!s.gzhead.name ? 0 : 8) + (!s.gzhead.comment ? 0 : 16));
                put_byte(s, s.gzhead.time & 255);
                put_byte(s, s.gzhead.time >> 8 & 255);
                put_byte(s, s.gzhead.time >> 16 & 255);
                put_byte(s, s.gzhead.time >> 24 & 255);
                put_byte(s, s.level === 9 ? 2 : s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ? 4 : 0);
                put_byte(s, s.gzhead.os & 255);
                if (s.gzhead.extra && s.gzhead.extra.length) {
                    put_byte(s, s.gzhead.extra.length & 255);
                    put_byte(s, s.gzhead.extra.length >> 8 & 255);
                }
                if (s.gzhead.hcrc) strm.adler = crc32(strm.adler, s.pending_buf, s.pending, 0);
                s.gzindex = 0;
                s.status = EXTRA_STATE;
            }
        } else {
            var header = Z_DEFLATED + (s.w_bits - 8 << 4) << 8;
            var level_flags = -1;
            if (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2) level_flags = 0;
            else if (s.level < 6) level_flags = 1;
            else if (s.level === 6) level_flags = 2;
            else level_flags = 3;
            header |= level_flags << 6;
            if (s.strstart !== 0) header |= PRESET_DICT;
            header += 31 - header % 31;
            s.status = BUSY_STATE;
            putShortMSB(s, header);
            /* Save the adler32 of the preset dictionary: */ if (s.strstart !== 0) {
                putShortMSB(s, strm.adler >>> 16);
                putShortMSB(s, strm.adler & 65535);
            }
            strm.adler = 1; // adler32(0L, Z_NULL, 0);
        }
    }
    //#ifdef GZIP
    if (s.status === EXTRA_STATE) {
        if (s.gzhead.extra /* != Z_NULL*/ ) {
            beg = s.pending; /* start of bytes to update crc */ 
            while(s.gzindex < (s.gzhead.extra.length & 65535)){
                if (s.pending === s.pending_buf_size) {
                    if (s.gzhead.hcrc && s.pending > beg) strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
                    flush_pending(strm);
                    beg = s.pending;
                    if (s.pending === s.pending_buf_size) break;
                }
                put_byte(s, s.gzhead.extra[s.gzindex] & 255);
                s.gzindex++;
            }
            if (s.gzhead.hcrc && s.pending > beg) strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
            if (s.gzindex === s.gzhead.extra.length) {
                s.gzindex = 0;
                s.status = NAME_STATE;
            }
        } else s.status = NAME_STATE;
    }
    if (s.status === NAME_STATE) {
        if (s.gzhead.name /* != Z_NULL*/ ) {
            beg = s.pending; /* start of bytes to update crc */ 
            //int val;
            do {
                if (s.pending === s.pending_buf_size) {
                    if (s.gzhead.hcrc && s.pending > beg) strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
                    flush_pending(strm);
                    beg = s.pending;
                    if (s.pending === s.pending_buf_size) {
                        val = 1;
                        break;
                    }
                }
                // JS specific: little magic to add zero terminator to end of string
                if (s.gzindex < s.gzhead.name.length) val = s.gzhead.name.charCodeAt(s.gzindex++) & 255;
                else val = 0;
                put_byte(s, val);
            }while (val !== 0)
            if (s.gzhead.hcrc && s.pending > beg) strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
            if (val === 0) {
                s.gzindex = 0;
                s.status = COMMENT_STATE;
            }
        } else s.status = COMMENT_STATE;
    }
    if (s.status === COMMENT_STATE) {
        if (s.gzhead.comment /* != Z_NULL*/ ) {
            beg = s.pending; /* start of bytes to update crc */ 
            //int val;
            do {
                if (s.pending === s.pending_buf_size) {
                    if (s.gzhead.hcrc && s.pending > beg) strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
                    flush_pending(strm);
                    beg = s.pending;
                    if (s.pending === s.pending_buf_size) {
                        val = 1;
                        break;
                    }
                }
                // JS specific: little magic to add zero terminator to end of string
                if (s.gzindex < s.gzhead.comment.length) val = s.gzhead.comment.charCodeAt(s.gzindex++) & 255;
                else val = 0;
                put_byte(s, val);
            }while (val !== 0)
            if (s.gzhead.hcrc && s.pending > beg) strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
            if (val === 0) s.status = HCRC_STATE;
        } else s.status = HCRC_STATE;
    }
    if (s.status === HCRC_STATE) {
        if (s.gzhead.hcrc) {
            if (s.pending + 2 > s.pending_buf_size) flush_pending(strm);
            if (s.pending + 2 <= s.pending_buf_size) {
                put_byte(s, strm.adler & 255);
                put_byte(s, strm.adler >> 8 & 255);
                strm.adler = 0; //crc32(0L, Z_NULL, 0);
                s.status = BUSY_STATE;
            }
        } else s.status = BUSY_STATE;
    }
    //#endif
    /* Flush as much pending output as possible */ if (s.pending !== 0) {
        flush_pending(strm);
        if (strm.avail_out === 0) {
            /* Since avail_out is 0, deflate will be called again with
       * more output space, but possibly with both pending and
       * avail_in equal to zero. There won't be anything to do,
       * but this is not an error situation so make sure we
       * return OK instead of BUF_ERROR at next call of deflate:
       */ s.last_flush = -1;
            return Z_OK;
        }
    /* Make sure there is something to do and avoid duplicate consecutive
     * flushes. For repeated and useless calls with Z_FINISH, we keep
     * returning Z_STREAM_END instead of Z_BUF_ERROR.
     */ } else if (strm.avail_in === 0 && rank(flush) <= rank(old_flush) && flush !== Z_FINISH) return err(strm, Z_BUF_ERROR);
    /* User must not provide more input after the first FINISH: */ if (s.status === FINISH_STATE && strm.avail_in !== 0) return err(strm, Z_BUF_ERROR);
    /* Start a new block or continue the current one.
   */ if (strm.avail_in !== 0 || s.lookahead !== 0 || flush !== Z_NO_FLUSH && s.status !== FINISH_STATE) {
        var bstate = s.strategy === Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : s.strategy === Z_RLE ? deflate_rle(s, flush) : configuration_table[s.level].func(s, flush);
        if (bstate === BS_FINISH_STARTED || bstate === BS_FINISH_DONE) s.status = FINISH_STATE;
        if (bstate === BS_NEED_MORE || bstate === BS_FINISH_STARTED) {
            if (strm.avail_out === 0) s.last_flush = -1;
            return Z_OK;
        /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
       * of deflate should use the same flush parameter to make sure
       * that the flush is complete. So we don't have to output an
       * empty block here, this will be done at next call. This also
       * ensures that for a very small output buffer, we emit at most
       * one empty block.
       */ }
        if (bstate === BS_BLOCK_DONE) {
            if (flush === Z_PARTIAL_FLUSH) trees._tr_align(s);
            else if (flush !== Z_BLOCK) {
                trees._tr_stored_block(s, 0, 0, false);
                /* For a full flush, this empty block will be recognized
         * as a special marker by inflate_sync().
         */ if (flush === Z_FULL_FLUSH) {
                    /*** CLEAR_HASH(s); ***/ /* forget history */ zero(s.head); // Fill with NIL (= 0);
                    if (s.lookahead === 0) {
                        s.strstart = 0;
                        s.block_start = 0;
                        s.insert = 0;
                    }
                }
            }
            flush_pending(strm);
            if (strm.avail_out === 0) {
                s.last_flush = -1; /* avoid BUF_ERROR at next call, see above */ 
                return Z_OK;
            }
        }
    }
    //Assert(strm->avail_out > 0, "bug2");
    //if (strm.avail_out <= 0) { throw new Error("bug2");}
    if (flush !== Z_FINISH) return Z_OK;
    if (s.wrap <= 0) return Z_STREAM_END;
    /* Write the trailer */ if (s.wrap === 2) {
        put_byte(s, strm.adler & 255);
        put_byte(s, strm.adler >> 8 & 255);
        put_byte(s, strm.adler >> 16 & 255);
        put_byte(s, strm.adler >> 24 & 255);
        put_byte(s, strm.total_in & 255);
        put_byte(s, strm.total_in >> 8 & 255);
        put_byte(s, strm.total_in >> 16 & 255);
        put_byte(s, strm.total_in >> 24 & 255);
    } else {
        putShortMSB(s, strm.adler >>> 16);
        putShortMSB(s, strm.adler & 65535);
    }
    flush_pending(strm);
    /* If avail_out is zero, the application will call deflate again
   * to flush the rest.
   */ if (s.wrap > 0) s.wrap = -s.wrap;
    /* write the trailer only once! */ return s.pending !== 0 ? Z_OK : Z_STREAM_END;
}
function deflateEnd(strm) {
    var status;
    if (!strm /*== Z_NULL*/  || !strm.state /*== Z_NULL*/ ) return Z_STREAM_ERROR;
    status = strm.state.status;
    if (status !== INIT_STATE && status !== EXTRA_STATE && status !== NAME_STATE && status !== COMMENT_STATE && status !== HCRC_STATE && status !== BUSY_STATE && status !== FINISH_STATE) return err(strm, Z_STREAM_ERROR);
    strm.state = null;
    return status === BUSY_STATE ? err(strm, Z_DATA_ERROR) : Z_OK;
}
/* =========================================================================
 * Initializes the compression dictionary from the given byte
 * sequence without producing any compressed output.
 */ function deflateSetDictionary(strm, dictionary) {
    var dictLength = dictionary.length;
    var s;
    var str, n;
    var wrap;
    var avail;
    var next;
    var input;
    var tmpDict;
    if (!strm /*== Z_NULL*/  || !strm.state /*== Z_NULL*/ ) return Z_STREAM_ERROR;
    s = strm.state;
    wrap = s.wrap;
    if (wrap === 2 || wrap === 1 && s.status !== INIT_STATE || s.lookahead) return Z_STREAM_ERROR;
    /* when using zlib wrappers, compute Adler-32 for provided dictionary */ if (wrap === 1) /* adler32(strm->adler, dictionary, dictLength); */ strm.adler = adler32(strm.adler, dictionary, dictLength, 0);
    s.wrap = 0; /* avoid computing Adler-32 in read_buf */ 
    /* if dictionary would fill window, just replace the history */ if (dictLength >= s.w_size) {
        if (wrap === 0) {
            /*** CLEAR_HASH(s); ***/ zero(s.head); // Fill with NIL (= 0);
            s.strstart = 0;
            s.block_start = 0;
            s.insert = 0;
        }
        /* use the tail */ // dictionary = dictionary.slice(dictLength - s.w_size);
        tmpDict = new utils.Buf8(s.w_size);
        utils.arraySet(tmpDict, dictionary, dictLength - s.w_size, s.w_size, 0);
        dictionary = tmpDict;
        dictLength = s.w_size;
    }
    /* insert dictionary into window and hash */ avail = strm.avail_in;
    next = strm.next_in;
    input = strm.input;
    strm.avail_in = dictLength;
    strm.next_in = 0;
    strm.input = dictionary;
    fill_window(s);
    while(s.lookahead >= MIN_MATCH){
        str = s.strstart;
        n = s.lookahead - (MIN_MATCH - 1);
        do {
            /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */ s.ins_h = (s.ins_h << s.hash_shift ^ s.window[str + MIN_MATCH - 1]) & s.hash_mask;
            s.prev[str & s.w_mask] = s.head[s.ins_h];
            s.head[s.ins_h] = str;
            str++;
        }while (--n)
        s.strstart = str;
        s.lookahead = MIN_MATCH - 1;
        fill_window(s);
    }
    s.strstart += s.lookahead;
    s.block_start = s.strstart;
    s.insert = s.lookahead;
    s.lookahead = 0;
    s.match_length = s.prev_length = MIN_MATCH - 1;
    s.match_available = 0;
    strm.next_in = next;
    strm.input = input;
    strm.avail_in = avail;
    s.wrap = wrap;
    return Z_OK;
}
exports.deflateInit = deflateInit;
exports.deflateInit2 = deflateInit2;
exports.deflateReset = deflateReset;
exports.deflateResetKeep = deflateResetKeep;
exports.deflateSetHeader = deflateSetHeader;
exports.deflate = deflate;
exports.deflateEnd = deflateEnd;
exports.deflateSetDictionary = deflateSetDictionary;
exports.deflateInfo = 'pako deflate (from Nodeca project)'; /* Not implemented
exports.deflateBound = deflateBound;
exports.deflateCopy = deflateCopy;
exports.deflateParams = deflateParams;
exports.deflatePending = deflatePending;
exports.deflatePrime = deflatePrime;
exports.deflateTune = deflateTune;
*/ 

},{"../utils/common":"2FpJl","./trees":"5Edzu","./adler32":"5HolB","./crc32":"hlmdd","./messages":"4MwdS"}],"5Edzu":[function(require,module,exports) {
'use strict';
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
//   claim that you wrote the original software. If you use this software
//   in a product, an acknowledgment in the product documentation would be
//   appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
//   misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
/* eslint-disable space-unary-ops */ var utils = require('../utils/common');
/* Public constants ==========================================================*/ /* ===========================================================================*/ //var Z_FILTERED          = 1;
//var Z_HUFFMAN_ONLY      = 2;
//var Z_RLE               = 3;
var Z_FIXED = 4;
//var Z_DEFAULT_STRATEGY  = 0;
/* Possible values of the data_type field (though see inflate()) */ var Z_BINARY = 0;
var Z_TEXT = 1;
//var Z_ASCII             = 1; // = Z_TEXT
var Z_UNKNOWN = 2;
/*============================================================================*/ function zero(buf) {
    var len = buf.length;
    while(--len >= 0)buf[len] = 0;
}
// From zutil.h
var STORED_BLOCK = 0;
var STATIC_TREES = 1;
var DYN_TREES = 2;
/* The three kinds of block type */ var MIN_MATCH = 3;
var MAX_MATCH = 258;
/* The minimum and maximum match lengths */ // From deflate.h
/* ===========================================================================
 * Internal compression state.
 */ var LENGTH_CODES = 29;
/* number of length codes, not counting the special END_BLOCK code */ var LITERALS = 256;
/* number of literal bytes 0..255 */ var L_CODES = LITERALS + 1 + LENGTH_CODES;
/* number of Literal or Length codes, including the END_BLOCK code */ var D_CODES = 30;
/* number of distance codes */ var BL_CODES = 19;
/* number of codes used to transfer the bit lengths */ var HEAP_SIZE = 2 * L_CODES + 1;
/* maximum heap size */ var MAX_BITS = 15;
/* All codes must not exceed MAX_BITS bits */ var Buf_size = 16;
/* size of bit buffer in bi_buf */ /* ===========================================================================
 * Constants
 */ var MAX_BL_BITS = 7;
/* Bit length codes must not exceed MAX_BL_BITS bits */ var END_BLOCK = 256;
/* end of block literal code */ var REP_3_6 = 16;
/* repeat previous bit length 3-6 times (2 bits of repeat count) */ var REPZ_3_10 = 17;
/* repeat a zero length 3-10 times  (3 bits of repeat count) */ var REPZ_11_138 = 18;
/* repeat a zero length 11-138 times  (7 bits of repeat count) */ /* eslint-disable comma-spacing,array-bracket-spacing */ var extra_lbits = /* extra bits for each length code */ [
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    1,
    1,
    1,
    1,
    2,
    2,
    2,
    2,
    3,
    3,
    3,
    3,
    4,
    4,
    4,
    4,
    5,
    5,
    5,
    5,
    0
];
var extra_dbits = /* extra bits for each distance code */ [
    0,
    0,
    0,
    0,
    1,
    1,
    2,
    2,
    3,
    3,
    4,
    4,
    5,
    5,
    6,
    6,
    7,
    7,
    8,
    8,
    9,
    9,
    10,
    10,
    11,
    11,
    12,
    12,
    13,
    13
];
var extra_blbits = /* extra bits for each bit length code */ [
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    2,
    3,
    7
];
var bl_order = [
    16,
    17,
    18,
    0,
    8,
    7,
    9,
    6,
    10,
    5,
    11,
    4,
    12,
    3,
    13,
    2,
    14,
    1,
    15
];
/* eslint-enable comma-spacing,array-bracket-spacing */ /* The lengths of the bit length codes are sent in order of decreasing
 * probability, to avoid transmitting the lengths for unused bit length codes.
 */ /* ===========================================================================
 * Local data. These are initialized only once.
 */ // We pre-fill arrays with 0 to avoid uninitialized gaps
var DIST_CODE_LEN = 512; /* see definition of array dist_code below */ 
// !!!! Use flat array instead of structure, Freq = i*2, Len = i*2+1
var static_ltree = new Array((L_CODES + 2) * 2);
zero(static_ltree);
/* The static literal tree. Since the bit lengths are imposed, there is no
 * need for the L_CODES extra codes used during heap construction. However
 * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
 * below).
 */ var static_dtree = new Array(D_CODES * 2);
zero(static_dtree);
/* The static distance tree. (Actually a trivial tree since all codes use
 * 5 bits.)
 */ var _dist_code = new Array(DIST_CODE_LEN);
zero(_dist_code);
/* Distance codes. The first 256 values correspond to the distances
 * 3 .. 258, the last 256 values correspond to the top 8 bits of
 * the 15 bit distances.
 */ var _length_code = new Array(MAX_MATCH - MIN_MATCH + 1);
zero(_length_code);
/* length code for each normalized match length (0 == MIN_MATCH) */ var base_length = new Array(LENGTH_CODES);
zero(base_length);
/* First normalized length for each code (0 = MIN_MATCH) */ var base_dist = new Array(D_CODES);
zero(base_dist);
/* First normalized distance for each code (0 = distance of 1) */ function StaticTreeDesc(static_tree, extra_bits, extra_base, elems, max_length) {
    this.static_tree = static_tree; /* static tree or NULL */ 
    this.extra_bits = extra_bits; /* extra bits for each code or NULL */ 
    this.extra_base = extra_base; /* base index for extra_bits */ 
    this.elems = elems; /* max number of elements in the tree */ 
    this.max_length = max_length; /* max bit length for the codes */ 
    // show if `static_tree` has data or dummy - needed for monomorphic objects
    this.has_stree = static_tree && static_tree.length;
}
var static_l_desc;
var static_d_desc;
var static_bl_desc;
function TreeDesc(dyn_tree, stat_desc) {
    this.dyn_tree = dyn_tree; /* the dynamic tree */ 
    this.max_code = 0; /* largest code with non zero frequency */ 
    this.stat_desc = stat_desc; /* the corresponding static tree */ 
}
function d_code(dist) {
    return dist < 256 ? _dist_code[dist] : _dist_code[256 + (dist >>> 7)];
}
/* ===========================================================================
 * Output a short LSB first on the stream.
 * IN assertion: there is enough room in pendingBuf.
 */ function put_short(s, w) {
    //    put_byte(s, (uch)((w) & 0xff));
    //    put_byte(s, (uch)((ush)(w) >> 8));
    s.pending_buf[s.pending++] = w & 255;
    s.pending_buf[s.pending++] = w >>> 8 & 255;
}
/* ===========================================================================
 * Send a value on a given number of bits.
 * IN assertion: length <= 16 and value fits in length bits.
 */ function send_bits(s, value, length) {
    if (s.bi_valid > Buf_size - length) {
        s.bi_buf |= value << s.bi_valid & 65535;
        put_short(s, s.bi_buf);
        s.bi_buf = value >> Buf_size - s.bi_valid;
        s.bi_valid += length - Buf_size;
    } else {
        s.bi_buf |= value << s.bi_valid & 65535;
        s.bi_valid += length;
    }
}
function send_code(s, c, tree) {
    send_bits(s, tree[c * 2], tree[c * 2 + 1]);
}
/* ===========================================================================
 * Reverse the first len bits of a code, using straightforward code (a faster
 * method would use a table)
 * IN assertion: 1 <= len <= 15
 */ function bi_reverse(code, len) {
    var res = 0;
    do {
        res |= code & 1;
        code >>>= 1;
        res <<= 1;
    }while (--len > 0)
    return res >>> 1;
}
/* ===========================================================================
 * Flush the bit buffer, keeping at most 7 bits in it.
 */ function bi_flush(s) {
    if (s.bi_valid === 16) {
        put_short(s, s.bi_buf);
        s.bi_buf = 0;
        s.bi_valid = 0;
    } else if (s.bi_valid >= 8) {
        s.pending_buf[s.pending++] = s.bi_buf & 255;
        s.bi_buf >>= 8;
        s.bi_valid -= 8;
    }
}
/* ===========================================================================
 * Compute the optimal bit lengths for a tree and update the total bit length
 * for the current block.
 * IN assertion: the fields freq and dad are set, heap[heap_max] and
 *    above are the tree nodes sorted by increasing frequency.
 * OUT assertions: the field len is set to the optimal bit length, the
 *     array bl_count contains the frequencies for each bit length.
 *     The length opt_len is updated; static_len is also updated if stree is
 *     not null.
 */ function gen_bitlen(s, desc) //    deflate_state *s;
//    tree_desc *desc;    /* the tree descriptor */
{
    var tree = desc.dyn_tree;
    var max_code = desc.max_code;
    var stree = desc.stat_desc.static_tree;
    var has_stree = desc.stat_desc.has_stree;
    var extra = desc.stat_desc.extra_bits;
    var base = desc.stat_desc.extra_base;
    var max_length = desc.stat_desc.max_length;
    var h; /* heap index */ 
    var n, m; /* iterate over the tree elements */ 
    var bits; /* bit length */ 
    var xbits; /* extra bits */ 
    var f; /* frequency */ 
    var overflow = 0; /* number of elements with bit length too large */ 
    for(bits = 0; bits <= MAX_BITS; bits++)s.bl_count[bits] = 0;
    /* In a first pass, compute the optimal bit lengths (which may
   * overflow in the case of the bit length tree).
   */ tree[s.heap[s.heap_max] * 2 + 1] = 0; /* root of the heap */ 
    for(h = s.heap_max + 1; h < HEAP_SIZE; h++){
        n = s.heap[h];
        bits = tree[tree[n * 2 + 1] * 2 + 1] + 1;
        if (bits > max_length) {
            bits = max_length;
            overflow++;
        }
        tree[n * 2 + 1] = bits;
        /* We overwrite tree[n].Dad which is no longer needed */ if (n > max_code) continue;
         /* not a leaf node */ 
        s.bl_count[bits]++;
        xbits = 0;
        if (n >= base) xbits = extra[n - base];
        f = tree[n * 2];
        s.opt_len += f * (bits + xbits);
        if (has_stree) s.static_len += f * (stree[n * 2 + 1] + xbits);
    }
    if (overflow === 0) return;
    // Trace((stderr,"\nbit length overflow\n"));
    /* This happens for example on obj2 and pic of the Calgary corpus */ /* Find the first bit length which could increase: */ do {
        bits = max_length - 1;
        while(s.bl_count[bits] === 0)bits--;
        s.bl_count[bits]--; /* move one leaf down the tree */ 
        s.bl_count[bits + 1] += 2; /* move one overflow item as its brother */ 
        s.bl_count[max_length]--;
        /* The brother of the overflow item also moves one step up,
     * but this does not affect bl_count[max_length]
     */ overflow -= 2;
    }while (overflow > 0)
    /* Now recompute all bit lengths, scanning in increasing frequency.
   * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
   * lengths instead of fixing only the wrong ones. This idea is taken
   * from 'ar' written by Haruhiko Okumura.)
   */ for(bits = max_length; bits !== 0; bits--){
        n = s.bl_count[bits];
        while(n !== 0){
            m = s.heap[--h];
            if (m > max_code) continue;
            if (tree[m * 2 + 1] !== bits) {
                // Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
                s.opt_len += (bits - tree[m * 2 + 1]) * tree[m * 2];
                tree[m * 2 + 1] = bits;
            }
            n--;
        }
    }
}
/* ===========================================================================
 * Generate the codes for a given tree and bit counts (which need not be
 * optimal).
 * IN assertion: the array bl_count contains the bit length statistics for
 * the given tree and the field len is set for all tree elements.
 * OUT assertion: the field code is set for all tree elements of non
 *     zero code length.
 */ function gen_codes(tree, max_code, bl_count) //    ct_data *tree;             /* the tree to decorate */
//    int max_code;              /* largest code with non zero frequency */
//    ushf *bl_count;            /* number of codes at each bit length */
{
    var next_code = new Array(MAX_BITS + 1); /* next code value for each bit length */ 
    var code = 0; /* running code value */ 
    var bits; /* bit index */ 
    var n; /* code index */ 
    /* The distribution counts are first used to generate the code values
   * without bit reversal.
   */ for(bits = 1; bits <= MAX_BITS; bits++)next_code[bits] = code = code + bl_count[bits - 1] << 1;
    /* Check that the bit counts in bl_count are consistent. The last code
   * must be all ones.
   */ //Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
    //        "inconsistent bit counts");
    //Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
    for(n = 0; n <= max_code; n++){
        var len = tree[n * 2 + 1];
        if (len === 0) continue;
        /* Now reverse the bits */ tree[n * 2] = bi_reverse(next_code[len]++, len);
    //Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
    //     n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
    }
}
/* ===========================================================================
 * Initialize the various 'constant' tables.
 */ function tr_static_init() {
    var n; /* iterates over tree elements */ 
    var bits; /* bit counter */ 
    var length; /* length value */ 
    var code; /* code value */ 
    var dist; /* distance index */ 
    var bl_count = new Array(MAX_BITS + 1);
    /* number of codes at each bit length for an optimal tree */ // do check in _tr_init()
    //if (static_init_done) return;
    /* For some embedded targets, global variables are not initialized: */ /*#ifdef NO_INIT_GLOBAL_POINTERS
  static_l_desc.static_tree = static_ltree;
  static_l_desc.extra_bits = extra_lbits;
  static_d_desc.static_tree = static_dtree;
  static_d_desc.extra_bits = extra_dbits;
  static_bl_desc.extra_bits = extra_blbits;
#endif*/ /* Initialize the mapping length (0..255) -> length code (0..28) */ length = 0;
    for(code = 0; code < LENGTH_CODES - 1; code++){
        base_length[code] = length;
        for(n = 0; n < 1 << extra_lbits[code]; n++)_length_code[length++] = code;
    }
    //Assert (length == 256, "tr_static_init: length != 256");
    /* Note that the length 255 (match length 258) can be represented
   * in two different ways: code 284 + 5 bits or code 285, so we
   * overwrite length_code[255] to use the best encoding:
   */ _length_code[length - 1] = code;
    /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ dist = 0;
    for(code = 0; code < 16; code++){
        base_dist[code] = dist;
        for(n = 0; n < 1 << extra_dbits[code]; n++)_dist_code[dist++] = code;
    }
    //Assert (dist == 256, "tr_static_init: dist != 256");
    dist >>= 7; /* from now on, all distances are divided by 128 */ 
    for(; code < D_CODES; code++){
        base_dist[code] = dist << 7;
        for(n = 0; n < 1 << extra_dbits[code] - 7; n++)_dist_code[256 + dist++] = code;
    }
    //Assert (dist == 256, "tr_static_init: 256+dist != 512");
    /* Construct the codes of the static literal tree */ for(bits = 0; bits <= MAX_BITS; bits++)bl_count[bits] = 0;
    n = 0;
    while(n <= 143){
        static_ltree[n * 2 + 1] = 8;
        n++;
        bl_count[8]++;
    }
    while(n <= 255){
        static_ltree[n * 2 + 1] = 9;
        n++;
        bl_count[9]++;
    }
    while(n <= 279){
        static_ltree[n * 2 + 1] = 7;
        n++;
        bl_count[7]++;
    }
    while(n <= 287){
        static_ltree[n * 2 + 1] = 8;
        n++;
        bl_count[8]++;
    }
    /* Codes 286 and 287 do not exist, but we must include them in the
   * tree construction to get a canonical Huffman tree (longest code
   * all ones)
   */ gen_codes(static_ltree, L_CODES + 1, bl_count);
    /* The static distance tree is trivial: */ for(n = 0; n < D_CODES; n++){
        static_dtree[n * 2 + 1] = 5;
        static_dtree[n * 2] = bi_reverse(n, 5);
    }
    // Now data ready and we can init static trees
    static_l_desc = new StaticTreeDesc(static_ltree, extra_lbits, LITERALS + 1, L_CODES, MAX_BITS);
    static_d_desc = new StaticTreeDesc(static_dtree, extra_dbits, 0, D_CODES, MAX_BITS);
    static_bl_desc = new StaticTreeDesc(new Array(0), extra_blbits, 0, BL_CODES, MAX_BL_BITS);
//static_init_done = true;
}
/* ===========================================================================
 * Initialize a new block.
 */ function init_block(s) {
    var n; /* iterates over tree elements */ 
    /* Initialize the trees. */ for(n = 0; n < L_CODES; n++)s.dyn_ltree[n * 2] = 0;
    for(n = 0; n < D_CODES; n++)s.dyn_dtree[n * 2] = 0;
    for(n = 0; n < BL_CODES; n++)s.bl_tree[n * 2] = 0;
    s.dyn_ltree[END_BLOCK * 2] = 1;
    s.opt_len = s.static_len = 0;
    s.last_lit = s.matches = 0;
}
/* ===========================================================================
 * Flush the bit buffer and align the output on a byte boundary
 */ function bi_windup(s) {
    if (s.bi_valid > 8) put_short(s, s.bi_buf);
    else if (s.bi_valid > 0) //put_byte(s, (Byte)s->bi_buf);
    s.pending_buf[s.pending++] = s.bi_buf;
    s.bi_buf = 0;
    s.bi_valid = 0;
}
/* ===========================================================================
 * Copy a stored block, storing first the length and its
 * one's complement if requested.
 */ function copy_block(s, buf, len, header) //DeflateState *s;
//charf    *buf;    /* the input data */
//unsigned len;     /* its length */
//int      header;  /* true if block header must be written */
{
    bi_windup(s); /* align on byte boundary */ 
    if (header) {
        put_short(s, len);
        put_short(s, ~len);
    }
    //  while (len--) {
    //    put_byte(s, *buf++);
    //  }
    utils.arraySet(s.pending_buf, s.window, buf, len, s.pending);
    s.pending += len;
}
/* ===========================================================================
 * Compares to subtrees, using the tree depth as tie breaker when
 * the subtrees have equal frequency. This minimizes the worst case length.
 */ function smaller(tree, n, m, depth) {
    var _n2 = n * 2;
    var _m2 = m * 2;
    return tree[_n2] < tree[_m2] || tree[_n2] === tree[_m2] && depth[n] <= depth[m];
}
/* ===========================================================================
 * Restore the heap property by moving down the tree starting at node k,
 * exchanging a node with the smallest of its two sons if necessary, stopping
 * when the heap property is re-established (each father smaller than its
 * two sons).
 */ function pqdownheap(s, tree, k) //    deflate_state *s;
//    ct_data *tree;  /* the tree to restore */
//    int k;               /* node to move down */
{
    var v = s.heap[k];
    var j = k << 1; /* left son of k */ 
    while(j <= s.heap_len){
        /* Set j to the smallest of the two sons: */ if (j < s.heap_len && smaller(tree, s.heap[j + 1], s.heap[j], s.depth)) j++;
        /* Exit if v is smaller than both sons */ if (smaller(tree, v, s.heap[j], s.depth)) break;
        /* Exchange v with the smallest son */ s.heap[k] = s.heap[j];
        k = j;
        /* And continue down the tree, setting j to the left son of k */ j <<= 1;
    }
    s.heap[k] = v;
}
// inlined manually
// var SMALLEST = 1;
/* ===========================================================================
 * Send the block data compressed using the given Huffman trees
 */ function compress_block(s, ltree, dtree) //    deflate_state *s;
//    const ct_data *ltree; /* literal tree */
//    const ct_data *dtree; /* distance tree */
{
    var dist; /* distance of matched string */ 
    var lc; /* match length or unmatched char (if dist == 0) */ 
    var lx = 0; /* running index in l_buf */ 
    var code; /* the code to send */ 
    var extra; /* number of extra bits to send */ 
    if (s.last_lit !== 0) do {
        dist = s.pending_buf[s.d_buf + lx * 2] << 8 | s.pending_buf[s.d_buf + lx * 2 + 1];
        lc = s.pending_buf[s.l_buf + lx];
        lx++;
        if (dist === 0) send_code(s, lc, ltree); /* send a literal byte */ 
        else {
            /* Here, lc is the match length - MIN_MATCH */ code = _length_code[lc];
            send_code(s, code + LITERALS + 1, ltree); /* send the length code */ 
            extra = extra_lbits[code];
            if (extra !== 0) {
                lc -= base_length[code];
                send_bits(s, lc, extra); /* send the extra length bits */ 
            }
            dist--; /* dist is now the match distance - 1 */ 
            code = d_code(dist);
            //Assert (code < D_CODES, "bad d_code");
            send_code(s, code, dtree); /* send the distance code */ 
            extra = extra_dbits[code];
            if (extra !== 0) {
                dist -= base_dist[code];
                send_bits(s, dist, extra); /* send the extra distance bits */ 
            }
        } /* literal or match pair ? */ 
    /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ //Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
    //       "pendingBuf overflow");
    }while (lx < s.last_lit)
    send_code(s, END_BLOCK, ltree);
}
/* ===========================================================================
 * Construct one Huffman tree and assigns the code bit strings and lengths.
 * Update the total bit length for the current block.
 * IN assertion: the field freq is set for all tree elements.
 * OUT assertions: the fields len and code are set to the optimal bit length
 *     and corresponding code. The length opt_len is updated; static_len is
 *     also updated if stree is not null. The field max_code is set.
 */ function build_tree(s, desc) //    deflate_state *s;
//    tree_desc *desc; /* the tree descriptor */
{
    var tree = desc.dyn_tree;
    var stree = desc.stat_desc.static_tree;
    var has_stree = desc.stat_desc.has_stree;
    var elems = desc.stat_desc.elems;
    var n, m; /* iterate over heap elements */ 
    var max_code = -1; /* largest code with non zero frequency */ 
    var node; /* new node being created */ 
    /* Construct the initial heap, with least frequent element in
   * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
   * heap[0] is not used.
   */ s.heap_len = 0;
    s.heap_max = HEAP_SIZE;
    for(n = 0; n < elems; n++)if (tree[n * 2] !== 0) {
        s.heap[++s.heap_len] = max_code = n;
        s.depth[n] = 0;
    } else tree[n * 2 + 1] = 0;
    /* The pkzip format requires that at least one distance code exists,
   * and that at least one bit should be sent even if there is only one
   * possible code. So to avoid special checks later on we force at least
   * two codes of non zero frequency.
   */ while(s.heap_len < 2){
        node = s.heap[++s.heap_len] = max_code < 2 ? ++max_code : 0;
        tree[node * 2] = 1;
        s.depth[node] = 0;
        s.opt_len--;
        if (has_stree) s.static_len -= stree[node * 2 + 1];
    /* node is 0 or 1 so it does not have extra bits */ }
    desc.max_code = max_code;
    /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
   * establish sub-heaps of increasing lengths:
   */ for(n = s.heap_len >> 1 /*int /2*/ ; n >= 1; n--)pqdownheap(s, tree, n);
    /* Construct the Huffman tree by repeatedly combining the least two
   * frequent nodes.
   */ node = elems; /* next internal node of the tree */ 
    do {
        //pqremove(s, tree, n);  /* n = node of least frequency */
        /*** pqremove ***/ n = s.heap[1 /*SMALLEST*/ ];
        s.heap[1 /*SMALLEST*/ ] = s.heap[s.heap_len--];
        pqdownheap(s, tree, 1 /*SMALLEST*/ );
        /***/ m = s.heap[1 /*SMALLEST*/ ]; /* m = node of next least frequency */ 
        s.heap[--s.heap_max] = n; /* keep the nodes sorted by frequency */ 
        s.heap[--s.heap_max] = m;
        /* Create a new node father of n and m */ tree[node * 2] = tree[n * 2] + tree[m * 2];
        s.depth[node] = (s.depth[n] >= s.depth[m] ? s.depth[n] : s.depth[m]) + 1;
        tree[n * 2 + 1] = tree[m * 2 + 1] = node;
        /* and insert the new node in the heap */ s.heap[1 /*SMALLEST*/ ] = node++;
        pqdownheap(s, tree, 1 /*SMALLEST*/ );
    }while (s.heap_len >= 2)
    s.heap[--s.heap_max] = s.heap[1 /*SMALLEST*/ ];
    /* At this point, the fields freq and dad are set. We can now
   * generate the bit lengths.
   */ gen_bitlen(s, desc);
    /* The field len is now set, we can generate the bit codes */ gen_codes(tree, max_code, s.bl_count);
}
/* ===========================================================================
 * Scan a literal or distance tree to determine the frequencies of the codes
 * in the bit length tree.
 */ function scan_tree(s, tree, max_code) //    deflate_state *s;
//    ct_data *tree;   /* the tree to be scanned */
//    int max_code;    /* and its largest code of non zero frequency */
{
    var n; /* iterates over all tree elements */ 
    var prevlen = -1; /* last emitted length */ 
    var curlen; /* length of current code */ 
    var nextlen = tree[1]; /* length of next code */ 
    var count = 0; /* repeat count of the current code */ 
    var max_count = 7; /* max repeat count */ 
    var min_count = 4; /* min repeat count */ 
    if (nextlen === 0) {
        max_count = 138;
        min_count = 3;
    }
    tree[(max_code + 1) * 2 + 1] = 65535; /* guard */ 
    for(n = 0; n <= max_code; n++){
        curlen = nextlen;
        nextlen = tree[(n + 1) * 2 + 1];
        if (++count < max_count && curlen === nextlen) continue;
        else if (count < min_count) s.bl_tree[curlen * 2] += count;
        else if (curlen !== 0) {
            if (curlen !== prevlen) s.bl_tree[curlen * 2]++;
            s.bl_tree[REP_3_6 * 2]++;
        } else if (count <= 10) s.bl_tree[REPZ_3_10 * 2]++;
        else s.bl_tree[REPZ_11_138 * 2]++;
        count = 0;
        prevlen = curlen;
        if (nextlen === 0) {
            max_count = 138;
            min_count = 3;
        } else if (curlen === nextlen) {
            max_count = 6;
            min_count = 3;
        } else {
            max_count = 7;
            min_count = 4;
        }
    }
}
/* ===========================================================================
 * Send a literal or distance tree in compressed form, using the codes in
 * bl_tree.
 */ function send_tree(s, tree, max_code) //    deflate_state *s;
//    ct_data *tree; /* the tree to be scanned */
//    int max_code;       /* and its largest code of non zero frequency */
{
    var n; /* iterates over all tree elements */ 
    var prevlen = -1; /* last emitted length */ 
    var curlen; /* length of current code */ 
    var nextlen = tree[1]; /* length of next code */ 
    var count = 0; /* repeat count of the current code */ 
    var max_count = 7; /* max repeat count */ 
    var min_count = 4; /* min repeat count */ 
    /* tree[max_code+1].Len = -1; */ /* guard already set */ if (nextlen === 0) {
        max_count = 138;
        min_count = 3;
    }
    for(n = 0; n <= max_code; n++){
        curlen = nextlen;
        nextlen = tree[(n + 1) * 2 + 1];
        if (++count < max_count && curlen === nextlen) continue;
        else if (count < min_count) do send_code(s, curlen, s.bl_tree);
        while (--count !== 0)
        else if (curlen !== 0) {
            if (curlen !== prevlen) {
                send_code(s, curlen, s.bl_tree);
                count--;
            }
            //Assert(count >= 3 && count <= 6, " 3_6?");
            send_code(s, REP_3_6, s.bl_tree);
            send_bits(s, count - 3, 2);
        } else if (count <= 10) {
            send_code(s, REPZ_3_10, s.bl_tree);
            send_bits(s, count - 3, 3);
        } else {
            send_code(s, REPZ_11_138, s.bl_tree);
            send_bits(s, count - 11, 7);
        }
        count = 0;
        prevlen = curlen;
        if (nextlen === 0) {
            max_count = 138;
            min_count = 3;
        } else if (curlen === nextlen) {
            max_count = 6;
            min_count = 3;
        } else {
            max_count = 7;
            min_count = 4;
        }
    }
}
/* ===========================================================================
 * Construct the Huffman tree for the bit lengths and return the index in
 * bl_order of the last bit length code to send.
 */ function build_bl_tree(s) {
    var max_blindex; /* index of last bit length code of non zero freq */ 
    /* Determine the bit length frequencies for literal and distance trees */ scan_tree(s, s.dyn_ltree, s.l_desc.max_code);
    scan_tree(s, s.dyn_dtree, s.d_desc.max_code);
    /* Build the bit length tree: */ build_tree(s, s.bl_desc);
    /* opt_len now includes the length of the tree representations, except
   * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
   */ /* Determine the number of bit length codes to send. The pkzip format
   * requires that at least 4 bit length codes be sent. (appnote.txt says
   * 3 but the actual value used is 4.)
   */ for(max_blindex = BL_CODES - 1; max_blindex >= 3; max_blindex--){
        if (s.bl_tree[bl_order[max_blindex] * 2 + 1] !== 0) break;
    }
    /* Update opt_len to include the bit length tree and counts */ s.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4;
    //Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
    //        s->opt_len, s->static_len));
    return max_blindex;
}
/* ===========================================================================
 * Send the header for a block using dynamic Huffman trees: the counts, the
 * lengths of the bit length codes, the literal tree and the distance tree.
 * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
 */ function send_all_trees(s, lcodes, dcodes, blcodes) //    deflate_state *s;
//    int lcodes, dcodes, blcodes; /* number of codes for each tree */
{
    var rank; /* index in bl_order */ 
    //Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
    //Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
    //        "too many codes");
    //Tracev((stderr, "\nbl counts: "));
    send_bits(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */ 
    send_bits(s, dcodes - 1, 5);
    send_bits(s, blcodes - 4, 4); /* not -3 as stated in appnote.txt */ 
    for(rank = 0; rank < blcodes; rank++)//Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
    send_bits(s, s.bl_tree[bl_order[rank] * 2 + 1], 3);
    //Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
    send_tree(s, s.dyn_ltree, lcodes - 1); /* literal tree */ 
    //Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
    send_tree(s, s.dyn_dtree, dcodes - 1); /* distance tree */ 
//Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
}
/* ===========================================================================
 * Check if the data type is TEXT or BINARY, using the following algorithm:
 * - TEXT if the two conditions below are satisfied:
 *    a) There are no non-portable control characters belonging to the
 *       "black list" (0..6, 14..25, 28..31).
 *    b) There is at least one printable character belonging to the
 *       "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).
 * - BINARY otherwise.
 * - The following partially-portable control characters form a
 *   "gray list" that is ignored in this detection algorithm:
 *   (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).
 * IN assertion: the fields Freq of dyn_ltree are set.
 */ function detect_data_type(s) {
    /* black_mask is the bit mask of black-listed bytes
   * set bits 0..6, 14..25, and 28..31
   * 0xf3ffc07f = binary 11110011111111111100000001111111
   */ var black_mask = 4093624447;
    var n;
    /* Check for non-textual ("black-listed") bytes. */ for(n = 0; n <= 31; n++, black_mask >>>= 1){
        if (black_mask & 1 && s.dyn_ltree[n * 2] !== 0) return Z_BINARY;
    }
    /* Check for textual ("white-listed") bytes. */ if (s.dyn_ltree[18] !== 0 || s.dyn_ltree[20] !== 0 || s.dyn_ltree[26] !== 0) return Z_TEXT;
    for(n = 32; n < LITERALS; n++){
        if (s.dyn_ltree[n * 2] !== 0) return Z_TEXT;
    }
    /* There are no "black-listed" or "white-listed" bytes:
   * this stream either is empty or has tolerated ("gray-listed") bytes only.
   */ return Z_BINARY;
}
var static_init_done = false;
/* ===========================================================================
 * Initialize the tree data structures for a new zlib stream.
 */ function _tr_init(s) {
    if (!static_init_done) {
        tr_static_init();
        static_init_done = true;
    }
    s.l_desc = new TreeDesc(s.dyn_ltree, static_l_desc);
    s.d_desc = new TreeDesc(s.dyn_dtree, static_d_desc);
    s.bl_desc = new TreeDesc(s.bl_tree, static_bl_desc);
    s.bi_buf = 0;
    s.bi_valid = 0;
    /* Initialize the first block of the first file: */ init_block(s);
}
/* ===========================================================================
 * Send a stored block
 */ function _tr_stored_block(s, buf, stored_len, last) //DeflateState *s;
//charf *buf;       /* input block */
//ulg stored_len;   /* length of input block */
//int last;         /* one if this is the last block for a file */
{
    send_bits(s, (STORED_BLOCK << 1) + (last ? 1 : 0), 3); /* send block type */ 
    copy_block(s, buf, stored_len, true); /* with header */ 
}
/* ===========================================================================
 * Send one empty static block to give enough lookahead for inflate.
 * This takes 10 bits, of which 7 may remain in the bit buffer.
 */ function _tr_align(s) {
    send_bits(s, STATIC_TREES << 1, 3);
    send_code(s, END_BLOCK, static_ltree);
    bi_flush(s);
}
/* ===========================================================================
 * Determine the best encoding for the current block: dynamic trees, static
 * trees or store, and output the encoded block to the zip file.
 */ function _tr_flush_block(s, buf, stored_len, last) //DeflateState *s;
//charf *buf;       /* input block, or NULL if too old */
//ulg stored_len;   /* length of input block */
//int last;         /* one if this is the last block for a file */
{
    var opt_lenb, static_lenb; /* opt_len and static_len in bytes */ 
    var max_blindex = 0; /* index of last bit length code of non zero freq */ 
    /* Build the Huffman trees unless a stored block is forced */ if (s.level > 0) {
        /* Check if the file is binary or text */ if (s.strm.data_type === Z_UNKNOWN) s.strm.data_type = detect_data_type(s);
        /* Construct the literal and distance trees */ build_tree(s, s.l_desc);
        // Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
        //        s->static_len));
        build_tree(s, s.d_desc);
        // Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
        //        s->static_len));
        /* At this point, opt_len and static_len are the total bit lengths of
     * the compressed block data, excluding the tree representations.
     */ /* Build the bit length tree for the above two trees, and get the index
     * in bl_order of the last bit length code to send.
     */ max_blindex = build_bl_tree(s);
        /* Determine the best encoding. Compute the block lengths in bytes. */ opt_lenb = s.opt_len + 3 + 7 >>> 3;
        static_lenb = s.static_len + 3 + 7 >>> 3;
        // Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
        //        opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
        //        s->last_lit));
        if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
    } else // Assert(buf != (char*)0, "lost buf");
    opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ 
    if (stored_len + 4 <= opt_lenb && buf !== -1) /* 4: two words for the lengths */ /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
     * Otherwise we can't have processed more than WSIZE input bytes since
     * the last block flush, because compression would have been
     * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
     * transform a block into a stored block.
     */ _tr_stored_block(s, buf, stored_len, last);
    else if (s.strategy === Z_FIXED || static_lenb === opt_lenb) {
        send_bits(s, (STATIC_TREES << 1) + (last ? 1 : 0), 3);
        compress_block(s, static_ltree, static_dtree);
    } else {
        send_bits(s, (DYN_TREES << 1) + (last ? 1 : 0), 3);
        send_all_trees(s, s.l_desc.max_code + 1, s.d_desc.max_code + 1, max_blindex + 1);
        compress_block(s, s.dyn_ltree, s.dyn_dtree);
    }
    // Assert (s->compressed_len == s->bits_sent, "bad compressed size");
    /* The above check is made mod 2^32, for files larger than 512 MB
   * and uLong implemented on 32 bits.
   */ init_block(s);
    if (last) bi_windup(s);
// Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
//       s->compressed_len-7*last));
}
/* ===========================================================================
 * Save the match info and tally the frequency counts. Return true if
 * the current block must be flushed.
 */ function _tr_tally(s, dist, lc) //    deflate_state *s;
//    unsigned dist;  /* distance of matched string */
//    unsigned lc;    /* match length-MIN_MATCH or unmatched char (if dist==0) */
{
    //var out_length, in_length, dcode;
    s.pending_buf[s.d_buf + s.last_lit * 2] = dist >>> 8 & 255;
    s.pending_buf[s.d_buf + s.last_lit * 2 + 1] = dist & 255;
    s.pending_buf[s.l_buf + s.last_lit] = lc & 255;
    s.last_lit++;
    if (dist === 0) /* lc is the unmatched char */ s.dyn_ltree[lc * 2]++;
    else {
        s.matches++;
        /* Here, lc is the match length - MIN_MATCH */ dist--; /* dist = match distance - 1 */ 
        //Assert((ush)dist < (ush)MAX_DIST(s) &&
        //       (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
        //       (ush)d_code(dist) < (ush)D_CODES,  "_tr_tally: bad match");
        s.dyn_ltree[(_length_code[lc] + LITERALS + 1) * 2]++;
        s.dyn_dtree[d_code(dist) * 2]++;
    }
    // (!) This block is disabled in zlib defaults,
    // don't enable it for binary compatibility
    //#ifdef TRUNCATE_BLOCK
    //  /* Try to guess if it is profitable to stop the current block here */
    //  if ((s.last_lit & 0x1fff) === 0 && s.level > 2) {
    //    /* Compute an upper bound for the compressed length */
    //    out_length = s.last_lit*8;
    //    in_length = s.strstart - s.block_start;
    //
    //    for (dcode = 0; dcode < D_CODES; dcode++) {
    //      out_length += s.dyn_dtree[dcode*2]/*.Freq*/ * (5 + extra_dbits[dcode]);
    //    }
    //    out_length >>>= 3;
    //    //Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
    //    //       s->last_lit, in_length, out_length,
    //    //       100L - out_length*100L/in_length));
    //    if (s.matches < (s.last_lit>>1)/*int /2*/ && out_length < (in_length>>1)/*int /2*/) {
    //      return true;
    //    }
    //  }
    //#endif
    return s.last_lit === s.lit_bufsize - 1;
/* We avoid equality with lit_bufsize because of wraparound at 64K
   * on 16 bit machines and because stored blocks are restricted to
   * 64K-1 bytes.
   */ }
exports._tr_init = _tr_init;
exports._tr_stored_block = _tr_stored_block;
exports._tr_flush_block = _tr_flush_block;
exports._tr_tally = _tr_tally;
exports._tr_align = _tr_align;

},{"../utils/common":"2FpJl"}],"5HolB":[function(require,module,exports) {
'use strict';
// Note: adler32 takes 12% for level 0 and 2% for level 6.
// It isn't worth it to make additional optimizations as in original.
// Small size is preferable.
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
//   claim that you wrote the original software. If you use this software
//   in a product, an acknowledgment in the product documentation would be
//   appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
//   misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
function adler32(adler, buf, len, pos) {
    var s1 = adler & 65535 | 0, s2 = adler >>> 16 & 65535 | 0, n = 0;
    while(len !== 0){
        // Set limit ~ twice less than 5552, to keep
        // s2 in 31-bits, because we force signed ints.
        // in other case %= will fail.
        n = len > 2000 ? 2000 : len;
        len -= n;
        do {
            s1 = s1 + buf[pos++] | 0;
            s2 = s2 + s1 | 0;
        }while (--n)
        s1 %= 65521;
        s2 %= 65521;
    }
    return s1 | s2 << 16 | 0;
}
module.exports = adler32;

},{}],"hlmdd":[function(require,module,exports) {
'use strict';
// Note: we can't get significant speed boost here.
// So write code to minimize size - no pregenerated tables
// and array tools dependencies.
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
//   claim that you wrote the original software. If you use this software
//   in a product, an acknowledgment in the product documentation would be
//   appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
//   misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
// Use ordinary array, since untyped makes no boost here
function makeTable() {
    var c, table = [];
    for(var n = 0; n < 256; n++){
        c = n;
        for(var k = 0; k < 8; k++)c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1;
        table[n] = c;
    }
    return table;
}
// Create table on load. Just 255 signed longs. Not a problem.
var crcTable = makeTable();
function crc32(crc, buf, len, pos) {
    var t = crcTable, end = pos + len;
    crc ^= -1;
    for(var i = pos; i < end; i++)crc = crc >>> 8 ^ t[(crc ^ buf[i]) & 255];
    return crc ^ -1; // >>> 0;
}
module.exports = crc32;

},{}],"4MwdS":[function(require,module,exports) {
'use strict';
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
//   claim that you wrote the original software. If you use this software
//   in a product, an acknowledgment in the product documentation would be
//   appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
//   misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
module.exports = {
    2: 'need dictionary',
    /* Z_NEED_DICT       2  */ 1: 'stream end',
    /* Z_STREAM_END      1  */ 0: '',
    /* Z_OK              0  */ '-1': 'file error',
    /* Z_ERRNO         (-1) */ '-2': 'stream error',
    /* Z_STREAM_ERROR  (-2) */ '-3': 'data error',
    /* Z_DATA_ERROR    (-3) */ '-4': 'insufficient memory',
    /* Z_MEM_ERROR     (-4) */ '-5': 'buffer error',
    /* Z_BUF_ERROR     (-5) */ '-6': 'incompatible version' /* Z_VERSION_ERROR (-6) */ 
};

},{}],"eOURD":[function(require,module,exports) {
// String encode/decode helpers
'use strict';
var utils = require('./common');
// Quick check if we can use fast array to bin string conversion
//
// - apply(Array) can fail on Android 2.2
// - apply(Uint8Array) can fail on iOS 5.1 Safari
//
var STR_APPLY_OK = true;
var STR_APPLY_UIA_OK = true;
try {
    String.fromCharCode.apply(null, [
        0
    ]);
} catch (__) {
    STR_APPLY_OK = false;
}
try {
    String.fromCharCode.apply(null, new Uint8Array(1));
} catch (__1) {
    STR_APPLY_UIA_OK = false;
}
// Table with utf8 lengths (calculated by first byte of sequence)
// Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS,
// because max possible codepoint is 0x10ffff
var _utf8len = new utils.Buf8(256);
for(var q = 0; q < 256; q++)_utf8len[q] = q >= 252 ? 6 : q >= 248 ? 5 : q >= 240 ? 4 : q >= 224 ? 3 : q >= 192 ? 2 : 1;
_utf8len[254] = _utf8len[254] = 1; // Invalid sequence start
// convert string to array (typed, when possible)
exports.string2buf = function(str) {
    var buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0;
    // count binary size
    for(m_pos = 0; m_pos < str_len; m_pos++){
        c = str.charCodeAt(m_pos);
        if ((c & 64512) === 55296 && m_pos + 1 < str_len) {
            c2 = str.charCodeAt(m_pos + 1);
            if ((c2 & 64512) === 56320) {
                c = 65536 + (c - 55296 << 10) + (c2 - 56320);
                m_pos++;
            }
        }
        buf_len += c < 128 ? 1 : c < 2048 ? 2 : c < 65536 ? 3 : 4;
    }
    // allocate buffer
    buf = new utils.Buf8(buf_len);
    // convert
    for(i = 0, m_pos = 0; i < buf_len; m_pos++){
        c = str.charCodeAt(m_pos);
        if ((c & 64512) === 55296 && m_pos + 1 < str_len) {
            c2 = str.charCodeAt(m_pos + 1);
            if ((c2 & 64512) === 56320) {
                c = 65536 + (c - 55296 << 10) + (c2 - 56320);
                m_pos++;
            }
        }
        if (c < 128) /* one byte */ buf[i++] = c;
        else if (c < 2048) {
            /* two bytes */ buf[i++] = 192 | c >>> 6;
            buf[i++] = 128 | c & 63;
        } else if (c < 65536) {
            /* three bytes */ buf[i++] = 224 | c >>> 12;
            buf[i++] = 128 | c >>> 6 & 63;
            buf[i++] = 128 | c & 63;
        } else {
            /* four bytes */ buf[i++] = 240 | c >>> 18;
            buf[i++] = 128 | c >>> 12 & 63;
            buf[i++] = 128 | c >>> 6 & 63;
            buf[i++] = 128 | c & 63;
        }
    }
    return buf;
};
// Helper (used in 2 places)
function buf2binstring(buf, len) {
    // On Chrome, the arguments in a function call that are allowed is `65534`.
    // If the length of the buffer is smaller than that, we can use this optimization,
    // otherwise we will take a slower path.
    if (len < 65534) {
        if (buf.subarray && STR_APPLY_UIA_OK || !buf.subarray && STR_APPLY_OK) return String.fromCharCode.apply(null, utils.shrinkBuf(buf, len));
    }
    var result = '';
    for(var i = 0; i < len; i++)result += String.fromCharCode(buf[i]);
    return result;
}
// Convert byte array to binary string
exports.buf2binstring = function(buf) {
    return buf2binstring(buf, buf.length);
};
// Convert binary string (typed, when possible)
exports.binstring2buf = function(str) {
    var buf = new utils.Buf8(str.length);
    for(var i = 0, len = buf.length; i < len; i++)buf[i] = str.charCodeAt(i);
    return buf;
};
// convert array to string
exports.buf2string = function(buf, max) {
    var i, out, c, c_len;
    var len = max || buf.length;
    // Reserve max possible length (2 words per char)
    // NB: by unknown reasons, Array is significantly faster for
    //     String.fromCharCode.apply than Uint16Array.
    var utf16buf = new Array(len * 2);
    for(out = 0, i = 0; i < len;){
        c = buf[i++];
        // quick process ascii
        if (c < 128) {
            utf16buf[out++] = c;
            continue;
        }
        c_len = _utf8len[c];
        // skip 5 & 6 byte codes
        if (c_len > 4) {
            utf16buf[out++] = 65533;
            i += c_len - 1;
            continue;
        }
        // apply mask on first byte
        c &= c_len === 2 ? 31 : c_len === 3 ? 15 : 7;
        // join the rest
        while(c_len > 1 && i < len){
            c = c << 6 | buf[i++] & 63;
            c_len--;
        }
        // terminated by end of string?
        if (c_len > 1) {
            utf16buf[out++] = 65533;
            continue;
        }
        if (c < 65536) utf16buf[out++] = c;
        else {
            c -= 65536;
            utf16buf[out++] = 55296 | c >> 10 & 1023;
            utf16buf[out++] = 56320 | c & 1023;
        }
    }
    return buf2binstring(utf16buf, out);
};
// Calculate max possible position in utf8 buffer,
// that will not break sequence. If that's not possible
// - (very small limits) return max size as is.
//
// buf[] - utf8 bytes array
// max   - length limit (mandatory);
exports.utf8border = function(buf, max) {
    var pos;
    max = max || buf.length;
    if (max > buf.length) max = buf.length;
    // go back from last position, until start of sequence found
    pos = max - 1;
    while(pos >= 0 && (buf[pos] & 192) === 128)pos--;
    // Very small and broken sequence,
    // return max, because we should return something anyway.
    if (pos < 0) return max;
    // If we came to start of buffer - that means buffer is too small,
    // return max too.
    if (pos === 0) return max;
    return pos + _utf8len[buf[pos]] > max ? pos : max;
};

},{"./common":"2FpJl"}],"8r8Eg":[function(require,module,exports) {
'use strict';
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
//   claim that you wrote the original software. If you use this software
//   in a product, an acknowledgment in the product documentation would be
//   appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
//   misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
function ZStream() {
    /* next input byte */ this.input = null; // JS specific, because we have no pointers
    this.next_in = 0;
    /* number of bytes available at input */ this.avail_in = 0;
    /* total number of input bytes read so far */ this.total_in = 0;
    /* next output byte should be put there */ this.output = null; // JS specific, because we have no pointers
    this.next_out = 0;
    /* remaining free space at output */ this.avail_out = 0;
    /* total number of bytes output so far */ this.total_out = 0;
    /* last error message, NULL if no error */ this.msg = '' /*Z_NULL*/ ;
    /* not visible by applications */ this.state = null;
    /* best guess about the data type: binary or text */ this.data_type = 2 /*Z_UNKNOWN*/ ;
    /* adler32 value of the uncompressed data */ this.adler = 0;
}
module.exports = ZStream;

},{}],"gcpcv":[function(require,module,exports) {
'use strict';
var zlib_inflate = require('./zlib/inflate');
var utils = require('./utils/common');
var strings = require('./utils/strings');
var c = require('./zlib/constants');
var msg = require('./zlib/messages');
var ZStream = require('./zlib/zstream');
var GZheader = require('./zlib/gzheader');
var toString = Object.prototype.toString;
/**
 * class Inflate
 *
 * Generic JS-style wrapper for zlib calls. If you don't need
 * streaming behaviour - use more simple functions: [[inflate]]
 * and [[inflateRaw]].
 **/ /* internal
 * inflate.chunks -> Array
 *
 * Chunks of output data, if [[Inflate#onData]] not overridden.
 **/ /**
 * Inflate.result -> Uint8Array|Array|String
 *
 * Uncompressed result, generated by default [[Inflate#onData]]
 * and [[Inflate#onEnd]] handlers. Filled after you push last chunk
 * (call [[Inflate#push]] with `Z_FINISH` / `true` param) or if you
 * push a chunk with explicit flush (call [[Inflate#push]] with
 * `Z_SYNC_FLUSH` param).
 **/ /**
 * Inflate.err -> Number
 *
 * Error code after inflate finished. 0 (Z_OK) on success.
 * Should be checked if broken data possible.
 **/ /**
 * Inflate.msg -> String
 *
 * Error message, if [[Inflate.err]] != 0
 **/ /**
 * new Inflate(options)
 * - options (Object): zlib inflate options.
 *
 * Creates new inflator instance with specified params. Throws exception
 * on bad params. Supported options:
 *
 * - `windowBits`
 * - `dictionary`
 *
 * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)
 * for more information on these.
 *
 * Additional options, for internal needs:
 *
 * - `chunkSize` - size of generated data chunks (16K by default)
 * - `raw` (Boolean) - do raw inflate
 * - `to` (String) - if equal to 'string', then result will be converted
 *   from utf8 to utf16 (javascript) string. When string output requested,
 *   chunk length can differ from `chunkSize`, depending on content.
 *
 * By default, when no options set, autodetect deflate/gzip data format via
 * wrapper header.
 *
 * ##### Example:
 *
 * ```javascript
 * var pako = require('pako')
 *   , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9])
 *   , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]);
 *
 * var inflate = new pako.Inflate({ level: 3});
 *
 * inflate.push(chunk1, false);
 * inflate.push(chunk2, true);  // true -> last chunk
 *
 * if (inflate.err) { throw new Error(inflate.err); }
 *
 * console.log(inflate.result);
 * ```
 **/ function Inflate(options) {
    if (!(this instanceof Inflate)) return new Inflate(options);
    this.options = utils.assign({
        chunkSize: 16384,
        windowBits: 0,
        to: ''
    }, options || {
    });
    var opt = this.options;
    // Force window size for `raw` data, if not set directly,
    // because we have no header for autodetect.
    if (opt.raw && opt.windowBits >= 0 && opt.windowBits < 16) {
        opt.windowBits = -opt.windowBits;
        if (opt.windowBits === 0) opt.windowBits = -15;
    }
    // If `windowBits` not defined (and mode not raw) - set autodetect flag for gzip/deflate
    if (opt.windowBits >= 0 && opt.windowBits < 16 && !(options && options.windowBits)) opt.windowBits += 32;
    // Gzip header has no info about windows size, we can do autodetect only
    // for deflate. So, if window size not set, force it to max when gzip possible
    if (opt.windowBits > 15 && opt.windowBits < 48) // bit 3 (16) -> gzipped data
    // bit 4 (32) -> autodetect gzip/deflate
    {
        if ((opt.windowBits & 15) === 0) opt.windowBits |= 15;
    }
    this.err = 0; // error code, if happens (0 = Z_OK)
    this.msg = ''; // error message
    this.ended = false; // used to avoid multiple onEnd() calls
    this.chunks = []; // chunks of compressed data
    this.strm = new ZStream();
    this.strm.avail_out = 0;
    var status = zlib_inflate.inflateInit2(this.strm, opt.windowBits);
    if (status !== c.Z_OK) throw new Error(msg[status]);
    this.header = new GZheader();
    zlib_inflate.inflateGetHeader(this.strm, this.header);
    // Setup dictionary
    if (opt.dictionary) {
        // Convert data if needed
        if (typeof opt.dictionary === 'string') opt.dictionary = strings.string2buf(opt.dictionary);
        else if (toString.call(opt.dictionary) === '[object ArrayBuffer]') opt.dictionary = new Uint8Array(opt.dictionary);
        if (opt.raw) {
            status = zlib_inflate.inflateSetDictionary(this.strm, opt.dictionary);
            if (status !== c.Z_OK) throw new Error(msg[status]);
        }
    }
}
/**
 * Inflate#push(data[, mode]) -> Boolean
 * - data (Uint8Array|Array|ArrayBuffer|String): input data
 * - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes.
 *   See constants. Skipped or `false` means Z_NO_FLUSH, `true` means Z_FINISH.
 *
 * Sends input data to inflate pipe, generating [[Inflate#onData]] calls with
 * new output chunks. Returns `true` on success. The last data block must have
 * mode Z_FINISH (or `true`). That will flush internal pending buffers and call
 * [[Inflate#onEnd]]. For interim explicit flushes (without ending the stream) you
 * can use mode Z_SYNC_FLUSH, keeping the decompression context.
 *
 * On fail call [[Inflate#onEnd]] with error code and return false.
 *
 * We strongly recommend to use `Uint8Array` on input for best speed (output
 * format is detected automatically). Also, don't skip last param and always
 * use the same type in your code (boolean or number). That will improve JS speed.
 *
 * For regular `Array`-s make sure all elements are [0..255].
 *
 * ##### Example
 *
 * ```javascript
 * push(chunk, false); // push one of data chunks
 * ...
 * push(chunk, true);  // push last chunk
 * ```
 **/ Inflate.prototype.push = function(data, mode) {
    var strm = this.strm;
    var chunkSize = this.options.chunkSize;
    var dictionary = this.options.dictionary;
    var status, _mode;
    var next_out_utf8, tail, utf8str;
    // Flag to properly process Z_BUF_ERROR on testing inflate call
    // when we check that all output data was flushed.
    var allowBufError = false;
    if (this.ended) return false;
    _mode = mode === ~~mode ? mode : mode === true ? c.Z_FINISH : c.Z_NO_FLUSH;
    // Convert data if needed
    if (typeof data === 'string') // Only binary strings can be decompressed on practice
    strm.input = strings.binstring2buf(data);
    else if (toString.call(data) === '[object ArrayBuffer]') strm.input = new Uint8Array(data);
    else strm.input = data;
    strm.next_in = 0;
    strm.avail_in = strm.input.length;
    do {
        if (strm.avail_out === 0) {
            strm.output = new utils.Buf8(chunkSize);
            strm.next_out = 0;
            strm.avail_out = chunkSize;
        }
        status = zlib_inflate.inflate(strm, c.Z_NO_FLUSH); /* no bad return value */ 
        if (status === c.Z_NEED_DICT && dictionary) status = zlib_inflate.inflateSetDictionary(this.strm, dictionary);
        if (status === c.Z_BUF_ERROR && allowBufError === true) {
            status = c.Z_OK;
            allowBufError = false;
        }
        if (status !== c.Z_STREAM_END && status !== c.Z_OK) {
            this.onEnd(status);
            this.ended = true;
            return false;
        }
        if (strm.next_out) {
            if (strm.avail_out === 0 || status === c.Z_STREAM_END || strm.avail_in === 0 && (_mode === c.Z_FINISH || _mode === c.Z_SYNC_FLUSH)) {
                if (this.options.to === 'string') {
                    next_out_utf8 = strings.utf8border(strm.output, strm.next_out);
                    tail = strm.next_out - next_out_utf8;
                    utf8str = strings.buf2string(strm.output, next_out_utf8);
                    // move tail
                    strm.next_out = tail;
                    strm.avail_out = chunkSize - tail;
                    if (tail) utils.arraySet(strm.output, strm.output, next_out_utf8, tail, 0);
                    this.onData(utf8str);
                } else this.onData(utils.shrinkBuf(strm.output, strm.next_out));
            }
        }
        // When no more input data, we should check that internal inflate buffers
        // are flushed. The only way to do it when avail_out = 0 - run one more
        // inflate pass. But if output data not exists, inflate return Z_BUF_ERROR.
        // Here we set flag to process this error properly.
        //
        // NOTE. Deflate does not return error in this case and does not needs such
        // logic.
        if (strm.avail_in === 0 && strm.avail_out === 0) allowBufError = true;
    }while ((strm.avail_in > 0 || strm.avail_out === 0) && status !== c.Z_STREAM_END)
    if (status === c.Z_STREAM_END) _mode = c.Z_FINISH;
    // Finalize on the last chunk.
    if (_mode === c.Z_FINISH) {
        status = zlib_inflate.inflateEnd(this.strm);
        this.onEnd(status);
        this.ended = true;
        return status === c.Z_OK;
    }
    // callback interim results if Z_SYNC_FLUSH.
    if (_mode === c.Z_SYNC_FLUSH) {
        this.onEnd(c.Z_OK);
        strm.avail_out = 0;
        return true;
    }
    return true;
};
/**
 * Inflate#onData(chunk) -> Void
 * - chunk (Uint8Array|Array|String): output data. Type of array depends
 *   on js engine support. When string output requested, each chunk
 *   will be string.
 *
 * By default, stores data blocks in `chunks[]` property and glue
 * those in `onEnd`. Override this handler, if you need another behaviour.
 **/ Inflate.prototype.onData = function(chunk) {
    this.chunks.push(chunk);
};
/**
 * Inflate#onEnd(status) -> Void
 * - status (Number): inflate status. 0 (Z_OK) on success,
 *   other if not.
 *
 * Called either after you tell inflate that the input stream is
 * complete (Z_FINISH) or should be flushed (Z_SYNC_FLUSH)
 * or if an error happened. By default - join collected chunks,
 * free memory and fill `results` / `err` properties.
 **/ Inflate.prototype.onEnd = function(status) {
    // On success - join
    if (status === c.Z_OK) {
        if (this.options.to === 'string') // Glue & convert here, until we teach pako to send
        // utf8 aligned strings to onData
        this.result = this.chunks.join('');
        else this.result = utils.flattenChunks(this.chunks);
    }
    this.chunks = [];
    this.err = status;
    this.msg = this.strm.msg;
};
/**
 * inflate(data[, options]) -> Uint8Array|Array|String
 * - data (Uint8Array|Array|String): input data to decompress.
 * - options (Object): zlib inflate options.
 *
 * Decompress `data` with inflate/ungzip and `options`. Autodetect
 * format via wrapper header by default. That's why we don't provide
 * separate `ungzip` method.
 *
 * Supported options are:
 *
 * - windowBits
 *
 * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)
 * for more information.
 *
 * Sugar (options):
 *
 * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify
 *   negative windowBits implicitly.
 * - `to` (String) - if equal to 'string', then result will be converted
 *   from utf8 to utf16 (javascript) string. When string output requested,
 *   chunk length can differ from `chunkSize`, depending on content.
 *
 *
 * ##### Example:
 *
 * ```javascript
 * var pako = require('pako')
 *   , input = pako.deflate([1,2,3,4,5,6,7,8,9])
 *   , output;
 *
 * try {
 *   output = pako.inflate(input);
 * } catch (err)
 *   console.log(err);
 * }
 * ```
 **/ function inflate(input, options) {
    var inflator = new Inflate(options);
    inflator.push(input, true);
    // That will never happens, if you don't cheat with options :)
    if (inflator.err) throw inflator.msg || msg[inflator.err];
    return inflator.result;
}
/**
 * inflateRaw(data[, options]) -> Uint8Array|Array|String
 * - data (Uint8Array|Array|String): input data to decompress.
 * - options (Object): zlib inflate options.
 *
 * The same as [[inflate]], but creates raw data, without wrapper
 * (header and adler32 crc).
 **/ function inflateRaw(input, options) {
    options = options || {
    };
    options.raw = true;
    return inflate(input, options);
}
/**
 * ungzip(data[, options]) -> Uint8Array|Array|String
 * - data (Uint8Array|Array|String): input data to decompress.
 * - options (Object): zlib inflate options.
 *
 * Just shortcut to [[inflate]], because it autodetects format
 * by header.content. Done for convenience.
 **/ exports.Inflate = Inflate;
exports.inflate = inflate;
exports.inflateRaw = inflateRaw;
exports.ungzip = inflate;

},{"./zlib/inflate":"8HcC4","./utils/common":"2FpJl","./utils/strings":"eOURD","./zlib/constants":"dfW1p","./zlib/messages":"4MwdS","./zlib/zstream":"8r8Eg","./zlib/gzheader":"5Gi15"}],"8HcC4":[function(require,module,exports) {
'use strict';
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
//   claim that you wrote the original software. If you use this software
//   in a product, an acknowledgment in the product documentation would be
//   appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
//   misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
var utils = require('../utils/common');
var adler32 = require('./adler32');
var crc32 = require('./crc32');
var inflate_fast = require('./inffast');
var inflate_table = require('./inftrees');
var CODES = 0;
var LENS = 1;
var DISTS = 2;
/* Public constants ==========================================================*/ /* ===========================================================================*/ /* Allowed flush values; see deflate() and inflate() below for details */ //var Z_NO_FLUSH      = 0;
//var Z_PARTIAL_FLUSH = 1;
//var Z_SYNC_FLUSH    = 2;
//var Z_FULL_FLUSH    = 3;
var Z_FINISH = 4;
var Z_BLOCK = 5;
var Z_TREES = 6;
/* Return codes for the compression/decompression functions. Negative values
 * are errors, positive values are used for special but normal events.
 */ var Z_OK = 0;
var Z_STREAM_END = 1;
var Z_NEED_DICT = 2;
//var Z_ERRNO         = -1;
var Z_STREAM_ERROR = -2;
var Z_DATA_ERROR = -3;
var Z_MEM_ERROR = -4;
var Z_BUF_ERROR = -5;
//var Z_VERSION_ERROR = -6;
/* The deflate compression method */ var Z_DEFLATED = 8;
/* STATES ====================================================================*/ /* ===========================================================================*/ var HEAD = 1; /* i: waiting for magic header */ 
var FLAGS = 2; /* i: waiting for method and flags (gzip) */ 
var TIME = 3; /* i: waiting for modification time (gzip) */ 
var OS = 4; /* i: waiting for extra flags and operating system (gzip) */ 
var EXLEN = 5; /* i: waiting for extra length (gzip) */ 
var EXTRA = 6; /* i: waiting for extra bytes (gzip) */ 
var NAME = 7; /* i: waiting for end of file name (gzip) */ 
var COMMENT = 8; /* i: waiting for end of comment (gzip) */ 
var HCRC = 9; /* i: waiting for header crc (gzip) */ 
var DICTID = 10; /* i: waiting for dictionary check value */ 
var DICT = 11; /* waiting for inflateSetDictionary() call */ 
var TYPE = 12; /* i: waiting for type bits, including last-flag bit */ 
var TYPEDO = 13; /* i: same, but skip check to exit inflate on new block */ 
var STORED = 14; /* i: waiting for stored size (length and complement) */ 
var COPY_ = 15; /* i/o: same as COPY below, but only first time in */ 
var COPY = 16; /* i/o: waiting for input or output to copy stored block */ 
var TABLE = 17; /* i: waiting for dynamic block table lengths */ 
var LENLENS = 18; /* i: waiting for code length code lengths */ 
var CODELENS = 19; /* i: waiting for length/lit and distance code lengths */ 
var LEN_ = 20; /* i: same as LEN below, but only first time in */ 
var LEN = 21; /* i: waiting for length/lit/eob code */ 
var LENEXT = 22; /* i: waiting for length extra bits */ 
var DIST = 23; /* i: waiting for distance code */ 
var DISTEXT = 24; /* i: waiting for distance extra bits */ 
var MATCH = 25; /* o: waiting for output space to copy string */ 
var LIT = 26; /* o: waiting for output space to write literal */ 
var CHECK = 27; /* i: waiting for 32-bit check value */ 
var LENGTH = 28; /* i: waiting for 32-bit length (gzip) */ 
var DONE = 29; /* finished check, done -- remain here until reset */ 
var BAD = 30; /* got a data error -- remain here until reset */ 
var MEM = 31; /* got an inflate() memory error -- remain here until reset */ 
var SYNC = 32; /* looking for synchronization bytes to restart inflate() */ 
/* ===========================================================================*/ var ENOUGH_LENS = 852;
var ENOUGH_DISTS = 592;
//var ENOUGH =  (ENOUGH_LENS+ENOUGH_DISTS);
var MAX_WBITS = 15;
/* 32K LZ77 window */ var DEF_WBITS = MAX_WBITS;
function zswap32(q) {
    return (q >>> 24 & 255) + (q >>> 8 & 65280) + ((q & 65280) << 8) + ((q & 255) << 24);
}
function InflateState() {
    this.mode = 0; /* current inflate mode */ 
    this.last = false; /* true if processing last block */ 
    this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */ 
    this.havedict = false; /* true if dictionary provided */ 
    this.flags = 0; /* gzip header method and flags (0 if zlib) */ 
    this.dmax = 0; /* zlib header max distance (INFLATE_STRICT) */ 
    this.check = 0; /* protected copy of check value */ 
    this.total = 0; /* protected copy of output count */ 
    // TODO: may be {}
    this.head = null; /* where to save gzip header information */ 
    /* sliding window */ this.wbits = 0; /* log base 2 of requested window size */ 
    this.wsize = 0; /* window size or zero if not using window */ 
    this.whave = 0; /* valid bytes in the window */ 
    this.wnext = 0; /* window write index */ 
    this.window = null; /* allocated sliding window, if needed */ 
    /* bit accumulator */ this.hold = 0; /* input bit accumulator */ 
    this.bits = 0; /* number of bits in "in" */ 
    /* for string and stored block copying */ this.length = 0; /* literal or length of data to copy */ 
    this.offset = 0; /* distance back to copy string from */ 
    /* for table and code decoding */ this.extra = 0; /* extra bits needed */ 
    /* fixed and dynamic code tables */ this.lencode = null; /* starting table for length/literal codes */ 
    this.distcode = null; /* starting table for distance codes */ 
    this.lenbits = 0; /* index bits for lencode */ 
    this.distbits = 0; /* index bits for distcode */ 
    /* dynamic table building */ this.ncode = 0; /* number of code length code lengths */ 
    this.nlen = 0; /* number of length code lengths */ 
    this.ndist = 0; /* number of distance code lengths */ 
    this.have = 0; /* number of code lengths in lens[] */ 
    this.next = null; /* next available space in codes[] */ 
    this.lens = new utils.Buf16(320); /* temporary storage for code lengths */ 
    this.work = new utils.Buf16(288); /* work area for code table building */ 
    /*
   because we don't have pointers in js, we use lencode and distcode directly
   as buffers so we don't need codes
  */ //this.codes = new utils.Buf32(ENOUGH);       /* space for code tables */
    this.lendyn = null; /* dynamic table for length/literal codes (JS specific) */ 
    this.distdyn = null; /* dynamic table for distance codes (JS specific) */ 
    this.sane = 0; /* if false, allow invalid distance too far */ 
    this.back = 0; /* bits back of last unprocessed length/lit */ 
    this.was = 0; /* initial length of match */ 
}
function inflateResetKeep(strm) {
    var state;
    if (!strm || !strm.state) return Z_STREAM_ERROR;
    state = strm.state;
    strm.total_in = strm.total_out = state.total = 0;
    strm.msg = ''; /*Z_NULL*/ 
    if (state.wrap) strm.adler = state.wrap & 1;
    state.mode = HEAD;
    state.last = 0;
    state.havedict = 0;
    state.dmax = 32768;
    state.head = null;
    state.hold = 0;
    state.bits = 0;
    //state.lencode = state.distcode = state.next = state.codes;
    state.lencode = state.lendyn = new utils.Buf32(ENOUGH_LENS);
    state.distcode = state.distdyn = new utils.Buf32(ENOUGH_DISTS);
    state.sane = 1;
    state.back = -1;
    //Tracev((stderr, "inflate: reset\n"));
    return Z_OK;
}
function inflateReset(strm) {
    var state;
    if (!strm || !strm.state) return Z_STREAM_ERROR;
    state = strm.state;
    state.wsize = 0;
    state.whave = 0;
    state.wnext = 0;
    return inflateResetKeep(strm);
}
function inflateReset2(strm, windowBits) {
    var wrap;
    var state;
    /* get the state */ if (!strm || !strm.state) return Z_STREAM_ERROR;
    state = strm.state;
    /* extract wrap request from windowBits parameter */ if (windowBits < 0) {
        wrap = 0;
        windowBits = -windowBits;
    } else {
        wrap = (windowBits >> 4) + 1;
        if (windowBits < 48) windowBits &= 15;
    }
    /* set number of window bits, free window if different */ if (windowBits && (windowBits < 8 || windowBits > 15)) return Z_STREAM_ERROR;
    if (state.window !== null && state.wbits !== windowBits) state.window = null;
    /* update state and reset the rest of it */ state.wrap = wrap;
    state.wbits = windowBits;
    return inflateReset(strm);
}
function inflateInit2(strm, windowBits) {
    var ret;
    var state;
    if (!strm) return Z_STREAM_ERROR;
    //strm.msg = Z_NULL;                 /* in case we return an error */
    state = new InflateState();
    //if (state === Z_NULL) return Z_MEM_ERROR;
    //Tracev((stderr, "inflate: allocated\n"));
    strm.state = state;
    state.window = null;
    ret = inflateReset2(strm, windowBits);
    if (ret !== Z_OK) strm.state = null;
    return ret;
}
function inflateInit(strm) {
    return inflateInit2(strm, DEF_WBITS);
}
/*
 Return state with length and distance decoding tables and index sizes set to
 fixed code decoding.  Normally this returns fixed tables from inffixed.h.
 If BUILDFIXED is defined, then instead this routine builds the tables the
 first time it's called, and returns those tables the first time and
 thereafter.  This reduces the size of the code by about 2K bytes, in
 exchange for a little execution time.  However, BUILDFIXED should not be
 used for threaded applications, since the rewriting of the tables and virgin
 may not be thread-safe.
 */ var virgin = true;
var lenfix, distfix; // We have no pointers in JS, so keep tables separate
function fixedtables(state) {
    /* build fixed huffman tables if first call (may not be thread safe) */ if (virgin) {
        var sym;
        lenfix = new utils.Buf32(512);
        distfix = new utils.Buf32(32);
        /* literal/length table */ sym = 0;
        while(sym < 144)state.lens[sym++] = 8;
        while(sym < 256)state.lens[sym++] = 9;
        while(sym < 280)state.lens[sym++] = 7;
        while(sym < 288)state.lens[sym++] = 8;
        inflate_table(LENS, state.lens, 0, 288, lenfix, 0, state.work, {
            bits: 9
        });
        /* distance table */ sym = 0;
        while(sym < 32)state.lens[sym++] = 5;
        inflate_table(DISTS, state.lens, 0, 32, distfix, 0, state.work, {
            bits: 5
        });
        /* do this just once */ virgin = false;
    }
    state.lencode = lenfix;
    state.lenbits = 9;
    state.distcode = distfix;
    state.distbits = 5;
}
/*
 Update the window with the last wsize (normally 32K) bytes written before
 returning.  If window does not exist yet, create it.  This is only called
 when a window is already in use, or when output has been written during this
 inflate call, but the end of the deflate stream has not been reached yet.
 It is also called to create a window for dictionary data when a dictionary
 is loaded.

 Providing output buffers larger than 32K to inflate() should provide a speed
 advantage, since only the last 32K of output is copied to the sliding window
 upon return from inflate(), and since all distances after the first 32K of
 output will fall in the output data, making match copies simpler and faster.
 The advantage may be dependent on the size of the processor's data caches.
 */ function updatewindow(strm, src, end, copy) {
    var dist;
    var state = strm.state;
    /* if it hasn't been done already, allocate space for the window */ if (state.window === null) {
        state.wsize = 1 << state.wbits;
        state.wnext = 0;
        state.whave = 0;
        state.window = new utils.Buf8(state.wsize);
    }
    /* copy state->wsize or less output bytes into the circular window */ if (copy >= state.wsize) {
        utils.arraySet(state.window, src, end - state.wsize, state.wsize, 0);
        state.wnext = 0;
        state.whave = state.wsize;
    } else {
        dist = state.wsize - state.wnext;
        if (dist > copy) dist = copy;
        //zmemcpy(state->window + state->wnext, end - copy, dist);
        utils.arraySet(state.window, src, end - copy, dist, state.wnext);
        copy -= dist;
        if (copy) {
            //zmemcpy(state->window, end - copy, copy);
            utils.arraySet(state.window, src, end - copy, copy, 0);
            state.wnext = copy;
            state.whave = state.wsize;
        } else {
            state.wnext += dist;
            if (state.wnext === state.wsize) state.wnext = 0;
            if (state.whave < state.wsize) state.whave += dist;
        }
    }
    return 0;
}
function inflate(strm, flush) {
    var state;
    var input, output; // input/output buffers
    var next; /* next input INDEX */ 
    var put; /* next output INDEX */ 
    var have, left; /* available input and output */ 
    var hold; /* bit buffer */ 
    var bits; /* bits in bit buffer */ 
    var _in, _out; /* save starting available input and output */ 
    var copy; /* number of stored or match bytes to copy */ 
    var from; /* where to copy match bytes from */ 
    var from_source;
    var here = 0; /* current decoding table entry */ 
    var here_bits, here_op, here_val; // paked "here" denormalized (JS specific)
    //var last;                   /* parent table entry */
    var last_bits, last_op, last_val; // paked "last" denormalized (JS specific)
    var len; /* length to copy for repeats, bits to drop */ 
    var ret; /* return code */ 
    var hbuf = new utils.Buf8(4); /* buffer for gzip header crc calculation */ 
    var opts;
    var n; // temporary var for NEED_BITS
    var order = /* permutation of code lengths */ [
        16,
        17,
        18,
        0,
        8,
        7,
        9,
        6,
        10,
        5,
        11,
        4,
        12,
        3,
        13,
        2,
        14,
        1,
        15
    ];
    if (!strm || !strm.state || !strm.output || !strm.input && strm.avail_in !== 0) return Z_STREAM_ERROR;
    state = strm.state;
    if (state.mode === TYPE) state.mode = TYPEDO;
     /* skip check */ 
    //--- LOAD() ---
    put = strm.next_out;
    output = strm.output;
    left = strm.avail_out;
    next = strm.next_in;
    input = strm.input;
    have = strm.avail_in;
    hold = state.hold;
    bits = state.bits;
    //---
    _in = have;
    _out = left;
    ret = Z_OK;
    inf_leave: for(;;)switch(state.mode){
        case HEAD:
            if (state.wrap === 0) {
                state.mode = TYPEDO;
                break;
            }
            //=== NEEDBITS(16);
            while(bits < 16){
                if (have === 0) break inf_leave;
                have--;
                hold += input[next++] << bits;
                bits += 8;
            }
            //===//
            if (state.wrap & 2 && hold === 35615) {
                state.check = 0 /*crc32(0L, Z_NULL, 0)*/ ;
                //=== CRC2(state.check, hold);
                hbuf[0] = hold & 255;
                hbuf[1] = hold >>> 8 & 255;
                state.check = crc32(state.check, hbuf, 2, 0);
                //===//
                //=== INITBITS();
                hold = 0;
                bits = 0;
                //===//
                state.mode = FLAGS;
                break;
            }
            state.flags = 0; /* expect zlib header */ 
            if (state.head) state.head.done = false;
            if (!(state.wrap & 1) || /* check if zlib header allowed */ (((hold & 255) << 8) + (hold >> 8)) % 31) {
                strm.msg = 'incorrect header check';
                state.mode = BAD;
                break;
            }
            if ((hold & 15) !== Z_DEFLATED) {
                strm.msg = 'unknown compression method';
                state.mode = BAD;
                break;
            }
            //--- DROPBITS(4) ---//
            hold >>>= 4;
            bits -= 4;
            //---//
            len = (hold & 15) + 8;
            if (state.wbits === 0) state.wbits = len;
            else if (len > state.wbits) {
                strm.msg = 'invalid window size';
                state.mode = BAD;
                break;
            }
            state.dmax = 1 << len;
            //Tracev((stderr, "inflate:   zlib header ok\n"));
            strm.adler = state.check = 1 /*adler32(0L, Z_NULL, 0)*/ ;
            state.mode = hold & 512 ? DICTID : TYPE;
            //=== INITBITS();
            hold = 0;
            bits = 0;
            break;
        case FLAGS:
            //=== NEEDBITS(16); */
            while(bits < 16){
                if (have === 0) break inf_leave;
                have--;
                hold += input[next++] << bits;
                bits += 8;
            }
            //===//
            state.flags = hold;
            if ((state.flags & 255) !== Z_DEFLATED) {
                strm.msg = 'unknown compression method';
                state.mode = BAD;
                break;
            }
            if (state.flags & 57344) {
                strm.msg = 'unknown header flags set';
                state.mode = BAD;
                break;
            }
            if (state.head) state.head.text = hold >> 8 & 1;
            if (state.flags & 512) {
                //=== CRC2(state.check, hold);
                hbuf[0] = hold & 255;
                hbuf[1] = hold >>> 8 & 255;
                state.check = crc32(state.check, hbuf, 2, 0);
            //===//
            }
            //=== INITBITS();
            hold = 0;
            bits = 0;
            //===//
            state.mode = TIME;
        /* falls through */ case TIME:
            //=== NEEDBITS(32); */
            while(bits < 32){
                if (have === 0) break inf_leave;
                have--;
                hold += input[next++] << bits;
                bits += 8;
            }
            //===//
            if (state.head) state.head.time = hold;
            if (state.flags & 512) {
                //=== CRC4(state.check, hold)
                hbuf[0] = hold & 255;
                hbuf[1] = hold >>> 8 & 255;
                hbuf[2] = hold >>> 16 & 255;
                hbuf[3] = hold >>> 24 & 255;
                state.check = crc32(state.check, hbuf, 4, 0);
            //===
            }
            //=== INITBITS();
            hold = 0;
            bits = 0;
            //===//
            state.mode = OS;
        /* falls through */ case OS:
            //=== NEEDBITS(16); */
            while(bits < 16){
                if (have === 0) break inf_leave;
                have--;
                hold += input[next++] << bits;
                bits += 8;
            }
            //===//
            if (state.head) {
                state.head.xflags = hold & 255;
                state.head.os = hold >> 8;
            }
            if (state.flags & 512) {
                //=== CRC2(state.check, hold);
                hbuf[0] = hold & 255;
                hbuf[1] = hold >>> 8 & 255;
                state.check = crc32(state.check, hbuf, 2, 0);
            //===//
            }
            //=== INITBITS();
            hold = 0;
            bits = 0;
            //===//
            state.mode = EXLEN;
        /* falls through */ case EXLEN:
            if (state.flags & 1024) {
                //=== NEEDBITS(16); */
                while(bits < 16){
                    if (have === 0) break inf_leave;
                    have--;
                    hold += input[next++] << bits;
                    bits += 8;
                }
                //===//
                state.length = hold;
                if (state.head) state.head.extra_len = hold;
                if (state.flags & 512) {
                    //=== CRC2(state.check, hold);
                    hbuf[0] = hold & 255;
                    hbuf[1] = hold >>> 8 & 255;
                    state.check = crc32(state.check, hbuf, 2, 0);
                //===//
                }
                //=== INITBITS();
                hold = 0;
                bits = 0;
            //===//
            } else if (state.head) state.head.extra = null;
            state.mode = EXTRA;
        /* falls through */ case EXTRA:
            if (state.flags & 1024) {
                copy = state.length;
                if (copy > have) copy = have;
                if (copy) {
                    if (state.head) {
                        len = state.head.extra_len - state.length;
                        if (!state.head.extra) // Use untyped array for more convenient processing later
                        state.head.extra = new Array(state.head.extra_len);
                        utils.arraySet(state.head.extra, input, next, // extra field is limited to 65536 bytes
                        // - no need for additional size check
                        copy, /*len + copy > state.head.extra_max - len ? state.head.extra_max : copy,*/ len);
                    //zmemcpy(state.head.extra + len, next,
                    //        len + copy > state.head.extra_max ?
                    //        state.head.extra_max - len : copy);
                    }
                    if (state.flags & 512) state.check = crc32(state.check, input, copy, next);
                    have -= copy;
                    next += copy;
                    state.length -= copy;
                }
                if (state.length) break inf_leave;
            }
            state.length = 0;
            state.mode = NAME;
        /* falls through */ case NAME:
            if (state.flags & 2048) {
                if (have === 0) break inf_leave;
                copy = 0;
                do {
                    // TODO: 2 or 1 bytes?
                    len = input[next + copy++];
                    /* use constant limit because in js we should not preallocate memory */ if (state.head && len && state.length < 65536 /*state.head.name_max*/ ) state.head.name += String.fromCharCode(len);
                }while (len && copy < have)
                if (state.flags & 512) state.check = crc32(state.check, input, copy, next);
                have -= copy;
                next += copy;
                if (len) break inf_leave;
            } else if (state.head) state.head.name = null;
            state.length = 0;
            state.mode = COMMENT;
        /* falls through */ case COMMENT:
            if (state.flags & 4096) {
                if (have === 0) break inf_leave;
                copy = 0;
                do {
                    len = input[next + copy++];
                    /* use constant limit because in js we should not preallocate memory */ if (state.head && len && state.length < 65536 /*state.head.comm_max*/ ) state.head.comment += String.fromCharCode(len);
                }while (len && copy < have)
                if (state.flags & 512) state.check = crc32(state.check, input, copy, next);
                have -= copy;
                next += copy;
                if (len) break inf_leave;
            } else if (state.head) state.head.comment = null;
            state.mode = HCRC;
        /* falls through */ case HCRC:
            if (state.flags & 512) {
                //=== NEEDBITS(16); */
                while(bits < 16){
                    if (have === 0) break inf_leave;
                    have--;
                    hold += input[next++] << bits;
                    bits += 8;
                }
                //===//
                if (hold !== (state.check & 65535)) {
                    strm.msg = 'header crc mismatch';
                    state.mode = BAD;
                    break;
                }
                //=== INITBITS();
                hold = 0;
                bits = 0;
            //===//
            }
            if (state.head) {
                state.head.hcrc = state.flags >> 9 & 1;
                state.head.done = true;
            }
            strm.adler = state.check = 0;
            state.mode = TYPE;
            break;
        case DICTID:
            //=== NEEDBITS(32); */
            while(bits < 32){
                if (have === 0) break inf_leave;
                have--;
                hold += input[next++] << bits;
                bits += 8;
            }
            //===//
            strm.adler = state.check = zswap32(hold);
            //=== INITBITS();
            hold = 0;
            bits = 0;
            //===//
            state.mode = DICT;
        /* falls through */ case DICT:
            if (state.havedict === 0) {
                //--- RESTORE() ---
                strm.next_out = put;
                strm.avail_out = left;
                strm.next_in = next;
                strm.avail_in = have;
                state.hold = hold;
                state.bits = bits;
                //---
                return Z_NEED_DICT;
            }
            strm.adler = state.check = 1 /*adler32(0L, Z_NULL, 0)*/ ;
            state.mode = TYPE;
        /* falls through */ case TYPE:
            if (flush === Z_BLOCK || flush === Z_TREES) break inf_leave;
        /* falls through */ case TYPEDO:
            if (state.last) {
                //--- BYTEBITS() ---//
                hold >>>= bits & 7;
                bits -= bits & 7;
                //---//
                state.mode = CHECK;
                break;
            }
            //=== NEEDBITS(3); */
            while(bits < 3){
                if (have === 0) break inf_leave;
                have--;
                hold += input[next++] << bits;
                bits += 8;
            }
            //===//
            state.last = hold & 1;
            //--- DROPBITS(1) ---//
            hold >>>= 1;
            bits -= 1;
            //---//
            switch(hold & 3){
                case 0:
                    /* stored block */ //Tracev((stderr, "inflate:     stored block%s\n",
                    //        state.last ? " (last)" : ""));
                    state.mode = STORED;
                    break;
                case 1:
                    /* fixed block */ fixedtables(state);
                    //Tracev((stderr, "inflate:     fixed codes block%s\n",
                    //        state.last ? " (last)" : ""));
                    state.mode = LEN_; /* decode codes */ 
                    if (flush === Z_TREES) {
                        //--- DROPBITS(2) ---//
                        hold >>>= 2;
                        bits -= 2;
                        break inf_leave;
                    }
                    break;
                case 2:
                    /* dynamic block */ //Tracev((stderr, "inflate:     dynamic codes block%s\n",
                    //        state.last ? " (last)" : ""));
                    state.mode = TABLE;
                    break;
                case 3:
                    strm.msg = 'invalid block type';
                    state.mode = BAD;
            }
            //--- DROPBITS(2) ---//
            hold >>>= 2;
            bits -= 2;
            break;
        case STORED:
            //--- BYTEBITS() ---// /* go to byte boundary */
            hold >>>= bits & 7;
            bits -= bits & 7;
            //---//
            //=== NEEDBITS(32); */
            while(bits < 32){
                if (have === 0) break inf_leave;
                have--;
                hold += input[next++] << bits;
                bits += 8;
            }
            //===//
            if ((hold & 65535) !== (hold >>> 16 ^ 65535)) {
                strm.msg = 'invalid stored block lengths';
                state.mode = BAD;
                break;
            }
            state.length = hold & 65535;
            //Tracev((stderr, "inflate:       stored length %u\n",
            //        state.length));
            //=== INITBITS();
            hold = 0;
            bits = 0;
            //===//
            state.mode = COPY_;
            if (flush === Z_TREES) break inf_leave;
        /* falls through */ case COPY_:
            state.mode = COPY;
        /* falls through */ case COPY:
            copy = state.length;
            if (copy) {
                if (copy > have) copy = have;
                if (copy > left) copy = left;
                if (copy === 0) break inf_leave;
                //--- zmemcpy(put, next, copy); ---
                utils.arraySet(output, input, next, copy, put);
                //---//
                have -= copy;
                next += copy;
                left -= copy;
                put += copy;
                state.length -= copy;
                break;
            }
            //Tracev((stderr, "inflate:       stored end\n"));
            state.mode = TYPE;
            break;
        case TABLE:
            //=== NEEDBITS(14); */
            while(bits < 14){
                if (have === 0) break inf_leave;
                have--;
                hold += input[next++] << bits;
                bits += 8;
            }
            //===//
            state.nlen = (hold & 31) + 257;
            //--- DROPBITS(5) ---//
            hold >>>= 5;
            bits -= 5;
            //---//
            state.ndist = (hold & 31) + 1;
            //--- DROPBITS(5) ---//
            hold >>>= 5;
            bits -= 5;
            //---//
            state.ncode = (hold & 15) + 4;
            //--- DROPBITS(4) ---//
            hold >>>= 4;
            bits -= 4;
            //---//
            //#ifndef PKZIP_BUG_WORKAROUND
            if (state.nlen > 286 || state.ndist > 30) {
                strm.msg = 'too many length or distance symbols';
                state.mode = BAD;
                break;
            }
            //#endif
            //Tracev((stderr, "inflate:       table sizes ok\n"));
            state.have = 0;
            state.mode = LENLENS;
        /* falls through */ case LENLENS:
            while(state.have < state.ncode){
                //=== NEEDBITS(3);
                while(bits < 3){
                    if (have === 0) break inf_leave;
                    have--;
                    hold += input[next++] << bits;
                    bits += 8;
                }
                //===//
                state.lens[order[state.have++]] = hold & 7; //BITS(3);
                //--- DROPBITS(3) ---//
                hold >>>= 3;
                bits -= 3;
            //---//
            }
            while(state.have < 19)state.lens[order[state.have++]] = 0;
            // We have separate tables & no pointers. 2 commented lines below not needed.
            //state.next = state.codes;
            //state.lencode = state.next;
            // Switch to use dynamic table
            state.lencode = state.lendyn;
            state.lenbits = 7;
            opts = {
                bits: state.lenbits
            };
            ret = inflate_table(CODES, state.lens, 0, 19, state.lencode, 0, state.work, opts);
            state.lenbits = opts.bits;
            if (ret) {
                strm.msg = 'invalid code lengths set';
                state.mode = BAD;
                break;
            }
            //Tracev((stderr, "inflate:       code lengths ok\n"));
            state.have = 0;
            state.mode = CODELENS;
        /* falls through */ case CODELENS:
            while(state.have < state.nlen + state.ndist){
                for(;;){
                    here = state.lencode[hold & (1 << state.lenbits) - 1]; /*BITS(state.lenbits)*/ 
                    here_bits = here >>> 24;
                    here_op = here >>> 16 & 255;
                    here_val = here & 65535;
                    if (here_bits <= bits) break;
                    //--- PULLBYTE() ---//
                    if (have === 0) break inf_leave;
                    have--;
                    hold += input[next++] << bits;
                    bits += 8;
                //---//
                }
                if (here_val < 16) {
                    //--- DROPBITS(here.bits) ---//
                    hold >>>= here_bits;
                    bits -= here_bits;
                    //---//
                    state.lens[state.have++] = here_val;
                } else {
                    if (here_val === 16) {
                        //=== NEEDBITS(here.bits + 2);
                        n = here_bits + 2;
                        while(bits < n){
                            if (have === 0) break inf_leave;
                            have--;
                            hold += input[next++] << bits;
                            bits += 8;
                        }
                        //===//
                        //--- DROPBITS(here.bits) ---//
                        hold >>>= here_bits;
                        bits -= here_bits;
                        //---//
                        if (state.have === 0) {
                            strm.msg = 'invalid bit length repeat';
                            state.mode = BAD;
                            break;
                        }
                        len = state.lens[state.have - 1];
                        copy = 3 + (hold & 3); //BITS(2);
                        //--- DROPBITS(2) ---//
                        hold >>>= 2;
                        bits -= 2;
                    //---//
                    } else if (here_val === 17) {
                        //=== NEEDBITS(here.bits + 3);
                        n = here_bits + 3;
                        while(bits < n){
                            if (have === 0) break inf_leave;
                            have--;
                            hold += input[next++] << bits;
                            bits += 8;
                        }
                        //===//
                        //--- DROPBITS(here.bits) ---//
                        hold >>>= here_bits;
                        bits -= here_bits;
                        //---//
                        len = 0;
                        copy = 3 + (hold & 7); //BITS(3);
                        //--- DROPBITS(3) ---//
                        hold >>>= 3;
                        bits -= 3;
                    //---//
                    } else {
                        //=== NEEDBITS(here.bits + 7);
                        n = here_bits + 7;
                        while(bits < n){
                            if (have === 0) break inf_leave;
                            have--;
                            hold += input[next++] << bits;
                            bits += 8;
                        }
                        //===//
                        //--- DROPBITS(here.bits) ---//
                        hold >>>= here_bits;
                        bits -= here_bits;
                        //---//
                        len = 0;
                        copy = 11 + (hold & 127); //BITS(7);
                        //--- DROPBITS(7) ---//
                        hold >>>= 7;
                        bits -= 7;
                    //---//
                    }
                    if (state.have + copy > state.nlen + state.ndist) {
                        strm.msg = 'invalid bit length repeat';
                        state.mode = BAD;
                        break;
                    }
                    while(copy--)state.lens[state.have++] = len;
                }
            }
            /* handle error breaks in while */ if (state.mode === BAD) break;
            /* check for end-of-block code (better have one) */ if (state.lens[256] === 0) {
                strm.msg = 'invalid code -- missing end-of-block';
                state.mode = BAD;
                break;
            }
            /* build code tables -- note: do not change the lenbits or distbits
           values here (9 and 6) without reading the comments in inftrees.h
           concerning the ENOUGH constants, which depend on those values */ state.lenbits = 9;
            opts = {
                bits: state.lenbits
            };
            ret = inflate_table(LENS, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts);
            // We have separate tables & no pointers. 2 commented lines below not needed.
            // state.next_index = opts.table_index;
            state.lenbits = opts.bits;
            // state.lencode = state.next;
            if (ret) {
                strm.msg = 'invalid literal/lengths set';
                state.mode = BAD;
                break;
            }
            state.distbits = 6;
            //state.distcode.copy(state.codes);
            // Switch to use dynamic table
            state.distcode = state.distdyn;
            opts = {
                bits: state.distbits
            };
            ret = inflate_table(DISTS, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts);
            // We have separate tables & no pointers. 2 commented lines below not needed.
            // state.next_index = opts.table_index;
            state.distbits = opts.bits;
            // state.distcode = state.next;
            if (ret) {
                strm.msg = 'invalid distances set';
                state.mode = BAD;
                break;
            }
            //Tracev((stderr, 'inflate:       codes ok\n'));
            state.mode = LEN_;
            if (flush === Z_TREES) break inf_leave;
        /* falls through */ case LEN_:
            state.mode = LEN;
        /* falls through */ case LEN:
            if (have >= 6 && left >= 258) {
                //--- RESTORE() ---
                strm.next_out = put;
                strm.avail_out = left;
                strm.next_in = next;
                strm.avail_in = have;
                state.hold = hold;
                state.bits = bits;
                //---
                inflate_fast(strm, _out);
                //--- LOAD() ---
                put = strm.next_out;
                output = strm.output;
                left = strm.avail_out;
                next = strm.next_in;
                input = strm.input;
                have = strm.avail_in;
                hold = state.hold;
                bits = state.bits;
                //---
                if (state.mode === TYPE) state.back = -1;
                break;
            }
            state.back = 0;
            for(;;){
                here = state.lencode[hold & (1 << state.lenbits) - 1]; /*BITS(state.lenbits)*/ 
                here_bits = here >>> 24;
                here_op = here >>> 16 & 255;
                here_val = here & 65535;
                if (here_bits <= bits) break;
                //--- PULLBYTE() ---//
                if (have === 0) break inf_leave;
                have--;
                hold += input[next++] << bits;
                bits += 8;
            //---//
            }
            if (here_op && (here_op & 240) === 0) {
                last_bits = here_bits;
                last_op = here_op;
                last_val = here_val;
                for(;;){
                    here = state.lencode[last_val + ((hold & (1 << last_bits + last_op) - 1) >> last_bits)];
                    here_bits = here >>> 24;
                    here_op = here >>> 16 & 255;
                    here_val = here & 65535;
                    if (last_bits + here_bits <= bits) break;
                    //--- PULLBYTE() ---//
                    if (have === 0) break inf_leave;
                    have--;
                    hold += input[next++] << bits;
                    bits += 8;
                //---//
                }
                //--- DROPBITS(last.bits) ---//
                hold >>>= last_bits;
                bits -= last_bits;
                //---//
                state.back += last_bits;
            }
            //--- DROPBITS(here.bits) ---//
            hold >>>= here_bits;
            bits -= here_bits;
            //---//
            state.back += here_bits;
            state.length = here_val;
            if (here_op === 0) {
                //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
                //        "inflate:         literal '%c'\n" :
                //        "inflate:         literal 0x%02x\n", here.val));
                state.mode = LIT;
                break;
            }
            if (here_op & 32) {
                //Tracevv((stderr, "inflate:         end of block\n"));
                state.back = -1;
                state.mode = TYPE;
                break;
            }
            if (here_op & 64) {
                strm.msg = 'invalid literal/length code';
                state.mode = BAD;
                break;
            }
            state.extra = here_op & 15;
            state.mode = LENEXT;
        /* falls through */ case LENEXT:
            if (state.extra) {
                //=== NEEDBITS(state.extra);
                n = state.extra;
                while(bits < n){
                    if (have === 0) break inf_leave;
                    have--;
                    hold += input[next++] << bits;
                    bits += 8;
                }
                //===//
                state.length += hold & (1 << state.extra) - 1;
                //--- DROPBITS(state.extra) ---//
                hold >>>= state.extra;
                bits -= state.extra;
                //---//
                state.back += state.extra;
            }
            //Tracevv((stderr, "inflate:         length %u\n", state.length));
            state.was = state.length;
            state.mode = DIST;
        /* falls through */ case DIST:
            for(;;){
                here = state.distcode[hold & (1 << state.distbits) - 1]; /*BITS(state.distbits)*/ 
                here_bits = here >>> 24;
                here_op = here >>> 16 & 255;
                here_val = here & 65535;
                if (here_bits <= bits) break;
                //--- PULLBYTE() ---//
                if (have === 0) break inf_leave;
                have--;
                hold += input[next++] << bits;
                bits += 8;
            //---//
            }
            if ((here_op & 240) === 0) {
                last_bits = here_bits;
                last_op = here_op;
                last_val = here_val;
                for(;;){
                    here = state.distcode[last_val + ((hold & (1 << last_bits + last_op) - 1) >> last_bits)];
                    here_bits = here >>> 24;
                    here_op = here >>> 16 & 255;
                    here_val = here & 65535;
                    if (last_bits + here_bits <= bits) break;
                    //--- PULLBYTE() ---//
                    if (have === 0) break inf_leave;
                    have--;
                    hold += input[next++] << bits;
                    bits += 8;
                //---//
                }
                //--- DROPBITS(last.bits) ---//
                hold >>>= last_bits;
                bits -= last_bits;
                //---//
                state.back += last_bits;
            }
            //--- DROPBITS(here.bits) ---//
            hold >>>= here_bits;
            bits -= here_bits;
            //---//
            state.back += here_bits;
            if (here_op & 64) {
                strm.msg = 'invalid distance code';
                state.mode = BAD;
                break;
            }
            state.offset = here_val;
            state.extra = here_op & 15;
            state.mode = DISTEXT;
        /* falls through */ case DISTEXT:
            if (state.extra) {
                //=== NEEDBITS(state.extra);
                n = state.extra;
                while(bits < n){
                    if (have === 0) break inf_leave;
                    have--;
                    hold += input[next++] << bits;
                    bits += 8;
                }
                //===//
                state.offset += hold & (1 << state.extra) - 1;
                //--- DROPBITS(state.extra) ---//
                hold >>>= state.extra;
                bits -= state.extra;
                //---//
                state.back += state.extra;
            }
            //#ifdef INFLATE_STRICT
            if (state.offset > state.dmax) {
                strm.msg = 'invalid distance too far back';
                state.mode = BAD;
                break;
            }
            //#endif
            //Tracevv((stderr, "inflate:         distance %u\n", state.offset));
            state.mode = MATCH;
        /* falls through */ case MATCH:
            if (left === 0) break inf_leave;
            copy = _out - left;
            if (state.offset > copy) {
                copy = state.offset - copy;
                if (copy > state.whave) {
                    if (state.sane) {
                        strm.msg = 'invalid distance too far back';
                        state.mode = BAD;
                        break;
                    }
                }
                if (copy > state.wnext) {
                    copy -= state.wnext;
                    from = state.wsize - copy;
                } else from = state.wnext - copy;
                if (copy > state.length) copy = state.length;
                from_source = state.window;
            } else {
                from_source = output;
                from = put - state.offset;
                copy = state.length;
            }
            if (copy > left) copy = left;
            left -= copy;
            state.length -= copy;
            do output[put++] = from_source[from++];
            while (--copy)
            if (state.length === 0) state.mode = LEN;
            break;
        case LIT:
            if (left === 0) break inf_leave;
            output[put++] = state.length;
            left--;
            state.mode = LEN;
            break;
        case CHECK:
            if (state.wrap) {
                //=== NEEDBITS(32);
                while(bits < 32){
                    if (have === 0) break inf_leave;
                    have--;
                    // Use '|' instead of '+' to make sure that result is signed
                    hold |= input[next++] << bits;
                    bits += 8;
                }
                //===//
                _out -= left;
                strm.total_out += _out;
                state.total += _out;
                if (_out) strm.adler = state.check = state.flags ? crc32(state.check, output, _out, put - _out) : adler32(state.check, output, _out, put - _out);
                _out = left;
                // NB: crc32 stored as signed 32-bit int, zswap32 returns signed too
                if ((state.flags ? hold : zswap32(hold)) !== state.check) {
                    strm.msg = 'incorrect data check';
                    state.mode = BAD;
                    break;
                }
                //=== INITBITS();
                hold = 0;
                bits = 0;
            //===//
            //Tracev((stderr, "inflate:   check matches trailer\n"));
            }
            state.mode = LENGTH;
        /* falls through */ case LENGTH:
            if (state.wrap && state.flags) {
                //=== NEEDBITS(32);
                while(bits < 32){
                    if (have === 0) break inf_leave;
                    have--;
                    hold += input[next++] << bits;
                    bits += 8;
                }
                //===//
                if (hold !== (state.total & 4294967295)) {
                    strm.msg = 'incorrect length check';
                    state.mode = BAD;
                    break;
                }
                //=== INITBITS();
                hold = 0;
                bits = 0;
            //===//
            //Tracev((stderr, "inflate:   length matches trailer\n"));
            }
            state.mode = DONE;
        /* falls through */ case DONE:
            ret = Z_STREAM_END;
            break inf_leave;
        case BAD:
            ret = Z_DATA_ERROR;
            break inf_leave;
        case MEM:
            return Z_MEM_ERROR;
        case SYNC:
        /* falls through */ default:
            return Z_STREAM_ERROR;
    }
    // inf_leave <- here is real place for "goto inf_leave", emulated via "break inf_leave"
    /*
     Return from inflate(), updating the total counts and the check value.
     If there was no progress during the inflate() call, return a buffer
     error.  Call updatewindow() to create and/or update the window state.
     Note: a memory error from inflate() is non-recoverable.
   */ //--- RESTORE() ---
    strm.next_out = put;
    strm.avail_out = left;
    strm.next_in = next;
    strm.avail_in = have;
    state.hold = hold;
    state.bits = bits;
    //---
    if (state.wsize || _out !== strm.avail_out && state.mode < BAD && (state.mode < CHECK || flush !== Z_FINISH)) {
        if (updatewindow(strm, strm.output, strm.next_out, _out - strm.avail_out)) {
            state.mode = MEM;
            return Z_MEM_ERROR;
        }
    }
    _in -= strm.avail_in;
    _out -= strm.avail_out;
    strm.total_in += _in;
    strm.total_out += _out;
    state.total += _out;
    if (state.wrap && _out) strm.adler = state.check = state.flags ? crc32(state.check, output, _out, strm.next_out - _out) : adler32(state.check, output, _out, strm.next_out - _out);
    strm.data_type = state.bits + (state.last ? 64 : 0) + (state.mode === TYPE ? 128 : 0) + (state.mode === LEN_ || state.mode === COPY_ ? 256 : 0);
    if ((_in === 0 && _out === 0 || flush === Z_FINISH) && ret === Z_OK) ret = Z_BUF_ERROR;
    return ret;
}
function inflateEnd(strm) {
    if (!strm || !strm.state /*|| strm->zfree == (free_func)0*/ ) return Z_STREAM_ERROR;
    var state = strm.state;
    if (state.window) state.window = null;
    strm.state = null;
    return Z_OK;
}
function inflateGetHeader(strm, head) {
    var state;
    /* check state */ if (!strm || !strm.state) return Z_STREAM_ERROR;
    state = strm.state;
    if ((state.wrap & 2) === 0) return Z_STREAM_ERROR;
    /* save header structure */ state.head = head;
    head.done = false;
    return Z_OK;
}
function inflateSetDictionary(strm, dictionary) {
    var dictLength = dictionary.length;
    var state;
    var dictid;
    var ret;
    /* check state */ if (!strm /* == Z_NULL */  || !strm.state /* == Z_NULL */ ) return Z_STREAM_ERROR;
    state = strm.state;
    if (state.wrap !== 0 && state.mode !== DICT) return Z_STREAM_ERROR;
    /* check for correct dictionary identifier */ if (state.mode === DICT) {
        dictid = 1; /* adler32(0, null, 0)*/ 
        /* dictid = adler32(dictid, dictionary, dictLength); */ dictid = adler32(dictid, dictionary, dictLength, 0);
        if (dictid !== state.check) return Z_DATA_ERROR;
    }
    /* copy dictionary to window using updatewindow(), which will amend the
   existing dictionary if appropriate */ ret = updatewindow(strm, dictionary, dictLength, dictLength);
    if (ret) {
        state.mode = MEM;
        return Z_MEM_ERROR;
    }
    state.havedict = 1;
    // Tracev((stderr, "inflate:   dictionary set\n"));
    return Z_OK;
}
exports.inflateReset = inflateReset;
exports.inflateReset2 = inflateReset2;
exports.inflateResetKeep = inflateResetKeep;
exports.inflateInit = inflateInit;
exports.inflateInit2 = inflateInit2;
exports.inflate = inflate;
exports.inflateEnd = inflateEnd;
exports.inflateGetHeader = inflateGetHeader;
exports.inflateSetDictionary = inflateSetDictionary;
exports.inflateInfo = 'pako inflate (from Nodeca project)'; /* Not implemented
exports.inflateCopy = inflateCopy;
exports.inflateGetDictionary = inflateGetDictionary;
exports.inflateMark = inflateMark;
exports.inflatePrime = inflatePrime;
exports.inflateSync = inflateSync;
exports.inflateSyncPoint = inflateSyncPoint;
exports.inflateUndermine = inflateUndermine;
*/ 

},{"../utils/common":"2FpJl","./adler32":"5HolB","./crc32":"hlmdd","./inffast":"jHibt","./inftrees":"hrU9c"}],"jHibt":[function(require,module,exports) {
'use strict';
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
//   claim that you wrote the original software. If you use this software
//   in a product, an acknowledgment in the product documentation would be
//   appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
//   misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
// See state defs from inflate.js
var BAD = 30; /* got a data error -- remain here until reset */ 
var TYPE = 12; /* i: waiting for type bits, including last-flag bit */ 
/*
   Decode literal, length, and distance codes and write out the resulting
   literal and match bytes until either not enough input or output is
   available, an end-of-block is encountered, or a data error is encountered.
   When large enough input and output buffers are supplied to inflate(), for
   example, a 16K input buffer and a 64K output buffer, more than 95% of the
   inflate execution time is spent in this routine.

   Entry assumptions:

        state.mode === LEN
        strm.avail_in >= 6
        strm.avail_out >= 258
        start >= strm.avail_out
        state.bits < 8

   On return, state.mode is one of:

        LEN -- ran out of enough output space or enough available input
        TYPE -- reached end of block code, inflate() to interpret next block
        BAD -- error in block data

   Notes:

    - The maximum input bits used by a length/distance pair is 15 bits for the
      length code, 5 bits for the length extra, 15 bits for the distance code,
      and 13 bits for the distance extra.  This totals 48 bits, or six bytes.
      Therefore if strm.avail_in >= 6, then there is enough input to avoid
      checking for available input while decoding.

    - The maximum bytes that a single length/distance pair can output is 258
      bytes, which is the maximum length that can be coded.  inflate_fast()
      requires strm.avail_out >= 258 for each loop to avoid checking for
      output space.
 */ module.exports = function inflate_fast(strm, start) {
    var state;
    var _in; /* local strm.input */ 
    var last; /* have enough input while in < last */ 
    var _out; /* local strm.output */ 
    var beg; /* inflate()'s initial strm.output */ 
    var end; /* while out < end, enough space available */ 
    //#ifdef INFLATE_STRICT
    var dmax; /* maximum distance from zlib header */ 
    //#endif
    var wsize; /* window size or zero if not using window */ 
    var whave; /* valid bytes in the window */ 
    var wnext; /* window write index */ 
    // Use `s_window` instead `window`, avoid conflict with instrumentation tools
    var s_window; /* allocated sliding window, if wsize != 0 */ 
    var hold; /* local strm.hold */ 
    var bits; /* local strm.bits */ 
    var lcode; /* local strm.lencode */ 
    var dcode; /* local strm.distcode */ 
    var lmask; /* mask for first level of length codes */ 
    var dmask; /* mask for first level of distance codes */ 
    var here; /* retrieved table entry */ 
    var op; /* code bits, operation, extra bits, or */ 
    /*  window position, window bytes to copy */ var len; /* match length, unused bytes */ 
    var dist; /* match distance */ 
    var from; /* where to copy match from */ 
    var from_source;
    var input, output; // JS specific, because we have no pointers
    /* copy state to local variables */ state = strm.state;
    //here = state.here;
    _in = strm.next_in;
    input = strm.input;
    last = _in + (strm.avail_in - 5);
    _out = strm.next_out;
    output = strm.output;
    beg = _out - (start - strm.avail_out);
    end = _out + (strm.avail_out - 257);
    //#ifdef INFLATE_STRICT
    dmax = state.dmax;
    //#endif
    wsize = state.wsize;
    whave = state.whave;
    wnext = state.wnext;
    s_window = state.window;
    hold = state.hold;
    bits = state.bits;
    lcode = state.lencode;
    dcode = state.distcode;
    lmask = (1 << state.lenbits) - 1;
    dmask = (1 << state.distbits) - 1;
    /* decode literals and length/distances until end-of-block or not enough
     input data or output space */ top: do {
        if (bits < 15) {
            hold += input[_in++] << bits;
            bits += 8;
            hold += input[_in++] << bits;
            bits += 8;
        }
        here = lcode[hold & lmask];
        dolen: for(;;){
            op = here >>> 24 /*here.bits*/ ;
            hold >>>= op;
            bits -= op;
            op = here >>> 16 & 255 /*here.op*/ ;
            if (op === 0) //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
            //        "inflate:         literal '%c'\n" :
            //        "inflate:         literal 0x%02x\n", here.val));
            output[_out++] = here & 65535 /*here.val*/ ;
            else if (op & 16) {
                len = here & 65535 /*here.val*/ ;
                op &= 15; /* number of extra bits */ 
                if (op) {
                    if (bits < op) {
                        hold += input[_in++] << bits;
                        bits += 8;
                    }
                    len += hold & (1 << op) - 1;
                    hold >>>= op;
                    bits -= op;
                }
                //Tracevv((stderr, "inflate:         length %u\n", len));
                if (bits < 15) {
                    hold += input[_in++] << bits;
                    bits += 8;
                    hold += input[_in++] << bits;
                    bits += 8;
                }
                here = dcode[hold & dmask];
                dodist: for(;;){
                    op = here >>> 24 /*here.bits*/ ;
                    hold >>>= op;
                    bits -= op;
                    op = here >>> 16 & 255 /*here.op*/ ;
                    if (op & 16) {
                        dist = here & 65535 /*here.val*/ ;
                        op &= 15; /* number of extra bits */ 
                        if (bits < op) {
                            hold += input[_in++] << bits;
                            bits += 8;
                            if (bits < op) {
                                hold += input[_in++] << bits;
                                bits += 8;
                            }
                        }
                        dist += hold & (1 << op) - 1;
                        //#ifdef INFLATE_STRICT
                        if (dist > dmax) {
                            strm.msg = 'invalid distance too far back';
                            state.mode = BAD;
                            break top;
                        }
                        //#endif
                        hold >>>= op;
                        bits -= op;
                        //Tracevv((stderr, "inflate:         distance %u\n", dist));
                        op = _out - beg; /* max distance in output */ 
                        if (dist > op) {
                            op = dist - op; /* distance back in window */ 
                            if (op > whave) {
                                if (state.sane) {
                                    strm.msg = 'invalid distance too far back';
                                    state.mode = BAD;
                                    break top;
                                }
                            }
                            from = 0; // window index
                            from_source = s_window;
                            if (wnext === 0) {
                                from += wsize - op;
                                if (op < len) {
                                    len -= op;
                                    do output[_out++] = s_window[from++];
                                    while (--op)
                                    from = _out - dist; /* rest from output */ 
                                    from_source = output;
                                }
                            } else if (wnext < op) {
                                from += wsize + wnext - op;
                                op -= wnext;
                                if (op < len) {
                                    len -= op;
                                    do output[_out++] = s_window[from++];
                                    while (--op)
                                    from = 0;
                                    if (wnext < len) {
                                        op = wnext;
                                        len -= op;
                                        do output[_out++] = s_window[from++];
                                        while (--op)
                                        from = _out - dist; /* rest from output */ 
                                        from_source = output;
                                    }
                                }
                            } else {
                                from += wnext - op;
                                if (op < len) {
                                    len -= op;
                                    do output[_out++] = s_window[from++];
                                    while (--op)
                                    from = _out - dist; /* rest from output */ 
                                    from_source = output;
                                }
                            }
                            while(len > 2){
                                output[_out++] = from_source[from++];
                                output[_out++] = from_source[from++];
                                output[_out++] = from_source[from++];
                                len -= 3;
                            }
                            if (len) {
                                output[_out++] = from_source[from++];
                                if (len > 1) output[_out++] = from_source[from++];
                            }
                        } else {
                            from = _out - dist; /* copy direct from output */ 
                            do {
                                output[_out++] = output[from++];
                                output[_out++] = output[from++];
                                output[_out++] = output[from++];
                                len -= 3;
                            }while (len > 2)
                            if (len) {
                                output[_out++] = output[from++];
                                if (len > 1) output[_out++] = output[from++];
                            }
                        }
                    } else if ((op & 64) === 0) {
                        here = dcode[(here & 65535) + (hold & (1 << op) - 1)];
                        continue dodist;
                    } else {
                        strm.msg = 'invalid distance code';
                        state.mode = BAD;
                        break top;
                    }
                    break; // need to emulate goto via "continue"
                }
            } else if ((op & 64) === 0) {
                here = lcode[(here & 65535) + (hold & (1 << op) - 1)];
                continue dolen;
            } else if (op & 32) {
                //Tracevv((stderr, "inflate:         end of block\n"));
                state.mode = TYPE;
                break top;
            } else {
                strm.msg = 'invalid literal/length code';
                state.mode = BAD;
                break top;
            }
            break; // need to emulate goto via "continue"
        }
    }while (_in < last && _out < end)
    /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ len = bits >> 3;
    _in -= len;
    bits -= len << 3;
    hold &= (1 << bits) - 1;
    /* update state and return */ strm.next_in = _in;
    strm.next_out = _out;
    strm.avail_in = _in < last ? 5 + (last - _in) : 5 - (_in - last);
    strm.avail_out = _out < end ? 257 + (end - _out) : 257 - (_out - end);
    state.hold = hold;
    state.bits = bits;
    return;
};

},{}],"hrU9c":[function(require,module,exports) {
'use strict';
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
//   claim that you wrote the original software. If you use this software
//   in a product, an acknowledgment in the product documentation would be
//   appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
//   misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
var utils = require('../utils/common');
var MAXBITS = 15;
var ENOUGH_LENS = 852;
var ENOUGH_DISTS = 592;
//var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS);
var CODES = 0;
var LENS = 1;
var DISTS = 2;
var lbase = [
    /* Length codes 257..285 base */ 3,
    4,
    5,
    6,
    7,
    8,
    9,
    10,
    11,
    13,
    15,
    17,
    19,
    23,
    27,
    31,
    35,
    43,
    51,
    59,
    67,
    83,
    99,
    115,
    131,
    163,
    195,
    227,
    258,
    0,
    0
];
var lext = [
    /* Length codes 257..285 extra */ 16,
    16,
    16,
    16,
    16,
    16,
    16,
    16,
    17,
    17,
    17,
    17,
    18,
    18,
    18,
    18,
    19,
    19,
    19,
    19,
    20,
    20,
    20,
    20,
    21,
    21,
    21,
    21,
    16,
    72,
    78
];
var dbase = [
    /* Distance codes 0..29 base */ 1,
    2,
    3,
    4,
    5,
    7,
    9,
    13,
    17,
    25,
    33,
    49,
    65,
    97,
    129,
    193,
    257,
    385,
    513,
    769,
    1025,
    1537,
    2049,
    3073,
    4097,
    6145,
    8193,
    12289,
    16385,
    24577,
    0,
    0
];
var dext = [
    /* Distance codes 0..29 extra */ 16,
    16,
    16,
    16,
    17,
    17,
    18,
    18,
    19,
    19,
    20,
    20,
    21,
    21,
    22,
    22,
    23,
    23,
    24,
    24,
    25,
    25,
    26,
    26,
    27,
    27,
    28,
    28,
    29,
    29,
    64,
    64
];
module.exports = function inflate_table(type, lens, lens_index, codes, table, table_index, work, opts) {
    var bits = opts.bits;
    //here = opts.here; /* table entry for duplication */
    var len = 0; /* a code's length in bits */ 
    var sym = 0; /* index of code symbols */ 
    var min = 0, max = 0; /* minimum and maximum code lengths */ 
    var root = 0; /* number of index bits for root table */ 
    var curr = 0; /* number of index bits for current table */ 
    var drop = 0; /* code bits to drop for sub-table */ 
    var left = 0; /* number of prefix codes available */ 
    var used = 0; /* code entries in table used */ 
    var huff = 0; /* Huffman code */ 
    var incr; /* for incrementing code, index */ 
    var fill; /* index for replicating entries */ 
    var low; /* low bits for current root entry */ 
    var mask; /* mask for low root bits */ 
    var next; /* next available space in table */ 
    var base = null; /* base value table to use */ 
    var base_index = 0;
    //  var shoextra;    /* extra bits table to use */
    var end; /* use base and extra for symbol > end */ 
    var count = new utils.Buf16(MAXBITS + 1); //[MAXBITS+1];    /* number of codes of each length */
    var offs = new utils.Buf16(MAXBITS + 1); //[MAXBITS+1];     /* offsets in table for each length */
    var extra = null;
    var extra_index = 0;
    var here_bits, here_op, here_val;
    /*
   Process a set of code lengths to create a canonical Huffman code.  The
   code lengths are lens[0..codes-1].  Each length corresponds to the
   symbols 0..codes-1.  The Huffman code is generated by first sorting the
   symbols by length from short to long, and retaining the symbol order
   for codes with equal lengths.  Then the code starts with all zero bits
   for the first code of the shortest length, and the codes are integer
   increments for the same length, and zeros are appended as the length
   increases.  For the deflate format, these bits are stored backwards
   from their more natural integer increment ordering, and so when the
   decoding tables are built in the large loop below, the integer codes
   are incremented backwards.

   This routine assumes, but does not check, that all of the entries in
   lens[] are in the range 0..MAXBITS.  The caller must assure this.
   1..MAXBITS is interpreted as that code length.  zero means that that
   symbol does not occur in this code.

   The codes are sorted by computing a count of codes for each length,
   creating from that a table of starting indices for each length in the
   sorted table, and then entering the symbols in order in the sorted
   table.  The sorted table is work[], with that space being provided by
   the caller.

   The length counts are used for other purposes as well, i.e. finding
   the minimum and maximum length codes, determining if there are any
   codes at all, checking for a valid set of lengths, and looking ahead
   at length counts to determine sub-table sizes when building the
   decoding tables.
   */ /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ for(len = 0; len <= MAXBITS; len++)count[len] = 0;
    for(sym = 0; sym < codes; sym++)count[lens[lens_index + sym]]++;
    /* bound code lengths, force root to be within code lengths */ root = bits;
    for(max = MAXBITS; max >= 1; max--){
        if (count[max] !== 0) break;
    }
    if (root > max) root = max;
    if (max === 0) {
        //table.op[opts.table_index] = 64;  //here.op = (var char)64;    /* invalid code marker */
        //table.bits[opts.table_index] = 1;   //here.bits = (var char)1;
        //table.val[opts.table_index++] = 0;   //here.val = (var short)0;
        table[table_index++] = 20971520;
        //table.op[opts.table_index] = 64;
        //table.bits[opts.table_index] = 1;
        //table.val[opts.table_index++] = 0;
        table[table_index++] = 20971520;
        opts.bits = 1;
        return 0; /* no symbols, but wait for decoding to report error */ 
    }
    for(min = 1; min < max; min++){
        if (count[min] !== 0) break;
    }
    if (root < min) root = min;
    /* check for an over-subscribed or incomplete set of lengths */ left = 1;
    for(len = 1; len <= MAXBITS; len++){
        left <<= 1;
        left -= count[len];
        if (left < 0) return -1;
         /* over-subscribed */ 
    }
    if (left > 0 && (type === CODES || max !== 1)) return -1; /* incomplete set */ 
    /* generate offsets into symbol table for each length for sorting */ offs[1] = 0;
    for(len = 1; len < MAXBITS; len++)offs[len + 1] = offs[len] + count[len];
    /* sort symbols by length, by symbol order within each length */ for(sym = 0; sym < codes; sym++)if (lens[lens_index + sym] !== 0) work[offs[lens[lens_index + sym]]++] = sym;
    /*
   Create and fill in decoding tables.  In this loop, the table being
   filled is at next and has curr index bits.  The code being used is huff
   with length len.  That code is converted to an index by dropping drop
   bits off of the bottom.  For codes where len is less than drop + curr,
   those top drop + curr - len bits are incremented through all values to
   fill the table with replicated entries.

   root is the number of index bits for the root table.  When len exceeds
   root, sub-tables are created pointed to by the root entry with an index
   of the low root bits of huff.  This is saved in low to check for when a
   new sub-table should be started.  drop is zero when the root table is
   being filled, and drop is root when sub-tables are being filled.

   When a new sub-table is needed, it is necessary to look ahead in the
   code lengths to determine what size sub-table is needed.  The length
   counts are used for this, and so count[] is decremented as codes are
   entered in the tables.

   used keeps track of how many table entries have been allocated from the
   provided *table space.  It is checked for LENS and DIST tables against
   the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in
   the initial root table size constants.  See the comments in inftrees.h
   for more information.

   sym increments through all symbols, and the loop terminates when
   all codes of length max, i.e. all codes, have been processed.  This
   routine permits incomplete codes, so another loop after this one fills
   in the rest of the decoding tables with invalid code markers.
   */ /* set up for code type */ // poor man optimization - use if-else instead of switch,
    // to avoid deopts in old v8
    if (type === CODES) {
        base = extra = work; /* dummy value--not used */ 
        end = 19;
    } else if (type === LENS) {
        base = lbase;
        base_index -= 257;
        extra = lext;
        extra_index -= 257;
        end = 256;
    } else {
        base = dbase;
        extra = dext;
        end = -1;
    }
    /* initialize opts for loop */ huff = 0; /* starting code */ 
    sym = 0; /* starting code symbol */ 
    len = min; /* starting code length */ 
    next = table_index; /* current table to fill in */ 
    curr = root; /* current table index bits */ 
    drop = 0; /* current bits to drop from code for index */ 
    low = -1; /* trigger new sub-table when len > root */ 
    used = 1 << root; /* use root table entries */ 
    mask = used - 1; /* mask for comparing low */ 
    /* check available table space */ if (type === LENS && used > ENOUGH_LENS || type === DISTS && used > ENOUGH_DISTS) return 1;
    /* process all codes and make table entries */ for(;;){
        /* create table entry */ here_bits = len - drop;
        if (work[sym] < end) {
            here_op = 0;
            here_val = work[sym];
        } else if (work[sym] > end) {
            here_op = extra[extra_index + work[sym]];
            here_val = base[base_index + work[sym]];
        } else {
            here_op = 96; /* end of block */ 
            here_val = 0;
        }
        /* replicate for those indices with low len bits equal to huff */ incr = 1 << len - drop;
        fill = 1 << curr;
        min = fill; /* save offset to next table */ 
        do {
            fill -= incr;
            table[next + (huff >> drop) + fill] = here_bits << 24 | here_op << 16 | here_val | 0;
        }while (fill !== 0)
        /* backwards increment the len-bit code huff */ incr = 1 << len - 1;
        while(huff & incr)incr >>= 1;
        if (incr !== 0) {
            huff &= incr - 1;
            huff += incr;
        } else huff = 0;
        /* go to next symbol, update count, len */ sym++;
        if (--count[len] === 0) {
            if (len === max) break;
            len = lens[lens_index + work[sym]];
        }
        /* create new sub-table if needed */ if (len > root && (huff & mask) !== low) {
            /* if first time, transition to sub-tables */ if (drop === 0) drop = root;
            /* increment past last table */ next += min; /* here min is 1 << curr */ 
            /* determine length of next table */ curr = len - drop;
            left = 1 << curr;
            while(curr + drop < max){
                left -= count[curr + drop];
                if (left <= 0) break;
                curr++;
                left <<= 1;
            }
            /* check for enough space */ used += 1 << curr;
            if (type === LENS && used > ENOUGH_LENS || type === DISTS && used > ENOUGH_DISTS) return 1;
            /* point entry in root table to sub-table */ low = huff & mask;
            /*table.op[low] = curr;
      table.bits[low] = root;
      table.val[low] = next - opts.table_index;*/ table[low] = root << 24 | curr << 16 | next - table_index | 0;
        }
    }
    /* fill in remaining table entry if code is incomplete (guaranteed to have
   at most one remaining entry, since if the code is incomplete, the
   maximum code length that was allowed to get this far is one bit) */ if (huff !== 0) //table.op[next + huff] = 64;            /* invalid code marker */
    //table.bits[next + huff] = len - drop;
    //table.val[next + huff] = 0;
    table[next + huff] = len - drop << 24 | 4194304;
    /* set return parameters */ //opts.table_index += used;
    opts.bits = root;
    return 0;
};

},{"../utils/common":"2FpJl"}],"dfW1p":[function(require,module,exports) {
'use strict';
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
//   claim that you wrote the original software. If you use this software
//   in a product, an acknowledgment in the product documentation would be
//   appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
//   misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
module.exports = {
    /* Allowed flush values; see deflate() and inflate() below for details */ Z_NO_FLUSH: 0,
    Z_PARTIAL_FLUSH: 1,
    Z_SYNC_FLUSH: 2,
    Z_FULL_FLUSH: 3,
    Z_FINISH: 4,
    Z_BLOCK: 5,
    Z_TREES: 6,
    /* Return codes for the compression/decompression functions. Negative values
  * are errors, positive values are used for special but normal events.
  */ Z_OK: 0,
    Z_STREAM_END: 1,
    Z_NEED_DICT: 2,
    Z_ERRNO: -1,
    Z_STREAM_ERROR: -2,
    Z_DATA_ERROR: -3,
    //Z_MEM_ERROR:     -4,
    Z_BUF_ERROR: -5,
    //Z_VERSION_ERROR: -6,
    /* compression levels */ Z_NO_COMPRESSION: 0,
    Z_BEST_SPEED: 1,
    Z_BEST_COMPRESSION: 9,
    Z_DEFAULT_COMPRESSION: -1,
    Z_FILTERED: 1,
    Z_HUFFMAN_ONLY: 2,
    Z_RLE: 3,
    Z_FIXED: 4,
    Z_DEFAULT_STRATEGY: 0,
    /* Possible values of the data_type field (though see inflate()) */ Z_BINARY: 0,
    Z_TEXT: 1,
    //Z_ASCII:                1, // = Z_TEXT (deprecated)
    Z_UNKNOWN: 2,
    /* The deflate compression method */ Z_DEFLATED: 8
};

},{}],"5Gi15":[function(require,module,exports) {
'use strict';
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
//   claim that you wrote the original software. If you use this software
//   in a product, an acknowledgment in the product documentation would be
//   appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
//   misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
function GZheader() {
    /* true if compressed data believed to be text */ this.text = 0;
    /* modification time */ this.time = 0;
    /* extra flags (not used when writing a gzip file) */ this.xflags = 0;
    /* operating system */ this.os = 0;
    /* pointer to extra field or Z_NULL if none */ this.extra = null;
    /* extra field length (valid if extra != Z_NULL) */ this.extra_len = 0; // Actually, we don't need it in JS,
    // but leave for few code modifications
    //
    // Setup limits is not necessary because in js we should not preallocate memory
    // for inflate use constant limit in 65536 bytes
    //
    /* space at extra (only when reading header) */ // this.extra_max  = 0;
    /* pointer to zero-terminated file name or Z_NULL */ this.name = '';
    /* space at name (only when reading header) */ // this.name_max   = 0;
    /* pointer to zero-terminated comment or Z_NULL */ this.comment = '';
    /* space at comment (only when reading header) */ // this.comm_max   = 0;
    /* true if there was or will be a header crc */ this.hcrc = 0;
    /* true when done reading gzip header (not used when writing a gzip file) */ this.done = false;
}
module.exports = GZheader;

},{}],"fQrKG":[function(require,module,exports) {
'use strict';
const { concat: uint8ArrayConcat  } = require('uint8arrays/concat');
/**
 * Takes an (async) iterable that yields buffer-like-objects and concats them
 * into one buffer
 * @param {AsyncIterable<Uint8Array>|Iterable<Uint8Array>} stream
 */ async function toBuffer(stream) {
    let buffer = new Uint8Array(0);
    for await (const buf of stream)buffer = uint8ArrayConcat([
        buffer,
        buf
    ], buffer.length + buf.length);
    return buffer;
}
module.exports = toBuffer;

},{"uint8arrays/concat":"fLIrL"}],"8fBhO":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var ipfsUnixfsExporter = require('ipfs-unixfs-exporter');
var errCode = require('err-code');
var utils = require('../utils.js');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
var cid = require('multiformats/cid');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
function createLs({ repo , preload  }) {
    async function* ls(ipfsPath, options = {
    }) {
        const legacyPath = utils.normalizeCidPath(ipfsPath);
        const pathComponents = legacyPath.split('/');
        if (options.preload !== false) preload(cid.CID.parse(pathComponents[0]));
        const ipfsPathOrCid = cid.CID.asCID(legacyPath) || legacyPath;
        const file = await ipfsUnixfsExporter.exporter(ipfsPathOrCid, repo.blocks, options);
        if (file.type === 'file') {
            yield utils.mapFile(file);
            return;
        }
        if (file.type === 'directory') {
            for await (const child of file.content())yield utils.mapFile(child);
            return;
        }
        throw errCode__default['default'](new Error(`Unknown UnixFS type ${file.type}`), 'ERR_UNKNOWN_UNIXFS_TYPE');
    }
    return withTimeoutOption.withTimeoutOption(ls);
}
exports.createLs = createLs;

},{"ipfs-unixfs-exporter":"Ufvxm","err-code":"eQvyh","../utils.js":"4LLx8","ipfs-core-utils/with-timeout-option":"5AiVw","multiformats/cid":"fJJnW"}],"4Kit3":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var version = require('../version.js');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function createVersion({ repo  }) {
    async function version$1(_options = {
    }) {
        const repoVersion = await repo.version.get();
        return {
            version: version.ipfsCore,
            commit: version.commit,
            repo: `${repoVersion}`,
            'ipfs-core': version.ipfsCore,
            'interface-ipfs-core': version.interfaceIpfsCore
        };
    }
    return withTimeoutOption.withTimeoutOption(version$1);
}
exports.createVersion = createVersion;

},{"../version.js":"7iiYH","ipfs-core-utils/with-timeout-option":"5AiVw"}],"7iiYH":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
const ipfsCore = '0.11.1';
const commit = '5ddd0c555cc6577ee15667f4ef4e7f3a3b17d04c';
const interfaceIpfsCore = '^0.151.1';
exports.commit = commit;
exports.interfaceIpfsCore = interfaceIpfsCore;
exports.ipfsCore = ipfsCore;

},{}],"9peBJ":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var version = require('../version.js');
var multiaddr = require('multiaddr');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
var toString = require('uint8arrays/to-string');
var PeerId = require('peer-id');
var errors = require('../errors.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var PeerId__default = /*#__PURE__*/ _interopDefaultLegacy(PeerId);
function createId({ peerId , network  }) {
    async function id1(options = {
    }) {
        if (options.peerId === peerId.toB58String()) delete options.peerId;
        const net = network.try();
        if (!net) {
            if (options.peerId) throw new errors.NotStartedError();
            const idStr = peerId.toB58String();
            return {
                id: idStr,
                publicKey: toString.toString(peerId.pubKey.bytes, 'base64pad'),
                addresses: [],
                agentVersion: `js-ipfs/${version.ipfsCore}`,
                protocolVersion: '9000',
                protocols: []
            };
        }
        const id = options.peerId ? PeerId__default['default'].createFromB58String(options.peerId.toString()) : peerId;
        const { libp2p  } = net;
        const publicKey = options.peerId ? libp2p.peerStore.keyBook.get(id) : id.pubKey;
        const addresses = options.peerId ? libp2p.peerStore.addressBook.getMultiaddrsForPeer(id) : libp2p.multiaddrs;
        const protocols = options.peerId ? libp2p.peerStore.protoBook.get(id) : Array.from(libp2p.upgrader.protocols.keys());
        const agentVersion = toString.toString(libp2p.peerStore.metadataBook.getValue(id, 'AgentVersion') || new Uint8Array());
        const protocolVersion = toString.toString(libp2p.peerStore.metadataBook.getValue(id, 'ProtocolVersion') || new Uint8Array());
        const idStr = id.toB58String();
        return {
            id: idStr,
            publicKey: toString.toString(publicKey.bytes, 'base64pad'),
            addresses: (addresses || []).map((ma)=>{
                const str = ma.toString();
                if (str.endsWith(`/p2p/${idStr}`)) return str;
                return `${str}/p2p/${idStr}`;
            }).sort().map((ma)=>new multiaddr.Multiaddr(ma)
            ),
            agentVersion,
            protocolVersion,
            protocols: (protocols || []).sort()
        };
    }
    return withTimeoutOption.withTimeoutOption(id1);
}
exports.createId = createId;

},{"../version.js":"7iiYH","multiaddr":"kOPrF","ipfs-core-utils/with-timeout-option":"5AiVw","uint8arrays/to-string":"g3mCQ","peer-id":"4VGWt","../errors.js":"itpk8"}],"8ed7u":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
var debug = require('debug');
var profiles = require('./profiles.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
const log = debug__default['default']('ipfs:core:config');
function createConfig({ repo  }) {
    async function getAll(options = {
    }) {
        return repo.config.getAll(options);
    }
    async function get(key, options) {
        if (!key) {
            return Promise.reject(new Error('key argument is required'));
        }
        return repo.config.get(key, options);
    }
    async function set(key, value, options) {
        return repo.config.set(key, value, options);
    }
    async function replace(value, options) {
        return repo.config.replace(value, options);
    }
    async function applyProfile(profileName, options = {
        dryRun: false
    }) {
        const { dryRun  } = options;
        const profile = profiles.profiles[profileName];
        if (!profile) {
            throw new Error(`No profile with name '${profileName}' exists`);
        }
        try {
            const oldCfg = await repo.config.getAll(options);
            let newCfg = JSON.parse(JSON.stringify(oldCfg));
            newCfg = profile.transform(newCfg);
            if (!dryRun) {
                await repo.config.replace(newCfg, options);
            }
            delete oldCfg.Identity.PrivKey;
            delete newCfg.Identity.PrivKey;
            return {
                original: oldCfg,
                updated: newCfg
            };
        } catch (err) {
            log(err);
            throw new Error(`Could not apply profile '${profileName}' to config: ${err.message}`);
        }
    }
    return {
        getAll: withTimeoutOption.withTimeoutOption(getAll),
        get: withTimeoutOption.withTimeoutOption(get),
        set: withTimeoutOption.withTimeoutOption(set),
        replace: withTimeoutOption.withTimeoutOption(replace),
        profiles: {
            apply: withTimeoutOption.withTimeoutOption(applyProfile),
            list: withTimeoutOption.withTimeoutOption(listProfiles)
        }
    };
}
async function listProfiles(_options) {
    return Object.keys(profiles.profiles).map((name)=>({
            name,
            description: profiles.profiles[name].description
        })
    );
}
exports.createConfig = createConfig;

},{"ipfs-core-utils/with-timeout-option":"5AiVw","debug":"lWlU4","./profiles.js":"6tQxX"}],"6tQxX":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var set = require('just-safe-set');
var getDefaultConfig = require('ipfs-core-config/config');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var set__default = /*#__PURE__*/ _interopDefaultLegacy(set);
var getDefaultConfig__default = /*#__PURE__*/ _interopDefaultLegacy(getDefaultConfig);
const profiles = {
    server: {
        description: 'Recommended for nodes with public IPv4 address (servers, VPSes, etc.), disables host and content discovery and UPnP in local networks.',
        transform: (config)=>{
            set__default['default'](config, 'Discovery.MDNS.Enabled', false);
            set__default['default'](config, 'Discovery.webRTCStar.Enabled', false);
            config.Swarm = {
                ...config.Swarm || {
                },
                DisableNatPortMap: true
            };
            return config;
        }
    },
    'local-discovery': {
        description: 'Sets default values to fields affected by `server` profile, enables discovery and UPnP in local networks.',
        transform: (config)=>{
            set__default['default'](config, 'Discovery.MDNS.Enabled', true);
            set__default['default'](config, 'Discovery.webRTCStar.Enabled', true);
            set__default['default'](config, 'Swarm', {
                ...config.Swarm || {
                },
                DisableNatPortMap: false
            });
            return config;
        }
    },
    test: {
        description: 'Reduces external interference, useful for running ipfs in test environments. Note that with these settings node won\'t be able to talk to the rest of the network without manual bootstrap.',
        transform: (config)=>{
            const defaultConfig = getDefaultConfig__default['default']();
            set__default['default'](config, 'Addresses.API', defaultConfig.Addresses.API ? '/ip4/127.0.0.1/tcp/0' : '');
            set__default['default'](config, 'Addresses.Gateway', defaultConfig.Addresses.Gateway ? '/ip4/127.0.0.1/tcp/0' : '');
            set__default['default'](config, 'Addresses.Swarm', defaultConfig.Addresses.Swarm.length ? [
                '/ip4/127.0.0.1/tcp/0'
            ] : []);
            set__default['default'](config, 'Addresses.Delegates', []);
            set__default['default'](config, 'Bootstrap', []);
            set__default['default'](config, 'Discovery.MDNS.Enabled', false);
            set__default['default'](config, 'Discovery.webRTCStar.Enabled', false);
            set__default['default'](config, 'Swarm', {
                ...config.Swarm || {
                },
                DisableNatPortMap: true
            });
            return config;
        }
    },
    'default-networking': {
        description: 'Restores default network settings. Inverse profile of the `test` profile.',
        transform: (config)=>{
            const defaultConfig = getDefaultConfig__default['default']();
            set__default['default'](config, 'Addresses.API', defaultConfig.Addresses.API);
            set__default['default'](config, 'Addresses.Gateway', defaultConfig.Addresses.Gateway);
            set__default['default'](config, 'Addresses.Swarm', defaultConfig.Addresses.Swarm);
            set__default['default'](config, 'Addresses.Delegates', defaultConfig.Addresses.Delegates);
            set__default['default'](config, 'Bootstrap', defaultConfig.Bootstrap);
            set__default['default'](config, 'Discovery.MDNS.Enabled', defaultConfig.Discovery.MDNS.Enabled);
            set__default['default'](config, 'Discovery.webRTCStar.Enabled', defaultConfig.Discovery.webRTCStar.Enabled);
            set__default['default'](config, 'Swarm', {
                ...config.Swarm || {
                },
                DisableNatPortMap: false
            });
            return config;
        }
    },
    lowpower: {
        description: 'Reduces daemon overhead on the system. May affect node functionality,performance of content discovery and data fetching may be degraded. Recommended for low power systems.',
        transform: (config)=>{
            const Swarm = config.Swarm || {
            };
            const ConnMgr = Swarm.ConnMgr || {
            };
            ConnMgr.LowWater = 20;
            ConnMgr.HighWater = 40;
            Swarm.ConnMgr = ConnMgr;
            config.Swarm = Swarm;
            return config;
        }
    },
    'default-power': {
        description: 'Inverse of "lowpower" profile.',
        transform: (config)=>{
            const defaultConfig = getDefaultConfig__default['default']();
            config.Swarm = defaultConfig.Swarm;
            return config;
        }
    }
};
exports.profiles = profiles;

},{"just-safe-set":"c9js5","ipfs-core-config/config":"i1esH"}],"c9js5":[function(require,module,exports) {
module.exports = set;
/*
  var obj1 = {};
  set(obj1, 'a.aa.aaa', 4); // true
  obj1; // {a: {aa: {aaa: 4}}}

  var obj2 = {};
  set(obj2, ['a', 'aa', 'aaa'], 4); // true
  obj2; // {a: {aa: {aaa: 4}}}

  var obj3 = {a: {aa: {aaa: 2}}};
  set(obj3, 'a.aa.aaa', 3); // true
  obj3; // {a: {aa: {aaa: 3}}}

  // don't clobber existing
  var obj4 = {a: {aa: {aaa: 2}}};
  set(obj4, 'a.aa', {bbb: 7}); // false

  const obj5 = {a: {}};
  const sym = Symbol();
  set(obj5.a, sym, 7); // true
  obj5; // {a: {Symbol(): 7}}
*/ function set(obj, propsArg, value) {
    var props, lastProp;
    if (Array.isArray(propsArg)) props = propsArg.slice(0);
    if (typeof propsArg == 'string') props = propsArg.split('.');
    if (typeof propsArg == 'symbol') props = [
        propsArg
    ];
    if (!Array.isArray(props)) throw new Error('props arg must be an array, a string or a symbol');
    lastProp = props.pop();
    if (!lastProp) return false;
    prototypeCheck(lastProp);
    var thisProp;
    while(thisProp = props.shift()){
        prototypeCheck(thisProp);
        if (typeof obj[thisProp] == 'undefined') obj[thisProp] = {
        };
        obj = obj[thisProp];
        if (!obj || typeof obj != 'object') return false;
    }
    obj[lastProp] = value;
    return true;
}
function prototypeCheck(prop) {
    if (prop === '__proto__' || prop === 'constructor' || prop === 'prototype') throw new Error('setting of prototype values not supported');
}

},{}],"6CCMQ":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var _export = require('./export.js');
var get = require('./get.js');
var _import = require('./import.js');
var put = require('./put.js');
var resolve = require('./resolve.js');
class DagAPI {
    constructor({ repo , codecs , hashers , preload  }){
        this.export = _export.createExport({
            repo,
            preload,
            codecs
        });
        this.get = get.createGet({
            codecs,
            repo,
            preload
        });
        this.import = _import.createImport({
            repo
        });
        this.resolve = resolve.createResolve({
            repo,
            codecs,
            preload
        });
        this.put = put.createPut({
            repo,
            codecs,
            hashers,
            preload
        });
    }
}
exports.DagAPI = DagAPI;

},{"./export.js":"3gN8c","./get.js":"bMR02","./import.js":"194yy","./put.js":"UwO0A","./resolve.js":"jpeHD"}],"3gN8c":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid1 = require('multiformats/cid');
var block1 = require('multiformats/block');
var base58 = require('multiformats/bases/base58');
var writer1 = require('@ipld/car/writer');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
var debug = require('debug');
var raw = require('multiformats/codecs/raw');
var json = require('multiformats/codecs/json');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n['default'] = e;
    return Object.freeze(n);
}
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
var raw__namespace = /*#__PURE__*/ _interopNamespace(raw);
var json__namespace = /*#__PURE__*/ _interopNamespace(json);
const log = debug__default['default']('ipfs:components:dag:import');
const NO_LINKS_CODECS = [
    raw__namespace.code,
    json__namespace.code
];
function createExport({ repo , preload , codecs  }) {
    async function* dagExport(root, options = {
    }) {
        if (options.preload !== false) preload(root);
        const cid$1 = cid1.CID.asCID(root);
        if (!cid$1) throw new Error(`Unexpected error converting CID type: ${root}`);
        log(`Exporting ${cid$1} as car`);
        const { writer: writer$1 , out  } = await writer1.CarWriter.create([
            cid$1
        ]);
        let err = null;
        (async ()=>{
            try {
                await traverseWrite(repo, {
                    signal: options.signal,
                    timeout: options.timeout
                }, cid$1, writer$1, codecs);
                writer$1.close();
            } catch (e) {
                err = e;
            }
        })();
        for await (const chunk of out){
            if (err) break;
            yield chunk;
        }
        if (err) throw err;
    }
    return withTimeoutOption.withTimeoutOption(dagExport);
}
async function traverseWrite(repo, options, cid, writer, codecs, seen = new Set()) {
    const b58Cid = cid.toString(base58.base58btc);
    if (seen.has(b58Cid)) return;
    const block = await getBlock(repo, options, cid, codecs);
    log(`Adding block ${cid} to car`);
    await writer.put(block);
    seen.add(b58Cid);
    for (const link of block.links)await traverseWrite(repo, options, link, writer, codecs, seen);
}
async function getBlock(repo, options, cid, codecs) {
    const bytes = await repo.blocks.get(cid, options);
    let links = [];
    const codec = await codecs.getCodec(cid.code);
    if (codec) {
        const block$1 = block1.createUnsafe({
            bytes,
            cid,
            codec
        });
        links = [
            ...block$1.links()
        ].map((l)=>l[1]
        );
    } else if (!NO_LINKS_CODECS.includes(cid.code)) throw new Error(`Can't decode links in block with codec 0x${cid.code.toString(16)} to form complete DAG`);
    return {
        cid,
        bytes,
        links
    };
}
exports.createExport = createExport;

},{"multiformats/cid":"fJJnW","multiformats/block":"8J6Pf","multiformats/bases/base58":"6Rnqi","@ipld/car/writer":"4X4g4","ipfs-core-utils/with-timeout-option":"5AiVw","debug":"lWlU4","multiformats/codecs/raw":"dkcyY","multiformats/codecs/json":"jwb79"}],"8J6Pf":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
require('./index.js');
var cid2 = require('./cid.js');
var bytes2 = require('./bytes.js');
const readonly = ({ enumerable =true , configurable =false  } = {
})=>({
        enumerable,
        configurable,
        writable: false
    })
;
const links = function*(source, base) {
    if (source == null) return;
    if (source instanceof Uint8Array) return;
    for (const [key, value] of Object.entries(source)){
        const path = [
            ...base,
            key
        ];
        if (value != null && typeof value === 'object') {
            if (Array.isArray(value)) for (const [index, element] of value.entries()){
                const elementPath = [
                    ...path,
                    index
                ];
                const cid$1 = cid2.CID.asCID(element);
                if (cid$1) yield [
                    elementPath.join('/'),
                    cid$1
                ];
                else if (typeof element === 'object') yield* links(element, elementPath);
            }
            else {
                const cid$1 = cid2.CID.asCID(value);
                if (cid$1) yield [
                    path.join('/'),
                    cid$1
                ];
                else yield* links(value, path);
            }
        }
    }
};
const tree = function*(source, base) {
    if (source == null) return;
    for (const [key, value] of Object.entries(source)){
        const path = [
            ...base,
            key
        ];
        yield path.join('/');
        if (value != null && !(value instanceof Uint8Array) && typeof value === 'object' && !cid2.CID.asCID(value)) {
            if (Array.isArray(value)) for (const [index, element] of value.entries()){
                const elementPath = [
                    ...path,
                    index
                ];
                yield elementPath.join('/');
                if (typeof element === 'object' && !cid2.CID.asCID(element)) yield* tree(element, elementPath);
            }
            else yield* tree(value, path);
        }
    }
};
const get = (source, path)=>{
    let node = source;
    for (const [index, key] of path.entries()){
        node = node[key];
        if (node == null) throw new Error(`Object has no property at ${path.slice(0, index + 1).map((part)=>`[${JSON.stringify(part)}]`
        ).join('')}`);
        const cid$1 = cid2.CID.asCID(node);
        if (cid$1) return {
            value: cid$1,
            remaining: path.slice(index + 1).join('/')
        };
    }
    return {
        value: node
    };
};
class Block {
    constructor({ cid: cid1 , bytes: bytes1 , value: value1  }){
        if (!cid1 || !bytes1 || typeof value1 === 'undefined') throw new Error('Missing required argument');
        this.cid = cid1;
        this.bytes = bytes1;
        this.value = value1;
        this.asBlock = this;
        Object.defineProperties(this, {
            cid: readonly(),
            bytes: readonly(),
            value: readonly(),
            asBlock: readonly()
        });
    }
    links() {
        return links(this.value, []);
    }
    tree() {
        return tree(this.value, []);
    }
    get(path = '/') {
        return get(this.value, path.split('/').filter(Boolean));
    }
}
const encode = async ({ value , codec , hasher  })=>{
    if (typeof value === 'undefined') throw new Error('Missing required argument "value"');
    if (!codec || !hasher) throw new Error('Missing required argument: codec or hasher');
    const bytes = codec.encode(value);
    const hash = await hasher.digest(bytes);
    const cid$1 = cid2.CID.create(1, codec.code, hash);
    return new Block({
        value,
        bytes,
        cid: cid$1
    });
};
const decode = async ({ bytes , codec , hasher  })=>{
    if (!bytes) throw new Error('Missing required argument "bytes"');
    if (!codec || !hasher) throw new Error('Missing required argument: codec or hasher');
    const value = codec.decode(bytes);
    const hash = await hasher.digest(bytes);
    const cid$1 = cid2.CID.create(1, codec.code, hash);
    return new Block({
        value,
        bytes,
        cid: cid$1
    });
};
const createUnsafe = ({ bytes , cid , value: maybeValue , codec  })=>{
    const value = maybeValue !== undefined ? maybeValue : codec && codec.decode(bytes);
    if (value === undefined) throw new Error('Missing required argument, must either provide "value" or "codec"');
    return new Block({
        cid,
        bytes,
        value
    });
};
const create = async ({ bytes: bytes$1 , cid , hasher , codec  })=>{
    if (!bytes$1) throw new Error('Missing required argument "bytes"');
    if (!hasher) throw new Error('Missing required argument "hasher"');
    const value = codec.decode(bytes$1);
    const hash = await hasher.digest(bytes$1);
    if (!bytes2.equals(cid.multihash.bytes, hash.bytes)) throw new Error('CID hash does not match bytes');
    return createUnsafe({
        bytes: bytes$1,
        cid,
        value,
        codec
    });
};
exports.Block = Block;
exports.create = create;
exports.createUnsafe = createUnsafe;
exports.decode = decode;
exports.encode = encode;

},{"./index.js":"8T5ng","./cid.js":"fJJnW","./bytes.js":"7cZyj"}],"4X4g4":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
var encoder = require('./encoder.js');
var iteratorChannel = require('./iterator-channel.js');
var decoder = require('./decoder.js');
class CarWriter {
    constructor(roots3, encoder1){
        this._encoder = encoder1;
        this._mutex = encoder1.setRoots(roots3);
        this._ended = false;
    }
    async put(block) {
        if (!(block.bytes instanceof Uint8Array) || !block.cid) throw new TypeError('Can only write {cid, bytes} objects');
        if (this._ended) throw new Error('Already closed');
        const cid$1 = cid.CID.asCID(block.cid);
        if (!cid$1) throw new TypeError('Can only write {cid, bytes} objects');
        this._mutex = this._mutex.then(()=>this._encoder.writeBlock({
                cid: cid$1,
                bytes: block.bytes
            })
        );
        return this._mutex;
    }
    async close() {
        if (this._ended) throw new Error('Already closed');
        await this._mutex;
        this._ended = true;
        return this._encoder.close();
    }
    static create(roots1) {
        roots1 = toRoots(roots1);
        const { encoder , iterator  } = encodeWriter();
        const writer = new CarWriter(roots1, encoder);
        const out = new CarWriterOut(iterator);
        return {
            writer,
            out
        };
    }
    static createAppender() {
        const { encoder , iterator  } = encodeWriter();
        encoder.setRoots = ()=>Promise.resolve()
        ;
        const writer = new CarWriter([], encoder);
        const out = new CarWriterOut(iterator);
        return {
            writer,
            out
        };
    }
    static async updateRootsInBytes(bytes, roots2) {
        const reader = decoder.bytesReader(bytes);
        await decoder.readHeader(reader);
        const newHeader = encoder.createHeader(roots2);
        if (reader.pos !== newHeader.length) throw new Error(`updateRoots() can only overwrite a header of the same length (old header is ${reader.pos} bytes, new header is ${newHeader.length} bytes)`);
        bytes.set(newHeader, 0);
        return bytes;
    }
}
class CarWriterOut {
    constructor(iterator1){
        this._iterator = iterator1;
    }
    [Symbol.asyncIterator]() {
        if (this._iterating) throw new Error('Multiple iterator not supported');
        this._iterating = true;
        return this._iterator;
    }
}
function encodeWriter() {
    const iw = iteratorChannel.create();
    const { writer , iterator  } = iw;
    const encoder$1 = encoder.createEncoder(writer);
    return {
        encoder: encoder$1,
        iterator
    };
}
function toRoots(roots) {
    if (roots === undefined) return [];
    if (!Array.isArray(roots)) {
        const cid$1 = cid.CID.asCID(roots);
        if (!cid$1) throw new TypeError('roots must be a single CID or an array of CIDs');
        return [
            cid$1
        ];
    }
    const _roots = [];
    for (const root of roots){
        const _root = cid.CID.asCID(root);
        if (!_root) throw new TypeError('roots must be a single CID or an array of CIDs');
        _roots.push(_root);
    }
    return _roots;
}
const __browser = true;
exports.CarWriter = CarWriter;
exports.CarWriterOut = CarWriterOut;
exports.__browser = __browser;

},{"multiformats/cid":"fJJnW","./encoder.js":"lPSb7","./iterator-channel.js":"7T074","./decoder.js":"gzyIx"}],"lPSb7":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var varint = require('varint');
var dagCbor = require('@ipld/dag-cbor');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var varint__default = /*#__PURE__*/ _interopDefaultLegacy(varint);
function createHeader(roots) {
    const headerBytes = dagCbor.encode({
        version: 1,
        roots
    });
    const varintBytes = varint__default["default"].encode(headerBytes.length);
    const header = new Uint8Array(varintBytes.length + headerBytes.length);
    header.set(varintBytes, 0);
    header.set(headerBytes, varintBytes.length);
    return header;
}
function createEncoder(writer) {
    return {
        async setRoots (roots) {
            const bytes = createHeader(roots);
            await writer.write(bytes);
        },
        async writeBlock (block) {
            const { cid , bytes  } = block;
            await writer.write(new Uint8Array(varint__default["default"].encode(cid.bytes.length + bytes.length)));
            await writer.write(cid.bytes);
            if (bytes.length) await writer.write(bytes);
        },
        async close () {
            return writer.end();
        }
    };
}
exports.createEncoder = createEncoder;
exports.createHeader = createHeader;

},{"varint":"l84uL","@ipld/dag-cbor":"kSG7F"}],"7T074":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
function noop() {
}
function create() {
    const chunkQueue = [];
    let drainer1 = null;
    let drainerResolver = noop;
    let ended = false;
    let outWait = null;
    let outWaitResolver = noop;
    const makeDrainer = ()=>{
        if (!drainer1) drainer1 = new Promise((resolve)=>{
            drainerResolver = ()=>{
                drainer1 = null;
                drainerResolver = noop;
                resolve();
            };
        });
        return drainer1;
    };
    const writer = {
        write (chunk) {
            chunkQueue.push(chunk);
            const drainer = makeDrainer();
            outWaitResolver();
            return drainer;
        },
        async end () {
            ended = true;
            const drainer = makeDrainer();
            outWaitResolver();
            return drainer;
        }
    };
    const iterator = {
        async next () {
            const chunk = chunkQueue.shift();
            if (chunk) {
                if (chunkQueue.length === 0) drainerResolver();
                return {
                    done: false,
                    value: chunk
                };
            }
            if (ended) {
                drainerResolver();
                return {
                    done: true,
                    value: undefined
                };
            }
            if (!outWait) outWait = new Promise((resolve)=>{
                outWaitResolver = ()=>{
                    outWait = null;
                    outWaitResolver = noop;
                    return resolve(iterator.next());
                };
            });
            return outWait;
        }
    };
    return {
        writer,
        iterator
    };
}
exports.create = create;

},{}],"gzyIx":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var varint = require('varint');
var cid1 = require('multiformats/cid');
var Digest = require('multiformats/hashes/digest');
var dagCbor = require('@ipld/dag-cbor');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n["default"] = e;
    return Object.freeze(n);
}
var varint__default = /*#__PURE__*/ _interopDefaultLegacy(varint);
var Digest__namespace = /*#__PURE__*/ _interopNamespace(Digest);
const CIDV0_BYTES = {
    SHA2_256: 18,
    LENGTH: 32,
    DAG_PB: 112
};
async function readVarint(reader) {
    const bytes = await reader.upTo(8);
    const i = varint__default["default"].decode(bytes);
    reader.seek(varint__default["default"].decode.bytes);
    return i;
}
async function readHeader(reader) {
    const length = await readVarint(reader);
    if (length === 0) throw new Error('Invalid CAR header (zero length)');
    const header = await reader.exactly(length);
    reader.seek(length);
    const block = dagCbor.decode(header);
    if (block == null || Array.isArray(block) || typeof block !== 'object') throw new Error('Invalid CAR header format');
    if (block.version !== 1) {
        if (typeof block.version === 'string') throw new Error(`Invalid CAR version: "${block.version}"`);
        throw new Error(`Invalid CAR version: ${block.version}`);
    }
    if (!Array.isArray(block.roots)) throw new Error('Invalid CAR header format');
    if (Object.keys(block).filter((p)=>p !== 'roots' && p !== 'version'
    ).length) throw new Error('Invalid CAR header format');
    return block;
}
async function readMultihash(reader) {
    const bytes = await reader.upTo(8);
    varint__default["default"].decode(bytes);
    const codeLength = varint__default["default"].decode.bytes;
    const length = varint__default["default"].decode(bytes.subarray(varint__default["default"].decode.bytes));
    const lengthLength = varint__default["default"].decode.bytes;
    const mhLength = codeLength + lengthLength + length;
    const multihash = await reader.exactly(mhLength);
    reader.seek(mhLength);
    return multihash;
}
async function readCid(reader) {
    const first = await reader.exactly(2);
    if (first[0] === CIDV0_BYTES.SHA2_256 && first[1] === CIDV0_BYTES.LENGTH) {
        const bytes = await reader.exactly(34);
        reader.seek(34);
        const multihash = Digest__namespace.decode(bytes);
        return cid1.CID.create(0, CIDV0_BYTES.DAG_PB, multihash);
    }
    const version = await readVarint(reader);
    if (version !== 1) throw new Error(`Unexpected CID version (${version})`);
    const codec = await readVarint(reader);
    const bytes = await readMultihash(reader);
    const multihash = Digest__namespace.decode(bytes);
    return cid1.CID.create(version, codec, multihash);
}
async function readBlockHead(reader) {
    const start = reader.pos;
    let length = await readVarint(reader);
    if (length === 0) throw new Error('Invalid CAR section (zero length)');
    length += reader.pos - start;
    const cid = await readCid(reader);
    const blockLength = length - (reader.pos - start);
    return {
        cid,
        length,
        blockLength
    };
}
async function readBlock(reader) {
    const { cid , blockLength  } = await readBlockHead(reader);
    const bytes = await reader.exactly(blockLength);
    reader.seek(blockLength);
    return {
        bytes,
        cid
    };
}
async function readBlockIndex(reader) {
    const offset = reader.pos;
    const { cid , length , blockLength  } = await readBlockHead(reader);
    const index = {
        cid,
        length,
        blockLength,
        offset,
        blockOffset: reader.pos
    };
    reader.seek(index.blockLength);
    return index;
}
function createDecoder(reader) {
    const headerPromise = readHeader(reader);
    return {
        header: ()=>headerPromise
        ,
        async *blocks () {
            await headerPromise;
            while((await reader.upTo(8)).length > 0)yield await readBlock(reader);
        },
        async *blocksIndex () {
            await headerPromise;
            while((await reader.upTo(8)).length > 0)yield await readBlockIndex(reader);
        }
    };
}
function bytesReader(bytes) {
    let pos = 0;
    return {
        async upTo (length) {
            return bytes.subarray(pos, pos + Math.min(length, bytes.length - pos));
        },
        async exactly (length) {
            if (length > bytes.length - pos) throw new Error('Unexpected end of data');
            return bytes.subarray(pos, pos + length);
        },
        seek (length) {
            pos += length;
        },
        get pos () {
            return pos;
        }
    };
}
function chunkReader(readChunk) {
    let pos = 0;
    let have = 0;
    let offset = 0;
    let currentChunk = new Uint8Array(0);
    const read = async (length)=>{
        have = currentChunk.length - offset;
        const bufa = [
            currentChunk.subarray(offset)
        ];
        while(have < length){
            const chunk = await readChunk();
            if (chunk == null) break;
            if (have < 0) {
                if (chunk.length > have) bufa.push(chunk.subarray(-have));
            } else bufa.push(chunk);
            have += chunk.length;
        }
        currentChunk = new Uint8Array(bufa.reduce((p, c)=>p + c.length
        , 0));
        let off = 0;
        for (const b of bufa){
            currentChunk.set(b, off);
            off += b.length;
        }
        offset = 0;
    };
    return {
        async upTo (length) {
            if (currentChunk.length - offset < length) await read(length);
            return currentChunk.subarray(offset, offset + Math.min(currentChunk.length - offset, length));
        },
        async exactly (length) {
            if (currentChunk.length - offset < length) await read(length);
            if (currentChunk.length - offset < length) throw new Error('Unexpected end of data');
            return currentChunk.subarray(offset, offset + length);
        },
        seek (length) {
            pos += length;
            offset += length;
        },
        get pos () {
            return pos;
        }
    };
}
function asyncIterableReader(asyncIterable) {
    const iterator = asyncIterable[Symbol.asyncIterator]();
    async function readChunk() {
        const next = await iterator.next();
        if (next.done) return null;
        return next.value;
    }
    return chunkReader(readChunk);
}
exports.asyncIterableReader = asyncIterableReader;
exports.bytesReader = bytesReader;
exports.chunkReader = chunkReader;
exports.createDecoder = createDecoder;
exports.readHeader = readHeader;

},{"varint":"l84uL","multiformats/cid":"fJJnW","multiformats/hashes/digest":"fkA58","@ipld/dag-cbor":"kSG7F"}],"bMR02":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
var first = require('it-first');
var last = require('it-last');
var utils = require('../../utils.js');
var errCode = require('err-code');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var first__default = /*#__PURE__*/ _interopDefaultLegacy(first);
var last__default = /*#__PURE__*/ _interopDefaultLegacy(last);
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
function createGet({ codecs , repo , preload  }) {
    const get = async function get(cid, options = {
    }) {
        if (options.preload !== false) preload(cid);
        if (options.path) {
            const entry = options.localResolve ? await first__default['default'](utils.resolve(cid, options.path, codecs, repo, options)) : await last__default['default'](utils.resolve(cid, options.path, codecs, repo, options));
            const result = entry;
            if (!result) throw errCode__default['default'](new Error('Not found'), 'ERR_NOT_FOUND');
            return result;
        }
        const codec = await codecs.getCodec(cid.code);
        const block = await repo.blocks.get(cid, options);
        const node = codec.decode(block);
        return {
            value: node,
            remainderPath: ''
        };
    };
    return withTimeoutOption.withTimeoutOption(get);
}
exports.createGet = createGet;

},{"ipfs-core-utils/with-timeout-option":"5AiVw","it-first":"imIGO","it-last":"7VTHF","../../utils.js":"4LLx8","err-code":"eQvyh"}],"imIGO":[function(require,module,exports) {
'use strict';
/**
 * Returns the first result from an (async) iterable, unless empty, in which
 * case returns `undefined`.
 *
 * @template T
 * @param {AsyncIterable<T>|Iterable<T>} source
 */ const first = async (source)=>{
    for await (const entry of source)return entry;
    return undefined;
};
module.exports = first;

},{}],"194yy":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var iterator = require('@ipld/car/iterator');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
var itPeekable = require('it-peekable');
var drain = require('it-drain');
var map = require('it-map');
var debug = require('debug');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var itPeekable__default = /*#__PURE__*/ _interopDefaultLegacy(itPeekable);
var drain__default = /*#__PURE__*/ _interopDefaultLegacy(drain);
var map__default = /*#__PURE__*/ _interopDefaultLegacy(map);
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
const log = debug__default['default']('ipfs:components:dag:import');
function createImport({ repo  }) {
    async function* dagImport(sources, options = {
    }) {
        const release = await repo.gcLock.readLock();
        try {
            const abortOptions = {
                signal: options.signal,
                timeout: options.timeout
            };
            const peekable = itPeekable__default['default'](sources);
            const { value , done  } = await peekable.peek();
            if (done) return;
            if (value) peekable.push(value);
            let cars;
            if (value instanceof Uint8Array) cars = [
                peekable
            ];
            else cars = peekable;
            for await (const car of cars){
                const roots = await importCar(repo, abortOptions, car);
                if (options.pinRoots !== false) for (const cid of roots){
                    let pinErrorMsg = '';
                    try {
                        if (await repo.blocks.has(cid)) {
                            log(`Pinning root ${cid}`);
                            await repo.pins.pinRecursively(cid);
                        } else pinErrorMsg = 'blockstore: block not found';
                    } catch (err) {
                        pinErrorMsg = err.message;
                    }
                    yield {
                        root: {
                            cid,
                            pinErrorMsg
                        }
                    };
                }
            }
        } finally{
            release();
        }
    }
    return withTimeoutOption.withTimeoutOption(dagImport);
}
async function importCar(repo, options, source) {
    const reader = await iterator.CarBlockIterator.fromIterable(source);
    const roots = await reader.getRoots();
    await drain__default['default'](repo.blocks.putMany(map__default['default'](reader, ({ cid: key , bytes: value  })=>{
        log(`Import block ${key}`);
        return {
            key,
            value
        };
    }), {
        signal: options.signal
    }));
    return roots;
}
exports.createImport = createImport;

},{"@ipld/car/iterator":"7Qcrf","ipfs-core-utils/with-timeout-option":"5AiVw","it-peekable":"kGyHM","it-drain":"h63K2","it-map":"dOmp3","debug":"lWlU4"}],"7Qcrf":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var decoder = require('./decoder.js');
class CarIteratorBase {
    constructor(version1, roots1, iterable){
        this._version = version1;
        this._roots = roots1;
        this._iterable = iterable;
        this._decoded = false;
    }
    get version() {
        return this._version;
    }
    async getRoots() {
        return this._roots;
    }
}
class CarBlockIterator extends CarIteratorBase {
    [Symbol.asyncIterator]() {
        if (this._decoded) throw new Error('Cannot decode more than once');
        if (!this._iterable) throw new Error('Block iterable not found');
        this._decoded = true;
        return this._iterable[Symbol.asyncIterator]();
    }
    static async fromBytes(bytes2) {
        const { version , roots , iterator  } = await fromBytes(bytes2);
        return new CarBlockIterator(version, roots, iterator);
    }
    static async fromIterable(asyncIterable2) {
        const { version , roots , iterator  } = await fromIterable(asyncIterable2);
        return new CarBlockIterator(version, roots, iterator);
    }
}
class CarCIDIterator extends CarIteratorBase {
    [Symbol.asyncIterator]() {
        if (this._decoded) throw new Error('Cannot decode more than once');
        if (!this._iterable) throw new Error('Block iterable not found');
        this._decoded = true;
        const iterable = this._iterable[Symbol.asyncIterator]();
        return {
            async next () {
                const next = await iterable.next();
                if (next.done) return next;
                return {
                    done: false,
                    value: next.value.cid
                };
            }
        };
    }
    static async fromBytes(bytes1) {
        const { version , roots , iterator  } = await fromBytes(bytes1);
        return new CarCIDIterator(version, roots, iterator);
    }
    static async fromIterable(asyncIterable1) {
        const { version , roots , iterator  } = await fromIterable(asyncIterable1);
        return new CarCIDIterator(version, roots, iterator);
    }
}
async function fromBytes(bytes) {
    if (!(bytes instanceof Uint8Array)) throw new TypeError('fromBytes() requires a Uint8Array');
    return decodeIterator(decoder.bytesReader(bytes));
}
async function fromIterable(asyncIterable) {
    if (!asyncIterable || !(typeof asyncIterable[Symbol.asyncIterator] === 'function')) throw new TypeError('fromIterable() requires an async iterable');
    return decodeIterator(decoder.asyncIterableReader(asyncIterable));
}
async function decodeIterator(reader) {
    const decoder$1 = decoder.createDecoder(reader);
    const { version , roots  } = await decoder$1.header();
    return {
        version,
        roots,
        iterator: decoder$1.blocks()
    };
}
exports.CarBlockIterator = CarBlockIterator;
exports.CarCIDIterator = CarCIDIterator;
exports.CarIteratorBase = CarIteratorBase;

},{"./decoder.js":"gzyIx"}],"UwO0A":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function createPut({ repo , codecs , hashers , preload  }) {
    async function put(dagNode, options = {
    }) {
        const release = options.pin ? await repo.gcLock.readLock() : null;
        try {
            const codecName = options.format || 'dag-cbor';
            const cidVersion = options.version != null ? options.version : codecName === 'dag-pb' ? 0 : 1;
            const codec = await codecs.getCodec(codecName);
            if (!codec) throw new Error(`Unknown codec ${options.format}, please configure additional BlockCodecs for this IPFS instance`);
            const hasher = await hashers.getHasher(options.hashAlg || 'sha2-256');
            if (!hasher) throw new Error(`Unknown hash algorithm ${options.hashAlg}, please configure additional MultihashHashers for this IPFS instance`);
            const buf = codec.encode(dagNode);
            const hash = await hasher.digest(buf);
            const cid$1 = cid.CID.create(cidVersion, codec.code, hash);
            await repo.blocks.put(cid$1, buf, {
                signal: options.signal
            });
            if (options.pin) await repo.pins.pinRecursively(cid$1);
            if (options.preload !== false) preload(cid$1);
            return cid$1;
        } finally{
            if (release) release();
        }
    }
    return withTimeoutOption.withTimeoutOption(put);
}
exports.createPut = createPut;

},{"multiformats/cid":"fJJnW","ipfs-core-utils/with-timeout-option":"5AiVw"}],"jpeHD":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
var toCidAndPath = require('ipfs-core-utils/to-cid-and-path');
var utils = require('../../utils.js');
function createResolve({ repo , codecs , preload  }) {
    async function dagResolve(ipfsPath, options = {
    }) {
        const { cid  } = toCidAndPath.toCidAndPath(ipfsPath);
        if (options.preload !== false) preload(cid);
        return utils.resolvePath(repo, codecs, ipfsPath, options);
    }
    return withTimeoutOption.withTimeoutOption(dagResolve);
}
exports.createResolve = createResolve;

},{"ipfs-core-utils/with-timeout-option":"5AiVw","ipfs-core-utils/to-cid-and-path":"5zZPz","../../utils.js":"4LLx8"}],"9hQTT":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var toUri = require('multiaddr-to-uri');
var debug = require('debug');
var shuffle = require('array-shuffle');
var nativeAbortController = require('native-abort-controller');
var preload = require('ipfs-core-config/preload');
var hashlru = require('hashlru');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var toUri__default = /*#__PURE__*/ _interopDefaultLegacy(toUri);
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
var shuffle__default = /*#__PURE__*/ _interopDefaultLegacy(shuffle);
var hashlru__default = /*#__PURE__*/ _interopDefaultLegacy(hashlru);
const log = Object.assign(debug__default['default']('ipfs:preload'), {
    error: debug__default['default']('ipfs:preload:error')
});
function createPreloader(options = {
}) {
    options.enabled = Boolean(options.enabled);
    options.addresses = options.addresses || [];
    options.cache = options.cache || 1000;
    if (!options.enabled || !options.addresses.length) {
        log('preload disabled');
        const api = ()=>{
        };
        return Object.assign(api, {
            start: ()=>{
            },
            stop: ()=>{
            }
        });
    }
    let stopped = true;
    let requests = [];
    const apiUris = options.addresses.map(toUri__default['default']);
    const cache = hashlru__default['default'](options.cache);
    const api = async (cid)=>{
        try {
            if (stopped) throw new Error(`preload ${cid} but preloader is not started`);
            const path = cid.toString();
            if (cache.has(path)) return;
            cache.set(path, true);
            const fallbackApiUris = shuffle__default['default'](apiUris);
            let success = false;
            const now = Date.now();
            for (const uri of fallbackApiUris){
                if (stopped) throw new Error(`preload aborted for ${path}`);
                let controller;
                try {
                    controller = new nativeAbortController.AbortController();
                    requests = requests.concat(controller);
                    await preload.preload(`${uri}/api/v0/refs?r=true&arg=${encodeURIComponent(path)}`, {
                        signal: controller.signal
                    });
                    success = true;
                } catch (err) {
                    if (err.type !== 'aborted') log.error(err);
                } finally{
                    requests = requests.filter((r)=>r !== controller
                    );
                }
                if (success) break;
            }
            log(`${success ? '' : 'un'}successfully preloaded ${path} in ${Date.now() - now}ms`);
        } catch (err) {
            log.error(err);
        }
    };
    api.start = ()=>{
        stopped = false;
    };
    api.stop = ()=>{
        stopped = true;
        log(`aborting ${requests.length} pending preload request(s)`);
        requests.forEach((r)=>r.abort()
        );
        requests = [];
    };
    return api;
}
exports.createPreloader = createPreloader;

},{"multiaddr-to-uri":"94qb6","debug":"lWlU4","array-shuffle":"fkjYM","native-abort-controller":"9z1Uk","ipfs-core-config/preload":"4OJWB","hashlru":"fzwAb"}],"94qb6":[function(require,module,exports) {
const { Multiaddr  } = require('multiaddr');
const reduceValue = (_, v)=>v
;
const tcpUri = (str, port, parts, opts)=>{
    // return tcp when explicitly requested
    if (opts && opts.assumeHttp === false) return `tcp://${str}:${port}`;
    // check if tcp is the last protocol in multiaddr
    let protocol = 'tcp';
    let explicitPort = `:${port}`;
    const last = parts[parts.length - 1];
    if (last.protocol === 'tcp') {
        // assume http and produce clean urls
        protocol = port === '443' ? 'https' : 'http';
        explicitPort = port === '443' || port === '80' ? '' : explicitPort;
    }
    return `${protocol}://${str}${explicitPort}`;
};
const Reducers = {
    ip4: reduceValue,
    ip6: (str, content, i, parts)=>parts.length === 1 && parts[0].protocol === 'ip6' ? content : `[${content}]`
    ,
    tcp: (str, content, i, parts, opts)=>parts.some((p)=>[
                'http',
                'https',
                'ws',
                'wss'
            ].includes(p.protocol)
        ) ? `${str}:${content}` : tcpUri(str, content, parts, opts)
    ,
    udp: (str, content)=>`udp://${str}:${content}`
    ,
    dnsaddr: reduceValue,
    dns4: reduceValue,
    dns6: reduceValue,
    ipfs: (str, content)=>`${str}/ipfs/${content}`
    ,
    p2p: (str, content)=>`${str}/p2p/${content}`
    ,
    http: (str)=>`http://${str}`
    ,
    https: (str)=>`https://${str}`
    ,
    ws: (str)=>`ws://${str}`
    ,
    wss: (str)=>`wss://${str}`
    ,
    'p2p-websocket-star': (str)=>`${str}/p2p-websocket-star`
    ,
    'p2p-webrtc-star': (str)=>`${str}/p2p-webrtc-star`
    ,
    'p2p-webrtc-direct': (str)=>`${str}/p2p-webrtc-direct`
};
module.exports = (multiaddr, opts)=>{
    const ma = new Multiaddr(multiaddr);
    const parts1 = multiaddr.toString().split('/').slice(1);
    return ma.tuples().map((tuple)=>({
            protocol: parts1.shift(),
            content: tuple[1] ? parts1.shift() : null
        })
    ).reduce((str, part, i, parts)=>{
        const reduce = Reducers[part.protocol];
        if (!reduce) throw new Error(`Unsupported protocol ${part.protocol}`);
        return reduce(str, part.content, i, parts, opts);
    }, '');
};

},{"multiaddr":"kOPrF"}],"fkjYM":[function(require,module,exports) {
'use strict';
module.exports = (array)=>{
    if (!Array.isArray(array)) throw new TypeError(`Expected an array, got ${typeof array}`);
    array = [
        ...array
    ];
    for(let index = array.length - 1; index > 0; index--){
        const newIndex = Math.floor(Math.random() * (index + 1));
        [array[index], array[newIndex]] = [
            array[newIndex],
            array[index]
        ];
    }
    return array;
};

},{}],"4OJWB":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var HTTP = require('ipfs-utils/src/http.js');
var debug = require('debug');
var PQueue = require('p-queue');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var HTTP__default = /*#__PURE__*/ _interopDefaultLegacy(HTTP);
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
var PQueue__default = /*#__PURE__*/ _interopDefaultLegacy(PQueue);
const log = Object.assign(debug__default["default"]('ipfs:preload'), {
    error: debug__default["default"]('ipfs:preload:error')
});
const Queue = PQueue__default["default"].default ? PQueue__default["default"].default : PQueue__default["default"];
const httpQueue = new Queue({
    concurrency: 4
});
function preload(url, options = {
}) {
    log(url);
    return httpQueue.add(async ()=>{
        const res = await HTTP__default["default"].post(url, {
            signal: options.signal
        });
        const reader = res.body.getReader();
        try {
            while(true){
                const { done  } = await reader.read();
                if (done) return;
            }
        } finally{
            reader.releaseLock();
        }
    });
}
exports.preload = preload;

},{"ipfs-utils/src/http.js":"2w2r7","debug":"lWlU4","p-queue":"ccCVf"}],"ii7Xb":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var debug = require('debug');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
const log = Object.assign(debug__default['default']('ipfs:mfs-preload'), {
    error: debug__default['default']('ipfs:mfs-preload:error')
});
function createMfsPreloader({ preload , files , options ={
}  }) {
    options.interval = options.interval || 30000;
    if (!options.enabled) {
        log('MFS preload disabled');
        const noop = async ()=>{
        };
        return {
            start: noop,
            stop: noop
        };
    }
    let rootCid = '';
    let timeoutId;
    const preloadMfs = async ()=>{
        try {
            const stats = await files.stat('/');
            const nextRootCid = stats.cid.toString();
            if (rootCid !== nextRootCid) {
                log(`preloading updated MFS root ${rootCid} -> ${stats.cid}`);
                await preload(stats.cid);
                rootCid = nextRootCid;
            }
        } catch (err) {
            log.error('failed to preload MFS root', err);
        } finally{
            timeoutId = setTimeout(preloadMfs, options.interval);
        }
    };
    return {
        async start () {
            const stats = await files.stat('/');
            rootCid = stats.cid.toString();
            log(`monitoring MFS root ${stats.cid}`);
            timeoutId = setTimeout(preloadMfs, options.interval);
        },
        stop () {
            clearTimeout(timeoutId);
        }
    };
}
exports.createMfsPreloader = createMfsPreloader;

},{"debug":"lWlU4"}],"lvLJk":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var createLock = require('./utils/create-lock.js');
var isIpfs = require('is-ipfs');
var stat = require('./stat.js');
var chmod = require('./chmod.js');
var cp = require('./cp.js');
var flush = require('./flush.js');
var mkdir = require('./mkdir.js');
var mv = require('./mv.js');
var rm = require('./rm.js');
var touch = require('./touch.js');
var read = require('./read.js');
var write = require('./write.js');
var ls = require('./ls.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var isIpfs__default = /*#__PURE__*/ _interopDefaultLegacy(isIpfs);
const readOperations = {
    stat: stat.createStat
};
const writeOperations = {
    chmod: chmod.createChmod,
    cp: cp.createCp,
    flush: flush.createFlush,
    mkdir: mkdir.createMkdir,
    mv: mv.createMv,
    rm: rm.createRm,
    touch: touch.createTouch
};
const unwrappedOperations = {
    write: write.createWrite,
    read: read.createRead,
    ls: ls.createLs
};
const wrap = ({ options , mfs , operations , lock  })=>{
    Object.keys(operations).forEach((key)=>{
        mfs[key] = lock(operations[key](options));
    });
};
const defaultOptions = {
    repoOwner: true,
    repo: null
};
function createMfs(options) {
    const { repoOwner  } = Object.assign({
    }, defaultOptions || {
    }, options);
    const lock = createLock.createLock(repoOwner);
    const readLock = (operation)=>{
        return lock.readLock(operation);
    };
    const writeLock = (operation)=>{
        return lock.writeLock(operation);
    };
    const mfs = {
    };
    wrap({
        options,
        mfs,
        operations: readOperations,
        lock: readLock
    });
    wrap({
        options,
        mfs,
        operations: writeOperations,
        lock: writeLock
    });
    Object.keys(unwrappedOperations).forEach((key)=>{
        mfs[key] = unwrappedOperations[key](options);
    });
    return mfs;
}
function createFiles({ repo , preload , hashers , options: constructorOptions  }) {
    const methods = createMfs({
        repo,
        repoOwner: Boolean(constructorOptions.repoOwner),
        hashers
    });
    const withPreload = (fn)=>{
        const wrapped = (...args)=>{
            const paths = args.filter((arg)=>isIpfs__default['default'].ipfsPath(arg) || isIpfs__default['default'].cid(arg)
            );
            if (paths.length) {
                const options = args[args.length - 1];
                if (options && options.preload !== false) paths.forEach((path)=>preload(path)
                );
            }
            return fn(...args);
        };
        return wrapped;
    };
    return {
        ...methods,
        chmod: methods.chmod,
        cp: withPreload(methods.cp),
        mkdir: methods.mkdir,
        stat: withPreload(methods.stat),
        rm: methods.rm,
        read: withPreload(methods.read),
        touch: methods.touch,
        write: methods.write,
        mv: withPreload(methods.mv),
        flush: methods.flush,
        ls: withPreload(async function*(...args) {
            for await (const file of methods.ls(...args))yield {
                ...file,
                size: file.size || 0
            };
        })
    };
}
exports.createFiles = createFiles;

},{"./utils/create-lock.js":"cNVmu","is-ipfs":"2Nskw","./stat.js":"b6mWw","./chmod.js":"lUt07","./cp.js":"8fxa7","./flush.js":"b5xsT","./mkdir.js":"j3o6O","./mv.js":"3kE4H","./rm.js":"bRRGH","./touch.js":"d9D43","./read.js":"96jxN","./write.js":"juLMo","./ls.js":"3Eqnu"}],"cNVmu":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var mortice = require('mortice');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var mortice__default = /*#__PURE__*/ _interopDefaultLegacy(mortice);
let lock;
function createLock(repoOwner = false) {
    if (lock) return lock;
    const mutex = mortice__default['default']({
        singleProcess: repoOwner
    });
    lock = {
        readLock: (func)=>{
            return async (...args)=>{
                const releaseLock = await mutex.readLock();
                try {
                    return await func.apply(null, args);
                } finally{
                    releaseLock();
                }
            };
        },
        writeLock: (func)=>{
            return async (...args)=>{
                const releaseLock = await mutex.writeLock();
                try {
                    return await func.apply(null, args);
                } finally{
                    releaseLock();
                }
            };
        }
    };
    return lock;
}
exports.createLock = createLock;

},{"mortice":"lcmcW"}],"lcmcW":[function(require,module,exports) {
var global = arguments[3];
const node = require('./node');
const browser = require('./browser');
const { default: Queue  } = require('p-queue');
const { timeout  } = require('promise-timeout');
const observe = require('observable-webworkers');
const mutexes = {
};
let implementation;
function createReleaseable(queue, options) {
    let res;
    const p = new Promise((resolve)=>{
        res = resolve;
    });
    queue.add(()=>timeout((()=>{
            return new Promise((resolve)=>{
                res(()=>{
                    resolve();
                });
            });
        })(), options.timeout)
    );
    return p;
}
const createMutex = (name, options)=>{
    if (implementation.isWorker) return {
        readLock: implementation.readLock(name, options),
        writeLock: implementation.writeLock(name, options)
    };
    const masterQueue = new Queue({
        concurrency: 1
    });
    let readQueue = null;
    return {
        readLock: ()=>{
            // If there's already a read queue, just add the task to it
            if (readQueue) return createReleaseable(readQueue, options);
            // Create a new read queue
            readQueue = new Queue({
                concurrency: options.concurrency,
                autoStart: false
            });
            const localReadQueue = readQueue;
            // Add the task to the read queue
            const readPromise = createReleaseable(readQueue, options);
            masterQueue.add(()=>{
                // Start the task only once the master queue has completed processing
                // any previous tasks
                localReadQueue.start();
                // Once all the tasks in the read queue have completed, remove it so
                // that the next read lock will occur after any write locks that were
                // started in the interim
                return localReadQueue.onIdle().then(()=>{
                    if (readQueue === localReadQueue) readQueue = null;
                });
            });
            return readPromise;
        },
        writeLock: ()=>{
            // Remove the read queue reference, so that any later read locks will be
            // added to a new queue that starts after this write lock has been
            // released
            readQueue = null;
            return createReleaseable(masterQueue, options);
        }
    };
};
const defaultOptions = {
    concurrency: Infinity,
    timeout: 84600000,
    global: global,
    singleProcess: false
};
module.exports = (name, options)=>{
    if (!options) options = {
    };
    if (typeof name === 'object') {
        options = name;
        name = 'lock';
    }
    if (!name) name = 'lock';
    options = Object.assign({
    }, defaultOptions, options);
    if (!implementation) {
        implementation = node(options) || browser(options);
        if (!implementation.isWorker) {
            // we are master, set up worker requests
            implementation.on('requestReadLock', (name, fn)=>{
                if (!mutexes[name]) return;
                mutexes[name].readLock().then((release)=>fn().finally(()=>release()
                    )
                );
            });
            implementation.on('requestWriteLock', async (name, fn)=>{
                if (!mutexes[name]) return;
                mutexes[name].writeLock().then((release)=>fn().finally(()=>release()
                    )
                );
            });
        }
    }
    if (!mutexes[name]) mutexes[name] = createMutex(name, options);
    return mutexes[name];
};
module.exports.Worker = function(script, Impl) {
    Impl = Impl || global.Worker;
    let worker;
    try {
        worker = new Impl(script);
    } catch (error) {
        if (error.message.includes('not a constructor')) worker = Impl(script);
    }
    if (!worker) throw new Error('Could not create Worker from', Impl);
    observe(worker);
    return worker;
};

},{"./node":"9GIr9","./browser":"7h7FS","p-queue":"ccCVf","promise-timeout":"dbYSI","observable-webworkers":"1yxug"}],"9GIr9":[function(require,module,exports) {
var process = require("process");
const EventEmitter = require('events').EventEmitter;
const { nanoid  } = require('nanoid');
const { WORKER_REQUEST_READ_LOCK , WORKER_RELEASE_READ_LOCK , MASTER_GRANT_READ_LOCK , WORKER_REQUEST_WRITE_LOCK , WORKER_RELEASE_WRITE_LOCK , MASTER_GRANT_WRITE_LOCK  } = require('./constants');
let cluster;
const handleWorkerLockRequest = (emitter, masterEvent, requestType, releaseType, grantType)=>{
    return (worker, requestEvent)=>{
        if (requestEvent && requestEvent.type === requestType) emitter.emit(masterEvent, requestEvent.name, ()=>{
            // grant lock to worker
            worker.send({
                type: grantType,
                name: requestEvent.name,
                identifier: requestEvent.identifier
            });
            // wait for worker to finish
            return new Promise((resolve)=>{
                const releaseEventListener = (releaseEvent)=>{
                    if (releaseEvent && releaseEvent.type === releaseType && releaseEvent.identifier === requestEvent.identifier) {
                        worker.removeListener('message', releaseEventListener);
                        resolve();
                    }
                };
                worker.on('message', releaseEventListener);
            });
        });
    };
};
const makeWorkerLockRequest = (name, requestType, grantType, releaseType)=>{
    return ()=>{
        const id = nanoid();
        process.send({
            type: requestType,
            identifier: id,
            name
        });
        return new Promise((resolve)=>{
            const listener = (event)=>{
                if (event && event.type === grantType && event.identifier === id) {
                    process.removeListener('message', listener);
                    // grant lock
                    resolve(()=>{
                        // release lock
                        process.send({
                            type: releaseType,
                            identifier: id,
                            name
                        });
                    });
                }
            };
            process.on('message', listener);
        });
    };
};
module.exports = (options)=>{
    try {
        cluster = require('cluster');
        if (!Object.keys(cluster).length) return;
    } catch (_) {
        return;
    }
    if (cluster.isMaster || options.singleProcess) {
        const emitter = new EventEmitter();
        cluster.on('message', handleWorkerLockRequest(emitter, 'requestReadLock', WORKER_REQUEST_READ_LOCK, WORKER_RELEASE_READ_LOCK, MASTER_GRANT_READ_LOCK));
        cluster.on('message', handleWorkerLockRequest(emitter, 'requestWriteLock', WORKER_REQUEST_WRITE_LOCK, WORKER_RELEASE_WRITE_LOCK, MASTER_GRANT_WRITE_LOCK));
        return emitter;
    }
    return {
        isWorker: true,
        readLock: (name)=>makeWorkerLockRequest(name, WORKER_REQUEST_READ_LOCK, MASTER_GRANT_READ_LOCK, WORKER_RELEASE_READ_LOCK)
        ,
        writeLock: (name)=>makeWorkerLockRequest(name, WORKER_REQUEST_WRITE_LOCK, MASTER_GRANT_WRITE_LOCK, WORKER_RELEASE_WRITE_LOCK)
    };
};

},{"process":"lDnB8","events":"bHM3D","nanoid":"4OOvb","./constants":"9bYDE","cluster":"joWnX"}],"9bYDE":[function(require,module,exports) {
module.exports = {
    WORKER_REQUEST_READ_LOCK: 'lock:worker:request-read',
    WORKER_RELEASE_READ_LOCK: 'lock:worker:release-read',
    MASTER_GRANT_READ_LOCK: 'lock:master:grant-read',
    WORKER_REQUEST_WRITE_LOCK: 'lock:worker:request-write',
    WORKER_RELEASE_WRITE_LOCK: 'lock:worker:release-write',
    MASTER_GRANT_WRITE_LOCK: 'lock:master:grant-write'
};

},{}],"7h7FS":[function(require,module,exports) {
const EventEmitter = require('events').EventEmitter;
const { nanoid  } = require('nanoid');
const { WORKER_REQUEST_READ_LOCK , WORKER_RELEASE_READ_LOCK , MASTER_GRANT_READ_LOCK , WORKER_REQUEST_WRITE_LOCK , WORKER_RELEASE_WRITE_LOCK , MASTER_GRANT_WRITE_LOCK  } = require('./constants');
const observer = require('observable-webworkers');
const handleWorkerLockRequest = (emitter, masterEvent, requestType, releaseType, grantType)=>{
    return (worker, event1)=>{
        if (!event1 || !event1.data || event1.data.type !== requestType) return;
        const requestEvent = {
            type: event1.data.type,
            name: event1.data.name,
            identifier: event1.data.identifier
        };
        emitter.emit(masterEvent, requestEvent.name, ()=>{
            // grant lock to worker
            worker.postMessage({
                type: grantType,
                name: requestEvent.name,
                identifier: requestEvent.identifier
            });
            // wait for worker to finish
            return new Promise((resolve)=>{
                const releaseEventListener = (event)=>{
                    if (!event || !event.data) return;
                    const releaseEvent = {
                        type: event.data.type,
                        name: event.data.name,
                        identifier: event.data.identifier
                    };
                    if (releaseEvent && releaseEvent.type === releaseType && releaseEvent.identifier === requestEvent.identifier) {
                        worker.removeEventListener('message', releaseEventListener);
                        resolve();
                    }
                };
                worker.addEventListener('message', releaseEventListener);
            });
        });
    };
};
const makeWorkerLockRequest = (name, requestType, grantType, releaseType)=>{
    return ()=>{
        const id = nanoid();
        globalThis.postMessage({
            type: requestType,
            identifier: id,
            name
        });
        return new Promise((resolve)=>{
            const listener = (event)=>{
                if (!event || !event.data) return;
                const responseEvent = {
                    type: event.data.type,
                    identifier: event.data.identifier
                };
                if (responseEvent && responseEvent.type === grantType && responseEvent.identifier === id) {
                    globalThis.removeEventListener('message', listener);
                    // grant lock
                    resolve(()=>{
                        // release lock
                        globalThis.postMessage({
                            type: releaseType,
                            identifier: id,
                            name
                        });
                    });
                }
            };
            globalThis.addEventListener('message', listener);
        });
    };
};
const defaultOptions = {
    singleProcess: false
};
module.exports = (options)=>{
    options = Object.assign({
    }, defaultOptions, options);
    const isMaster = !!globalThis.document || options.singleProcess;
    if (isMaster) {
        const emitter = new EventEmitter();
        observer.addEventListener('message', handleWorkerLockRequest(emitter, 'requestReadLock', WORKER_REQUEST_READ_LOCK, WORKER_RELEASE_READ_LOCK, MASTER_GRANT_READ_LOCK));
        observer.addEventListener('message', handleWorkerLockRequest(emitter, 'requestWriteLock', WORKER_REQUEST_WRITE_LOCK, WORKER_RELEASE_WRITE_LOCK, MASTER_GRANT_WRITE_LOCK));
        return emitter;
    }
    return {
        isWorker: true,
        readLock: (name)=>makeWorkerLockRequest(name, WORKER_REQUEST_READ_LOCK, MASTER_GRANT_READ_LOCK, WORKER_RELEASE_READ_LOCK)
        ,
        writeLock: (name)=>makeWorkerLockRequest(name, WORKER_REQUEST_WRITE_LOCK, MASTER_GRANT_WRITE_LOCK, WORKER_RELEASE_WRITE_LOCK)
    };
};

},{"events":"bHM3D","nanoid":"4OOvb","./constants":"9bYDE","observable-webworkers":"1yxug"}],"1yxug":[function(require,module,exports) {
const events = {
};
const observable = (worker)=>{
    worker.addEventListener('message', (event)=>{
        observable.dispatchEvent('message', worker, event);
    });
    if (worker.port) worker.port.addEventListener('message', (event)=>{
        observable.dispatchEvent('message', worker, event);
    });
};
observable.addEventListener = (type, fn)=>{
    if (!events[type]) events[type] = [];
    events[type].push(fn);
};
observable.removeEventListener = (type, fn)=>{
    if (!events[type]) return;
    events[type] = events[type].filter((listener)=>listener === fn
    );
};
observable.dispatchEvent = function() {
    const args = Array.prototype.slice.call(arguments);
    const type = args.shift();
    if (!events[type]) return;
    events[type].forEach((fn)=>fn.apply(null, args)
    );
};
module.exports = observable;

},{}],"dbYSI":[function(require,module,exports) {
// Copyright (c) 2015-2017 David M. Lee, II
'use strict';
/**
 * Local reference to TimeoutError
 * @private
 */ var TimeoutError;
/**
 * Rejects a promise with a {@link TimeoutError} if it does not settle within
 * the specified timeout.
 *
 * @param {Promise} promise The promise.
 * @param {number} timeoutMillis Number of milliseconds to wait on settling.
 * @returns {Promise} Either resolves/rejects with `promise`, or rejects with
 *                   `TimeoutError`, whichever settles first.
 */ var timeout1 = module.exports.timeout = function(promise, timeoutMillis) {
    var error = new TimeoutError(), timeout;
    return Promise.race([
        promise,
        new Promise(function(resolve, reject) {
            timeout = setTimeout(function() {
                reject(error);
            }, timeoutMillis);
        }), 
    ]).then(function(v) {
        clearTimeout(timeout);
        return v;
    }, function(err) {
        clearTimeout(timeout);
        throw err;
    });
};
/**
 * Exception indicating that the timeout expired.
 */ TimeoutError = module.exports.TimeoutError = function() {
    Error.call(this);
    this.stack = Error().stack;
    this.message = 'Timeout';
};
TimeoutError.prototype = Object.create(Error.prototype);
TimeoutError.prototype.name = "TimeoutError";

},{}],"b6mWw":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var mergeOpts = require('merge-options');
var toMfsPath = require('./utils/to-mfs-path.js');
var ipfsUnixfsExporter = require('ipfs-unixfs-exporter');
var debug = require('debug');
var errCode = require('err-code');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
var dagPB = require('@ipld/dag-pb');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n['default'] = e;
    return Object.freeze(n);
}
var mergeOpts__default = /*#__PURE__*/ _interopDefaultLegacy(mergeOpts);
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
var dagPB__namespace = /*#__PURE__*/ _interopNamespace(dagPB);
const mergeOptions = mergeOpts__default['default'].bind({
    ignoreUndefined: true
});
const log = debug__default['default']('ipfs:mfs:stat');
const defaultOptions = {
    withLocal: false
};
function createStat(context) {
    async function mfsStat(path, options = {
    }) {
        options = mergeOptions(defaultOptions, options);
        log(`Fetching stats for ${path}`);
        const { type , cid , mfsPath  } = await toMfsPath.toMfsPath(context, path, options);
        const exportPath = type === 'ipfs' && cid ? cid : mfsPath;
        let file;
        try {
            file = await ipfsUnixfsExporter.exporter(exportPath, context.repo.blocks);
        } catch (err) {
            if (err.code === 'ERR_NOT_FOUND') throw errCode__default['default'](new Error(`${path} does not exist`), 'ERR_NOT_FOUND');
            throw err;
        }
        if (!statters[file.type]) throw new Error(`Cannot stat codec ${file.cid.code}`);
        return statters[file.type](file);
    }
    return withTimeoutOption.withTimeoutOption(mfsStat);
}
const statters = {
    raw: (file)=>{
        return {
            cid: file.cid,
            size: file.node.length,
            cumulativeSize: file.node.length,
            blocks: 0,
            type: 'file',
            local: undefined,
            sizeLocal: undefined,
            withLocality: false
        };
    },
    file: (file)=>{
        const stat = {
            cid: file.cid,
            type: 'file',
            size: file.unixfs.fileSize(),
            cumulativeSize: dagPB__namespace.encode(file.node).length + (file.node.Links || []).reduce((acc, curr)=>acc + (curr.Tsize || 0)
            , 0),
            blocks: file.unixfs.blockSizes.length,
            local: undefined,
            sizeLocal: undefined,
            withLocality: false,
            mode: file.unixfs.mode
        };
        if (file.unixfs.mtime) stat.mtime = file.unixfs.mtime;
        return stat;
    },
    directory: (file)=>{
        const stat = {
            cid: file.cid,
            type: 'directory',
            size: 0,
            cumulativeSize: dagPB__namespace.encode(file.node).length + (file.node.Links || []).reduce((acc, curr)=>acc + (curr.Tsize || 0)
            , 0),
            blocks: file.node.Links.length,
            local: undefined,
            sizeLocal: undefined,
            withLocality: false,
            mode: file.unixfs.mode
        };
        if (file.unixfs.mtime) stat.mtime = file.unixfs.mtime;
        return stat;
    },
    object: (file)=>{
        return {
            cid: file.cid,
            size: file.node.length,
            cumulativeSize: file.node.length,
            type: 'file',
            blocks: 0,
            local: undefined,
            sizeLocal: undefined,
            withLocality: false
        };
    },
    identity: (file)=>{
        return {
            cid: file.cid,
            size: file.node.length,
            cumulativeSize: file.node.length,
            blocks: 0,
            type: 'file',
            local: undefined,
            sizeLocal: undefined,
            withLocality: false
        };
    }
};
exports.createStat = createStat;

},{"merge-options":"8VjFj","./utils/to-mfs-path.js":"kqPho","ipfs-unixfs-exporter":"Ufvxm","debug":"lWlU4","err-code":"eQvyh","ipfs-core-utils/with-timeout-option":"5AiVw","@ipld/dag-pb":"e9gy2"}],"kqPho":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var withMfsRoot = require('./with-mfs-root.js');
var toPathComponents = require('./to-path-components.js');
var ipfsUnixfsExporter = require('ipfs-unixfs-exporter');
var errCode = require('err-code');
var cid = require('multiformats/cid');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
const IPFS_PREFIX = 'ipfs';
const toMfsPath = async (context, path, options)=>{
    const root = await withMfsRoot.loadMfsRoot(context, options);
    let output = {
        entryType: 'file'
    };
    let ipfsPath = '';
    if (cid.CID.asCID(path)) ipfsPath = `/ipfs/${path}`;
    else ipfsPath = path.toString();
    ipfsPath = ipfsPath.trim();
    ipfsPath = ipfsPath.replace(/(\/\/+)/g, '/');
    if (ipfsPath.endsWith('/') && ipfsPath.length > 1) ipfsPath = ipfsPath.substring(0, ipfsPath.length - 1);
    if (!ipfsPath) throw errCode__default['default'](new Error('paths must not be empty'), 'ERR_NO_PATH');
    if (ipfsPath.substring(0, 1) !== '/') throw errCode__default['default'](new Error('paths must start with a leading slash'), 'ERR_INVALID_PATH');
    if (ipfsPath.substring(ipfsPath.length - 1) === '/') ipfsPath = ipfsPath.substring(0, ipfsPath.length - 1);
    const pathComponents = toPathComponents.toPathComponents(ipfsPath);
    if (pathComponents[0] === IPFS_PREFIX) {
        let mfsDirectory;
        if (pathComponents.length === 2) mfsDirectory = `/${pathComponents.join('/')}`;
        else mfsDirectory = `/${pathComponents.slice(0, pathComponents.length - 1).join('/')}`;
        output = {
            type: 'ipfs',
            depth: pathComponents.length - 2,
            entryType: 'file',
            mfsPath: `/${pathComponents.join('/')}`,
            mfsDirectory,
            parts: pathComponents,
            path: `/${pathComponents.join('/')}`,
            name: pathComponents[pathComponents.length - 1]
        };
    } else {
        const mfsPath = `/${IPFS_PREFIX}/${root}${pathComponents.length ? '/' + pathComponents.join('/') : ''}`;
        const mfsDirectory = `/${IPFS_PREFIX}/${root}/${pathComponents.slice(0, pathComponents.length - 1).join('/')}`;
        output = {
            type: 'mfs',
            depth: pathComponents.length,
            entryType: 'file',
            mfsDirectory,
            mfsPath,
            parts: pathComponents,
            path: `/${pathComponents.join('/')}`,
            name: pathComponents[pathComponents.length - 1]
        };
    }
    const cidPath = output.type === 'mfs' ? output.mfsPath : output.path;
    try {
        const res = await ipfsUnixfsExporter.exporter(cidPath, context.repo.blocks, options);
        output.cid = res.cid;
        output.mfsPath = `/ipfs/${res.path}`;
        output.entryType = res.type;
        output.content = res.content;
        if ((output.entryType === 'file' || output.entryType === 'directory') && (res.type === 'file' || res.type === 'directory')) output.unixfs = res.unixfs;
    } catch (err) {
        if (err.code !== 'ERR_NOT_FOUND') throw err;
    }
    output.exists = Boolean(output.cid);
    return output;
};
exports.toMfsPath = toMfsPath;

},{"./with-mfs-root.js":"34O5c","./to-path-components.js":"1zaZd","ipfs-unixfs-exporter":"Ufvxm","err-code":"eQvyh","multiformats/cid":"fJJnW"}],"34O5c":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
var ipfsUnixfs = require('ipfs-unixfs');
var dagPB = require('@ipld/dag-pb');
var sha2 = require('multiformats/hashes/sha2');
var debug = require('debug');
var errCode = require('err-code');
var utils = require('../../../utils.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n['default'] = e;
    return Object.freeze(n);
}
var dagPB__namespace = /*#__PURE__*/ _interopNamespace(dagPB);
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
const log = debug__default['default']('ipfs:mfs:utils:with-mfs-root');
async function loadMfsRoot(context, options) {
    if (options && options.signal && options.signal.aborted) throw errCode__default['default'](new Error('Request aborted'), 'ERR_ABORTED', {
        name: 'Aborted'
    });
    await context.repo.datastore.open();
    let cid$1;
    try {
        const buf = await context.repo.datastore.get(utils.MFS_ROOT_KEY);
        cid$1 = cid.CID.decode(buf);
    } catch (err) {
        if (err.code !== 'ERR_NOT_FOUND') throw err;
        log('Creating new MFS root');
        const buf = dagPB__namespace.encode({
            Data: new ipfsUnixfs.UnixFS({
                type: 'directory'
            }).marshal(),
            Links: []
        });
        const hash = await sha2.sha256.digest(buf);
        cid$1 = cid.CID.createV0(hash);
        await context.repo.blocks.put(cid$1, buf);
        if (options && options.signal && options.signal.aborted) throw errCode__default['default'](new Error('Request aborted'), 'ERR_ABORTED', {
            name: 'Aborted'
        });
        await context.repo.datastore.put(utils.MFS_ROOT_KEY, cid$1.bytes);
    }
    log(`Loaded MFS root /ipfs/${cid$1}`);
    return cid$1;
}
exports.loadMfsRoot = loadMfsRoot;

},{"multiformats/cid":"fJJnW","ipfs-unixfs":"fttXc","@ipld/dag-pb":"e9gy2","multiformats/hashes/sha2":"i8JnP","debug":"lWlU4","err-code":"eQvyh","../../../utils.js":"4LLx8"}],"1zaZd":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
function toPathComponents(path = '') {
    return (path.trim().match(/([^\\^/]|\\\/)+/g) || []).filter(Boolean);
}
exports.toPathComponents = toPathComponents;

},{}],"lUt07":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var mergeOpts = require('merge-options');
var toMfsPath = require('./utils/to-mfs-path.js');
var debug = require('debug');
var errCode = require('err-code');
var ipfsUnixfs = require('ipfs-unixfs');
var toTrail = require('./utils/to-trail.js');
var addLink = require('./utils/add-link.js');
var updateTree = require('./utils/update-tree.js');
var updateMfsRoot = require('./utils/update-mfs-root.js');
var dagPB = require('@ipld/dag-pb');
var cid1 = require('multiformats/cid');
var itPipe = require('it-pipe');
var ipfsUnixfsImporter = require('ipfs-unixfs-importer');
var ipfsUnixfsExporter = require('ipfs-unixfs-exporter');
var last = require('it-last');
var cp = require('./cp.js');
var rm = require('./rm.js');
var persist = require('./utils/persist.js');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n['default'] = e;
    return Object.freeze(n);
}
var mergeOpts__default = /*#__PURE__*/ _interopDefaultLegacy(mergeOpts);
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
var dagPB__namespace = /*#__PURE__*/ _interopNamespace(dagPB);
var last__default = /*#__PURE__*/ _interopDefaultLegacy(last);
const mergeOptions = mergeOpts__default['default'].bind({
    ignoreUndefined: true
});
const log = debug__default['default']('ipfs:mfs:touch');
const defaultOptions = {
    flush: true,
    shardSplitThreshold: 1000,
    hashAlg: 'sha2-256',
    cidVersion: 0,
    recursive: false
};
function calculateModification(mode, originalMode, isDirectory) {
    let modification = 0;
    if (mode.includes('x') || mode.includes('X') && (isDirectory || originalMode & 1 || originalMode & 8 || originalMode & 64)) modification += 1;
    if (mode.includes('w')) modification += 2;
    if (mode.includes('r')) modification += 4;
    return modification;
}
function calculateUGO(references, modification) {
    let ugo = 0;
    if (references.includes('u')) ugo += modification << 6;
    if (references.includes('g')) ugo += modification << 3;
    if (references.includes('o')) ugo += modification;
    return ugo;
}
function calculateSpecial(references, mode, modification) {
    if (mode.includes('t')) modification += parseInt('1000', 8);
    if (mode.includes('s')) {
        if (references.includes('u')) modification += parseInt('4000', 8);
        if (references.includes('g')) modification += parseInt('2000', 8);
    }
    return modification;
}
function parseSymbolicMode(input, originalMode, isDirectory) {
    if (!originalMode) originalMode = 0;
    const match = input.match(/^(u?g?o?a?)(-?\+?=?)?(r?w?x?X?s?t?)$/);
    if (!match) throw new Error(`Invalid file mode: ${input}`);
    let [, references, operator, mode] = match;
    if (references === 'a' || !references) references = 'ugo';
    let modification = calculateModification(mode, originalMode, isDirectory);
    modification = calculateUGO(references, modification);
    modification = calculateSpecial(references, mode, modification);
    if (operator === '=') {
        if (references.includes('u')) {
            originalMode = originalMode & parseInt('7077', 8);
            originalMode = originalMode | modification;
        }
        if (references.includes('g')) {
            originalMode = originalMode & parseInt('7707', 8);
            originalMode = originalMode | modification;
        }
        if (references.includes('o')) {
            originalMode = originalMode & parseInt('7770', 8);
            originalMode = originalMode | modification;
        }
        return originalMode;
    }
    if (operator === '+') return modification | originalMode;
    if (operator === '-') return modification ^ originalMode;
    return originalMode;
}
function calculateMode(mode, metadata) {
    if (mode instanceof String || typeof mode === 'string') {
        const strMode = `${mode}`;
        if (strMode.match(/^\d+$/g)) mode = parseInt(strMode, 8);
        else mode = 0 + strMode.split(',').reduce((curr, acc)=>{
            return parseSymbolicMode(acc, curr, metadata.isDirectory());
        }, metadata.mode || 0);
    }
    return mode;
}
function createChmod(context) {
    async function mfsChmod(path, mode, options = {
    }) {
        const opts1 = mergeOptions(defaultOptions, options);
        log(`Fetching stats for ${path}`);
        const { cid: cid$1 , mfsDirectory , name  } = await toMfsPath.toMfsPath(context, path, opts1);
        if (cid$1.code !== dagPB__namespace.code) throw errCode__default['default'](new Error(`${path} was not a UnixFS node`), 'ERR_NOT_UNIXFS');
        if (opts1.recursive) {
            const root = await itPipe.pipe(async function*() {
                for await (const entry of ipfsUnixfsExporter.recursive(cid$1, context.repo.blocks)){
                    if (entry.type !== 'file' && entry.type !== 'directory') throw errCode__default['default'](new Error(`${path} was not a UnixFS node`), 'ERR_NOT_UNIXFS');
                    entry.unixfs.mode = calculateMode(mode, entry.unixfs);
                    const node = dagPB__namespace.prepare({
                        Data: entry.unixfs.marshal(),
                        Links: entry.node.Links
                    });
                    yield {
                        path: entry.path,
                        content: node
                    };
                }
            }, (source1)=>ipfsUnixfsImporter.importer(source1, context.repo.blocks, {
                    ...opts1,
                    pin: false,
                    dagBuilder: async function*(source, block, opts) {
                        for await (const entry of source)yield async function() {
                            const node = entry.content;
                            const buf = dagPB__namespace.encode(node);
                            const cid = await persist.persist(buf, block, opts);
                            if (!node.Data) throw errCode__default['default'](new Error(`${cid} had no data`), 'ERR_INVALID_NODE');
                            const unixfs = ipfsUnixfs.UnixFS.unmarshal(node.Data);
                            return {
                                cid,
                                size: buf.length,
                                path: entry.path,
                                unixfs
                            };
                        };
                    }
                })
            , (nodes)=>last__default['default'](nodes)
            );
            if (!root) throw errCode__default['default'](new Error(`Could not chmod ${path}`), 'ERR_COULD_NOT_CHMOD');
            await rm.createRm(context)(path, opts1);
            await cp.createCp(context)(`/ipfs/${root.cid}`, path, opts1);
            return;
        }
        const block1 = await context.repo.blocks.get(cid$1);
        const node1 = dagPB__namespace.decode(block1);
        if (!node1.Data) throw errCode__default['default'](new Error(`${cid$1} had no data`), 'ERR_INVALID_NODE');
        const metadata = ipfsUnixfs.UnixFS.unmarshal(node1.Data);
        metadata.mode = calculateMode(mode, metadata);
        const updatedBlock = dagPB__namespace.encode({
            Data: metadata.marshal(),
            Links: node1.Links
        });
        const hashAlg = opts1.hashAlg || defaultOptions.hashAlg;
        const hasher = await context.hashers.getHasher(hashAlg);
        const hash = await hasher.digest(updatedBlock);
        const updatedCid = cid1.CID.create(opts1.cidVersion, dagPB__namespace.code, hash);
        if (opts1.flush) await context.repo.blocks.put(updatedCid, updatedBlock);
        const trail = await toTrail.toTrail(context, mfsDirectory);
        const parent = trail[trail.length - 1];
        const parentCid = cid1.CID.decode(parent.cid.bytes);
        const parentBlock = await context.repo.blocks.get(parentCid);
        const parentNode = dagPB__namespace.decode(parentBlock);
        const result = await addLink.addLink(context, {
            parent: parentNode,
            name: name,
            cid: updatedCid,
            size: updatedBlock.length,
            flush: opts1.flush,
            hashAlg,
            cidVersion: cid$1.version,
            shardSplitThreshold: Infinity
        });
        parent.cid = result.cid;
        const newRootCid = await updateTree.updateTree(context, trail, opts1);
        await updateMfsRoot.updateMfsRoot(context, newRootCid, opts1);
    }
    return withTimeoutOption.withTimeoutOption(mfsChmod);
}
exports.createChmod = createChmod;

},{"merge-options":"8VjFj","./utils/to-mfs-path.js":"kqPho","debug":"lWlU4","err-code":"eQvyh","ipfs-unixfs":"fttXc","./utils/to-trail.js":"4VWUQ","./utils/add-link.js":"bSiQY","./utils/update-tree.js":"dTPXZ","./utils/update-mfs-root.js":"fmsnB","@ipld/dag-pb":"e9gy2","multiformats/cid":"fJJnW","it-pipe":"4jukm","ipfs-unixfs-importer":"6sMoO","ipfs-unixfs-exporter":"Ufvxm","it-last":"7VTHF","./cp.js":"8fxa7","./rm.js":"bRRGH","./utils/persist.js":"8WYWK","ipfs-core-utils/with-timeout-option":"5AiVw"}],"4VWUQ":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var ipfsUnixfsExporter = require('ipfs-unixfs-exporter');
var debug = require('debug');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
const log = debug__default['default']('ipfs:mfs:utils:to-trail');
async function toTrail(context, path) {
    log(`Creating trail for path ${path}`);
    const output = [];
    for await (const fsEntry of ipfsUnixfsExporter.walkPath(path, context.repo.blocks))output.push({
        name: fsEntry.name,
        cid: fsEntry.cid,
        size: fsEntry.size,
        type: fsEntry.type
    });
    return output;
}
exports.toTrail = toTrail;

},{"ipfs-unixfs-exporter":"Ufvxm","debug":"lWlU4"}],"bSiQY":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var dagPB = require('@ipld/dag-pb');
var cid = require('multiformats/cid');
var debug = require('debug');
var ipfsUnixfs = require('ipfs-unixfs');
var dirSharded = require('./dir-sharded.js');
var hamtUtils = require('./hamt-utils.js');
var errCode = require('err-code');
var last = require('it-last');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n['default'] = e;
    return Object.freeze(n);
}
var dagPB__namespace = /*#__PURE__*/ _interopNamespace(dagPB);
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
var last__default = /*#__PURE__*/ _interopDefaultLegacy(last);
const log = debug__default['default']('ipfs:mfs:core:utils:add-link');
async function addLink(context, options) {
    let parent = options.parent;
    if (options.parentCid) {
        const parentCid = cid.CID.asCID(options.parentCid);
        if (parentCid === null) throw errCode__default['default'](new Error('Invalid CID passed to addLink'), 'EINVALIDPARENTCID');
        if (parentCid.code !== dagPB__namespace.code) throw errCode__default['default'](new Error('Unsupported codec. Only DAG-PB is supported'), 'EINVALIDPARENTCID');
        log(`Loading parent node ${parentCid}`);
        const block = await context.repo.blocks.get(parentCid);
        parent = dagPB__namespace.decode(block);
    }
    if (!parent) throw errCode__default['default'](new Error('No parent node or CID passed to addLink'), 'EINVALIDPARENT');
    if (!options.cid) throw errCode__default['default'](new Error('No child cid passed to addLink'), 'EINVALIDCHILDCID');
    if (!options.name) throw errCode__default['default'](new Error('No child name passed to addLink'), 'EINVALIDCHILDNAME');
    if (!options.size && options.size !== 0) throw errCode__default['default'](new Error('No child size passed to addLink'), 'EINVALIDCHILDSIZE');
    if (!parent.Data) throw errCode__default['default'](new Error('Parent node with no data passed to addLink'), 'ERR_INVALID_PARENT');
    const meta = ipfsUnixfs.UnixFS.unmarshal(parent.Data);
    if (meta.type === 'hamt-sharded-directory') {
        log('Adding link to sharded directory');
        return addToShardedDirectory(context, {
            ...options,
            parent
        });
    }
    if (parent.Links.length >= options.shardSplitThreshold) {
        log('Converting directory to sharded directory');
        return convertToShardedDirectory(context, {
            ...options,
            parent,
            mtime: meta.mtime,
            mode: meta.mode
        });
    }
    log(`Adding ${options.name} (${options.cid}) to regular directory`);
    return addToDirectory(context, {
        ...options,
        parent
    });
}
const convertToShardedDirectory = async (context, options)=>{
    const result = await hamtUtils.createShard(context, options.parent.Links.map((link)=>({
            name: link.Name || '',
            size: link.Tsize || 0,
            cid: link.Hash
        })
    ).concat({
        name: options.name,
        size: options.size,
        cid: options.cid
    }), options);
    log(`Converted directory to sharded directory ${result.cid}`);
    return result;
};
const addToDirectory = async (context, options)=>{
    const parentLinks = options.parent.Links.filter((link)=>{
        return link.Name !== options.name;
    });
    parentLinks.push({
        Name: options.name,
        Tsize: options.size,
        Hash: options.cid
    });
    if (!options.parent.Data) throw errCode__default['default'](new Error('Parent node with no data passed to addToDirectory'), 'ERR_INVALID_PARENT');
    const node = ipfsUnixfs.UnixFS.unmarshal(options.parent.Data);
    let data;
    if (node.mtime) {
        const ms = Date.now();
        const secs = Math.floor(ms / 1000);
        node.mtime = {
            secs: secs,
            nsecs: (ms - secs * 1000) * 1000
        };
        data = node.marshal();
    } else data = options.parent.Data;
    options.parent = dagPB__namespace.prepare({
        Data: data,
        Links: parentLinks
    });
    const hasher = await context.hashers.getHasher(options.hashAlg);
    const buf = dagPB__namespace.encode(options.parent);
    const hash = await hasher.digest(buf);
    const cid$1 = cid.CID.create(options.cidVersion, dagPB__namespace.code, hash);
    if (options.flush) await context.repo.blocks.put(cid$1, buf);
    return {
        node: options.parent,
        cid: cid$1,
        size: buf.length
    };
};
const addToShardedDirectory = async (context, options)=>{
    const { shard , path  } = await addFileToShardedDirectory(context, options);
    const result = await last__default['default'](shard.flush(context.repo.blocks));
    if (!result) throw new Error('No result from flushing shard');
    const block = await context.repo.blocks.get(result.cid);
    const node = dagPB__namespace.decode(block);
    const parentLinks = options.parent.Links.filter((link)=>{
        return (link.Name || '').substring(0, 2) !== path[0].prefix;
    });
    const newLink = node.Links.find((link)=>(link.Name || '').substring(0, 2) === path[0].prefix
    );
    if (!newLink) throw new Error(`No link found with prefix ${path[0].prefix}`);
    parentLinks.push(newLink);
    return hamtUtils.updateHamtDirectory(context, parentLinks, path[0].bucket, options);
};
const addFileToShardedDirectory = async (context, options)=>{
    const file = {
        name: options.name,
        cid: options.cid,
        size: options.size
    };
    if (!options.parent.Data) throw errCode__default['default'](new Error('Parent node with no data passed to addFileToShardedDirectory'), 'ERR_INVALID_PARENT');
    const rootBucket = await hamtUtils.recreateInitialHamtLevel(options.parent.Links);
    const node = ipfsUnixfs.UnixFS.unmarshal(options.parent.Data);
    const shard = new dirSharded.DirSharded({
        root: true,
        dir: true,
        parent: undefined,
        parentKey: undefined,
        path: '',
        dirty: true,
        flat: false,
        mode: node.mode
    }, options);
    shard._bucket = rootBucket;
    if (node.mtime) shard.mtime = {
        secs: Math.round(Date.now() / 1000)
    };
    const position = await rootBucket._findNewBucketAndPos(file.name);
    const path = toBucketPath(position);
    path[0].node = options.parent;
    let index = 0;
    while(index < path.length){
        const segment = path[index];
        index++;
        const node = segment.node;
        if (!node) throw new Error('Segment had no node');
        const link1 = node.Links.find((link)=>(link.Name || '').substring(0, 2) === segment.prefix
        );
        if (!link1) {
            log(`Link ${segment.prefix}${file.name} will be added`);
            index = path.length;
            break;
        }
        if (link1.Name === `${segment.prefix}${file.name}`) {
            log(`Link ${segment.prefix}${file.name} will be replaced`);
            index = path.length;
            break;
        }
        if ((link1.Name || '').length > 2) {
            log(`Link ${link1.Name} ${link1.Hash} will be replaced with a subshard`);
            index = path.length;
            break;
        }
        log(`Found subshard ${segment.prefix}`);
        const block = await context.repo.blocks.get(link1.Hash);
        const subShard = dagPB__namespace.decode(block);
        if (!path[index]) {
            log(`Loaded new subshard ${segment.prefix}`);
            await hamtUtils.recreateHamtLevel(subShard.Links, rootBucket, segment.bucket, parseInt(segment.prefix, 16));
            const position = await rootBucket._findNewBucketAndPos(file.name);
            path.push({
                bucket: position.bucket,
                prefix: hamtUtils.toPrefix(position.pos),
                node: subShard
            });
            break;
        }
        const nextSegment = path[index];
        await hamtUtils.addLinksToHamtBucket(subShard.Links, nextSegment.bucket, rootBucket);
        nextSegment.node = subShard;
    }
    await shard._bucket.put(file.name, {
        size: file.size,
        cid: file.cid
    });
    return {
        shard,
        path
    };
};
const toBucketPath = (position)=>{
    const path = [
        {
            bucket: position.bucket,
            prefix: hamtUtils.toPrefix(position.pos)
        }
    ];
    let bucket = position.bucket._parent;
    let positionInBucket = position.bucket._posAtParent;
    while(bucket){
        path.push({
            bucket,
            prefix: hamtUtils.toPrefix(positionInBucket)
        });
        positionInBucket = bucket._posAtParent;
        bucket = bucket._parent;
    }
    path.reverse();
    return path;
};
exports.addLink = addLink;

},{"@ipld/dag-pb":"e9gy2","multiformats/cid":"fJJnW","debug":"lWlU4","ipfs-unixfs":"fttXc","./dir-sharded.js":"hGAQD","./hamt-utils.js":"ecFCZ","err-code":"eQvyh","it-last":"7VTHF"}],"hGAQD":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var dagPB = require('@ipld/dag-pb');
var ipfsUnixfs = require('ipfs-unixfs');
var persist = require('./persist.js');
var hamtSharding = require('hamt-sharding');
var hamtConstants = require('./hamt-constants.js');
class Dir {
    constructor(props, options2){
        this.options = options2 || {
        };
        this.root = props.root;
        this.dir = props.dir;
        this.path = props.path;
        this.dirty = props.dirty;
        this.flat = props.flat;
        this.parent = props.parent;
        this.parentKey = props.parentKey;
        this.unixfs = props.unixfs;
        this.mode = props.mode;
        this.mtime = props.mtime;
        this.cid = undefined;
        this.size = undefined;
    }
    async put(name, value2) {
    }
    get(name1) {
        return Promise.resolve(this);
    }
    async *eachChildSeries() {
    }
    async *flush(blockstore2) {
    }
}
class DirSharded extends Dir {
    constructor(props1, options1){
        super(props1, options1);
        this._bucket = hamtSharding.createHAMT({
            hashFn: hamtConstants.hamtHashFn,
            bits: hamtConstants.hamtBucketBits
        });
    }
    async put(name2, value1) {
        await this._bucket.put(name2, value1);
    }
    get(name3) {
        return this._bucket.get(name3);
    }
    childCount() {
        return this._bucket.leafCount();
    }
    directChildrenCount() {
        return this._bucket.childrenCount();
    }
    onlyChild() {
        return this._bucket.onlyChild();
    }
    async *eachChildSeries() {
        for await (const { key , value  } of this._bucket.eachLeafSeries())yield {
            key,
            child: value
        };
    }
    async *flush(blockstore1) {
        yield* flush(this._bucket, blockstore1, this, this.options);
    }
}
async function* flush(bucket, blockstore, shardRoot, options) {
    const children = bucket._children;
    const links = [];
    let childrenSize = 0;
    for(let i = 0; i < children.length; i++){
        const child = children.get(i);
        if (!child) continue;
        const labelPrefix = i.toString(16).toUpperCase().padStart(2, '0');
        if (child instanceof hamtSharding.Bucket) {
            let shard;
            for await (const subShard of (await flush(child, blockstore, null, options)))shard = subShard;
            if (!shard) throw new Error('Could not flush sharded directory, no subshard found');
            links.push({
                Name: labelPrefix,
                Tsize: shard.size,
                Hash: shard.cid
            });
            childrenSize += shard.size;
        } else if (typeof child.value.flush === 'function') {
            const dir = child.value;
            let flushedDir;
            for await (const entry of dir.flush(blockstore)){
                flushedDir = entry;
                yield flushedDir;
            }
            const label = labelPrefix + child.key;
            links.push({
                Name: label,
                Tsize: flushedDir.size,
                Hash: flushedDir.cid
            });
            childrenSize += flushedDir.size;
        } else {
            const value = child.value;
            if (!value.cid) continue;
            const label = labelPrefix + child.key;
            const size = value.size;
            links.push({
                Name: label,
                Tsize: size,
                Hash: value.cid
            });
            childrenSize += size;
        }
    }
    const data = Uint8Array.from(children.bitField().reverse());
    const dir = new ipfsUnixfs.UnixFS({
        type: 'hamt-sharded-directory',
        data,
        fanout: bucket.tableSize(),
        hashType: hamtConstants.hamtHashCode,
        mtime: shardRoot && shardRoot.mtime,
        mode: shardRoot && shardRoot.mode
    });
    const node = {
        Data: dir.marshal(),
        Links: links
    };
    const buffer = dagPB.encode(dagPB.prepare(node));
    const cid = await persist.persist(buffer, blockstore, options);
    const size = buffer.length + childrenSize;
    yield {
        cid,
        node,
        size
    };
}
exports.Dir = Dir;
exports.DirSharded = DirSharded;

},{"@ipld/dag-pb":"e9gy2","ipfs-unixfs":"fttXc","./persist.js":"8WYWK","hamt-sharding":"4VZAD","./hamt-constants.js":"doXBD"}],"8WYWK":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
var dagPB = require('@ipld/dag-pb');
var sha2 = require('multiformats/hashes/sha2');
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n['default'] = e;
    return Object.freeze(n);
}
var dagPB__namespace = /*#__PURE__*/ _interopNamespace(dagPB);
const persist = async (buffer, blockstore, options)=>{
    if (!options.codec) options.codec = dagPB__namespace;
    if (!options.hasher) options.hasher = sha2.sha256;
    if (options.cidVersion === undefined) options.cidVersion = 1;
    if (options.codec === dagPB__namespace && options.hasher !== sha2.sha256) options.cidVersion = 1;
    const multihash = await options.hasher.digest(buffer);
    const cid$1 = cid.CID.create(options.cidVersion, options.codec.code, multihash);
    if (!options.onlyHash) await blockstore.put(cid$1, buffer, {
        signal: options.signal
    });
    return cid$1;
};
exports.persist = persist;

},{"multiformats/cid":"fJJnW","@ipld/dag-pb":"e9gy2","multiformats/hashes/sha2":"i8JnP"}],"doXBD":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var murmur3 = require('@multiformats/murmur3');
const hamtHashCode = murmur3.murmur3128.code;
const hamtBucketBits = 8;
async function hamtHashFn(buf) {
    return (await murmur3.murmur3128.encode(buf)).slice(0, 8).reverse();
}
exports.hamtBucketBits = hamtBucketBits;
exports.hamtHashCode = hamtHashCode;
exports.hamtHashFn = hamtHashFn;

},{"@multiformats/murmur3":"dDuFh"}],"ecFCZ":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var dagPB = require('@ipld/dag-pb');
var hamtSharding = require('hamt-sharding');
var dirSharded = require('./dir-sharded.js');
var debug = require('debug');
var ipfsUnixfs = require('ipfs-unixfs');
var last = require('it-last');
var cid = require('multiformats/cid');
var hamtConstants = require('./hamt-constants.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n['default'] = e;
    return Object.freeze(n);
}
var dagPB__namespace = /*#__PURE__*/ _interopNamespace(dagPB);
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
var last__default = /*#__PURE__*/ _interopDefaultLegacy(last);
const log = debug__default['default']('ipfs:mfs:core:utils:hamt-utils');
const updateHamtDirectory = async (context, links, bucket, options)=>{
    if (!options.parent.Data) throw new Error('Could not update HAMT directory because parent had no data');
    const data = Uint8Array.from(bucket._children.bitField().reverse());
    const node = ipfsUnixfs.UnixFS.unmarshal(options.parent.Data);
    const dir = new ipfsUnixfs.UnixFS({
        type: 'hamt-sharded-directory',
        data,
        fanout: bucket.tableSize(),
        hashType: hamtConstants.hamtHashCode,
        mode: node.mode,
        mtime: node.mtime
    });
    const hasher = await context.hashers.getHasher(options.hashAlg);
    const parent = {
        Data: dir.marshal(),
        Links: links.sort((a, b)=>(a.Name || '').localeCompare(b.Name || '')
        )
    };
    const buf = dagPB__namespace.encode(parent);
    const hash = await hasher.digest(buf);
    const cid$1 = cid.CID.create(options.cidVersion, dagPB__namespace.code, hash);
    if (options.flush) await context.repo.blocks.put(cid$1, buf);
    return {
        node: parent,
        cid: cid$1,
        size: links.reduce((sum, link)=>sum + (link.Tsize || 0)
        , buf.length)
    };
};
const recreateHamtLevel = async (links, rootBucket, parentBucket, positionAtParent)=>{
    const bucket = new hamtSharding.Bucket({
        hash: rootBucket._options.hash,
        bits: rootBucket._options.bits
    }, parentBucket, positionAtParent);
    parentBucket._putObjectAt(positionAtParent, bucket);
    await addLinksToHamtBucket(links, bucket, rootBucket);
    return bucket;
};
const recreateInitialHamtLevel = async (links)=>{
    const bucket = hamtSharding.createHAMT({
        hashFn: hamtConstants.hamtHashFn,
        bits: hamtConstants.hamtBucketBits
    });
    await addLinksToHamtBucket(links, bucket, bucket);
    return bucket;
};
const addLinksToHamtBucket = async (links, bucket, rootBucket)=>{
    await Promise.all(links.map((link)=>{
        const linkName = link.Name || '';
        if (linkName.length === 2) {
            const pos = parseInt(linkName, 16);
            bucket._putObjectAt(pos, new hamtSharding.Bucket({
                hash: rootBucket._options.hash,
                bits: rootBucket._options.bits
            }, bucket, pos));
            return Promise.resolve();
        }
        return rootBucket.put(linkName.substring(2), {
            size: link.Tsize,
            cid: link.Hash
        });
    }));
};
const toPrefix = (position)=>{
    return position.toString(16).toUpperCase().padStart(2, '0').substring(0, 2);
};
const generatePath = async (context, fileName, rootNode)=>{
    const rootBucket = await recreateInitialHamtLevel(rootNode.Links);
    const position = await rootBucket._findNewBucketAndPos(fileName);
    const path = [
        {
            bucket: position.bucket,
            prefix: toPrefix(position.pos)
        }
    ];
    let currentBucket = position.bucket;
    while(currentBucket !== rootBucket){
        path.push({
            bucket: currentBucket,
            prefix: toPrefix(currentBucket._posAtParent)
        });
        currentBucket = currentBucket._parent;
    }
    path.reverse();
    path[0].node = rootNode;
    for(let i = 0; i < path.length; i++){
        const segment = path[i];
        if (!segment.node) throw new Error('Could not generate HAMT path');
        const link1 = segment.node.Links.filter((link)=>(link.Name || '').substring(0, 2) === segment.prefix
        ).pop();
        if (!link1) {
            log(`Link ${segment.prefix}${fileName} will be added`);
            continue;
        }
        if (link1.Name === `${segment.prefix}${fileName}`) {
            log(`Link ${segment.prefix}${fileName} will be replaced`);
            continue;
        }
        log(`Found subshard ${segment.prefix}`);
        const block = await context.repo.blocks.get(link1.Hash);
        const node = dagPB__namespace.decode(block);
        if (!path[i + 1]) {
            log(`Loaded new subshard ${segment.prefix}`);
            await recreateHamtLevel(node.Links, rootBucket, segment.bucket, parseInt(segment.prefix, 16));
            const position = await rootBucket._findNewBucketAndPos(fileName);
            path.push({
                bucket: position.bucket,
                prefix: toPrefix(position.pos),
                node: node
            });
            continue;
        }
        const nextSegment = path[i + 1];
        await addLinksToHamtBucket(node.Links, nextSegment.bucket, rootBucket);
        nextSegment.node = node;
    }
    await rootBucket.put(fileName, true);
    path.reverse();
    return {
        rootBucket,
        path
    };
};
const createShard = async (context, contents, options = {
})=>{
    const shard = new dirSharded.DirSharded({
        root: true,
        dir: true,
        parent: undefined,
        parentKey: undefined,
        path: '',
        dirty: true,
        flat: false,
        mtime: options.mtime,
        mode: options.mode
    }, options);
    for(let i = 0; i < contents.length; i++)await shard._bucket.put(contents[i].name, {
        size: contents[i].size,
        cid: contents[i].cid
    });
    const res = await last__default['default'](shard.flush(context.repo.blocks));
    if (!res) throw new Error('Flushing shard yielded no result');
    return res;
};
exports.addLinksToHamtBucket = addLinksToHamtBucket;
exports.createShard = createShard;
exports.generatePath = generatePath;
exports.recreateHamtLevel = recreateHamtLevel;
exports.recreateInitialHamtLevel = recreateInitialHamtLevel;
exports.toPrefix = toPrefix;
exports.updateHamtDirectory = updateHamtDirectory;

},{"@ipld/dag-pb":"e9gy2","hamt-sharding":"4VZAD","./dir-sharded.js":"hGAQD","debug":"lWlU4","ipfs-unixfs":"fttXc","it-last":"7VTHF","multiformats/cid":"fJJnW","./hamt-constants.js":"doXBD"}],"dTPXZ":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var debug = require('debug');
var addLink = require('./add-link.js');
var dagPB = require('@ipld/dag-pb');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
const log = debug__default['default']('ipfs:mfs:utils:update-tree');
const defaultOptions = {
    shardSplitThreshold: 1000
};
async function updateTree(context, trail, options) {
    options = Object.assign({
    }, defaultOptions, options);
    log('Trail', trail);
    trail = trail.slice().reverse();
    let index = 0;
    let child;
    for await (const block of context.repo.blocks.getMany(trail.map((node)=>node.cid
    ))){
        const node = dagPB.decode(block);
        const cid = trail[index].cid;
        const name = trail[index].name;
        index++;
        if (!child) {
            child = {
                cid,
                name,
                size: block.length
            };
            continue;
        }
        const result = await addLink.addLink(context, {
            parent: node,
            name: child.name,
            cid: child.cid,
            size: child.size,
            flush: options.flush,
            shardSplitThreshold: options.shardSplitThreshold,
            hashAlg: options.hashAlg,
            cidVersion: options.cidVersion
        });
        child = {
            cid: result.cid,
            name,
            size: result.size
        };
    }
    const { cid  } = child;
    log(`Final CID ${cid}`);
    return cid;
}
exports.updateTree = updateTree;

},{"debug":"lWlU4","./add-link.js":"bSiQY","@ipld/dag-pb":"e9gy2"}],"fmsnB":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var debug = require('debug');
var utils = require('../../../utils.js');
var errCode = require('err-code');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
const log = debug__default['default']('ipfs:mfs:utils:update-mfs-root');
async function updateMfsRoot(context, cid, options) {
    if (options && options.signal && options.signal.aborted) throw errCode__default['default'](new Error('Request aborted'), 'ERR_ABORTED', {
        name: 'Aborted'
    });
    log(`New MFS root will be ${cid}`);
    await context.repo.datastore.put(utils.MFS_ROOT_KEY, cid.bytes);
    return cid;
}
exports.updateMfsRoot = updateMfsRoot;

},{"debug":"lWlU4","../../../utils.js":"4LLx8","err-code":"eQvyh"}],"8fxa7":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var mkdir = require('./mkdir.js');
var stat = require('./stat.js');
var debug = require('debug');
var errCode = require('err-code');
var updateTree = require('./utils/update-tree.js');
var updateMfsRoot = require('./utils/update-mfs-root.js');
var addLink = require('./utils/add-link.js');
var toMfsPath = require('./utils/to-mfs-path.js');
var mergeOpts = require('merge-options');
var toTrail = require('./utils/to-trail.js');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
var mergeOpts__default = /*#__PURE__*/ _interopDefaultLegacy(mergeOpts);
const mergeOptions = mergeOpts__default['default'].bind({
    ignoreUndefined: true
});
const log = debug__default['default']('ipfs:mfs:cp');
const defaultOptions = {
    parents: false,
    flush: true,
    hashAlg: 'sha2-256',
    cidVersion: 0,
    shardSplitThreshold: 1000
};
function createCp(context) {
    async function mfsCp(from, to, opts = {
    }) {
        const options = mergeOptions(defaultOptions, opts);
        if (!Array.isArray(from)) from = [
            from
        ];
        const sources = await Promise.all(from.map((path)=>toMfsPath.toMfsPath(context, path, options)
        ));
        let destination = await toMfsPath.toMfsPath(context, to, options);
        if (!sources.length || !destination) throw errCode__default['default'](new Error('Please supply at least one source'), 'ERR_INVALID_PARAMS');
        const missing = sources.find((source)=>!source.exists
        );
        if (missing) throw errCode__default['default'](new Error(`${missing.path} does not exist`), 'ERR_INVALID_PARAMS');
        const destinationIsDirectory = isDirectory(destination);
        if (destination.exists) {
            log('Destination exists');
            if (sources.length === 1 && !destinationIsDirectory) throw errCode__default['default'](new Error('directory already has entry by that name'), 'ERR_ALREADY_EXISTS');
        } else {
            log('Destination does not exist');
            if (sources.length > 1) {
                if (!options.parents) throw errCode__default['default'](new Error('destination did not exist, pass -p to create intermediate directories'), 'ERR_INVALID_PARAMS');
                await mkdir.createMkdir(context)(destination.path, options);
                destination = await toMfsPath.toMfsPath(context, destination.path, options);
            } else if (destination.parts.length > 1) {
                const parentFolder = `/${destination.parts.slice(0, -1).join('/')}`;
                try {
                    await stat.createStat(context)(parentFolder, options);
                } catch (err) {
                    if (err.code !== 'ERR_NOT_FOUND') throw err;
                    if (!options.parents) throw errCode__default['default'](new Error('destination did not exist, pass -p to create intermediate directories'), 'ERR_INVALID_PARAMS');
                    await mkdir.createMkdir(context)(parentFolder, options);
                    destination = await toMfsPath.toMfsPath(context, destination.path, options);
                }
            }
        }
        const destinationPath = isDirectory(destination) ? destination.mfsPath : destination.mfsDirectory;
        const trail = await toTrail.toTrail(context, destinationPath);
        if (sources.length === 1) {
            const source = sources.pop();
            if (!source) throw errCode__default['default'](new Error('could not find source'), 'ERR_INVALID_PARAMS');
            const destinationName = destinationIsDirectory ? source.name : destination.name;
            log(`Only one source, copying to destination ${destinationIsDirectory ? 'directory' : 'file'} ${destinationName}`);
            return copyToFile(context, source, destinationName, trail, options);
        }
        log('Multiple sources, wrapping in a directory');
        return copyToDirectory(context, sources, destination, trail, options);
    }
    return withTimeoutOption.withTimeoutOption(mfsCp);
}
const isDirectory = (destination)=>{
    return destination.unixfs && destination.unixfs.type && destination.unixfs.type.includes('directory');
};
const copyToFile = async (context, source, destination, destinationTrail, options)=>{
    let parent = destinationTrail.pop();
    if (!parent) throw errCode__default['default'](new Error('destination had no parent'), 'ERR_INVALID_PARAMS');
    parent = await addSourceToParent(context, source, destination, parent, options);
    destinationTrail.push(parent);
    const newRootCid = await updateTree.updateTree(context, destinationTrail, options);
    await updateMfsRoot.updateMfsRoot(context, newRootCid, options);
};
const copyToDirectory = async (context, sources, destination, destinationTrail, options)=>{
    for(let i = 0; i < sources.length; i++){
        const source = sources[i];
        destination = await addSourceToParent(context, source, source.name, destination, options);
    }
    destinationTrail[destinationTrail.length - 1] = destination;
    const newRootCid = await updateTree.updateTree(context, destinationTrail, options);
    await updateMfsRoot.updateMfsRoot(context, newRootCid, options);
};
const addSourceToParent = async (context, source, childName, parent, options)=>{
    const sourceBlock = await context.repo.blocks.get(source.cid);
    const { node , cid , size  } = await addLink.addLink(context, {
        parentCid: parent.cid,
        size: sourceBlock.length,
        cid: source.cid,
        name: childName,
        hashAlg: options.hashAlg,
        cidVersion: options.cidVersion,
        flush: options.flush,
        shardSplitThreshold: options.shardSplitThreshold
    });
    parent.node = node;
    parent.cid = cid;
    parent.size = size;
    return parent;
};
exports.createCp = createCp;

},{"./mkdir.js":"j3o6O","./stat.js":"b6mWw","debug":"lWlU4","err-code":"eQvyh","./utils/update-tree.js":"dTPXZ","./utils/update-mfs-root.js":"fmsnB","./utils/add-link.js":"bSiQY","./utils/to-mfs-path.js":"kqPho","merge-options":"8VjFj","./utils/to-trail.js":"4VWUQ","ipfs-core-utils/with-timeout-option":"5AiVw"}],"j3o6O":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var errCode = require('err-code');
var debug = require('debug');
var ipfsUnixfsExporter = require('ipfs-unixfs-exporter');
var createNode = require('./utils/create-node.js');
var toPathComponents = require('./utils/to-path-components.js');
var updateMfsRoot = require('./utils/update-mfs-root.js');
var updateTree = require('./utils/update-tree.js');
var addLink = require('./utils/add-link.js');
var withMfsRoot = require('./utils/with-mfs-root.js');
var mergeOpts = require('merge-options');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
var mergeOpts__default = /*#__PURE__*/ _interopDefaultLegacy(mergeOpts);
const mergeOptions = mergeOpts__default['default'].bind({
    ignoreUndefined: true
});
const log = debug__default['default']('ipfs:mfs:mkdir');
const defaultOptions = {
    parents: false,
    hashAlg: 'sha2-256',
    cidVersion: 0,
    shardSplitThreshold: 1000,
    flush: true
};
function createMkdir(context) {
    async function mfsMkdir(path, options = {
    }) {
        const opts = mergeOptions(defaultOptions, options);
        if (!path) throw new Error('no path given to Mkdir');
        path = path.trim();
        if (path === '/') {
            if (opts.parents) return;
            throw errCode__default['default'](new Error('cannot create directory \'/\': Already exists'), 'ERR_INVALID_PATH');
        }
        if (path.substring(0, 1) !== '/') throw errCode__default['default'](new Error('paths must start with a leading slash'), 'ERR_INVALID_PATH');
        log(`Creating ${path}`);
        const pathComponents = toPathComponents.toPathComponents(path);
        if (pathComponents[0] === 'ipfs') throw errCode__default['default'](new Error('path cannot have the prefix \'ipfs\''), 'ERR_INVALID_PATH');
        const root = await withMfsRoot.loadMfsRoot(context, opts);
        let parent;
        const trail = [];
        const emptyDir = await createNode.createNode(context, 'directory', opts);
        for(let i = 0; i <= pathComponents.length; i++){
            const subPathComponents = pathComponents.slice(0, i);
            const subPath = `/ipfs/${root}/${subPathComponents.join('/')}`;
            try {
                parent = await ipfsUnixfsExporter.exporter(subPath, context.repo.blocks);
                if (parent.type !== 'file' && parent.type !== 'directory') throw errCode__default['default'](new Error(`${path} was not a UnixFS node`), 'ERR_NOT_UNIXFS');
                if (i === pathComponents.length) {
                    if (opts.parents) return;
                    throw errCode__default['default'](new Error('file already exists'), 'ERR_ALREADY_EXISTS');
                }
                trail.push({
                    name: parent.name,
                    cid: parent.cid
                });
            } catch (err) {
                if (err.code === 'ERR_NOT_FOUND') {
                    if (i < pathComponents.length && !opts.parents) throw errCode__default['default'](new Error(`Intermediate directory path ${subPath} does not exist, use the -p flag to create it`), 'ERR_NOT_FOUND');
                    await addEmptyDir(context, subPathComponents[subPathComponents.length - 1], emptyDir, trail[trail.length - 1], trail, opts);
                } else throw err;
            }
        }
        const newRootCid = await updateTree.updateTree(context, trail, opts);
        await updateMfsRoot.updateMfsRoot(context, newRootCid, opts);
    }
    return withTimeoutOption.withTimeoutOption(mfsMkdir);
}
const addEmptyDir = async (context, childName, emptyDir, parent, trail, options)=>{
    log(`Adding empty dir called ${childName} to ${parent.cid}`);
    const result = await addLink.addLink(context, {
        parent: parent.node,
        parentCid: parent.cid,
        size: 0,
        cid: emptyDir.cid,
        name: childName,
        hashAlg: options.hashAlg,
        cidVersion: options.cidVersion,
        flush: options.flush,
        shardSplitThreshold: options.shardSplitThreshold
    });
    trail[trail.length - 1].cid = result.cid;
    trail.push({
        name: childName,
        cid: emptyDir.cid
    });
};
exports.createMkdir = createMkdir;

},{"err-code":"eQvyh","debug":"lWlU4","ipfs-unixfs-exporter":"Ufvxm","./utils/create-node.js":"5f0l4","./utils/to-path-components.js":"1zaZd","./utils/update-mfs-root.js":"fmsnB","./utils/update-tree.js":"dTPXZ","./utils/add-link.js":"bSiQY","./utils/with-mfs-root.js":"34O5c","merge-options":"8VjFj","ipfs-core-utils/with-timeout-option":"5AiVw"}],"5f0l4":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var ipfsUnixfs = require('ipfs-unixfs');
var dagPB = require('@ipld/dag-pb');
var cid = require('multiformats/cid');
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n['default'] = e;
    return Object.freeze(n);
}
var dagPB__namespace = /*#__PURE__*/ _interopNamespace(dagPB);
async function createNode(context, type, options) {
    const metadata = new ipfsUnixfs.UnixFS({
        type,
        mode: options.mode,
        mtime: options.mtime
    });
    const hasher = await context.hashers.getHasher(options.hashAlg);
    const node = {
        Data: metadata.marshal(),
        Links: []
    };
    const buf = dagPB__namespace.encode(node);
    const hash = await hasher.digest(buf);
    const cid$1 = cid.CID.create(options.cidVersion, dagPB__namespace.code, hash);
    if (options.flush) await context.repo.blocks.put(cid$1, buf);
    return {
        cid: cid$1,
        node
    };
}
exports.createNode = createNode;

},{"ipfs-unixfs":"fttXc","@ipld/dag-pb":"e9gy2","multiformats/cid":"fJJnW"}],"bRRGH":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var errCode = require('err-code');
var updateTree = require('./utils/update-tree.js');
var updateMfsRoot = require('./utils/update-mfs-root.js');
var removeLink = require('./utils/remove-link.js');
var toMfsPath = require('./utils/to-mfs-path.js');
var toTrail = require('./utils/to-trail.js');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
var mergeOpts = require('merge-options');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
var mergeOpts__default = /*#__PURE__*/ _interopDefaultLegacy(mergeOpts);
const mergeOptions = mergeOpts__default['default'].bind({
    ignoreUndefined: true
});
const defaultOptions = {
    recursive: false,
    cidVersion: 0,
    hashAlg: 'sha2-256',
    flush: true,
    shardSplitThreshold: 1000
};
function createRm(context) {
    async function mfsRm(paths, opts = {
    }) {
        const options = mergeOptions(defaultOptions, opts);
        if (!Array.isArray(paths)) paths = [
            paths
        ];
        const sources = await Promise.all(paths.map((path)=>toMfsPath.toMfsPath(context, path, options)
        ));
        if (!sources.length) throw errCode__default['default'](new Error('Please supply at least one path to remove'), 'ERR_INVALID_PARAMS');
        sources.forEach((source)=>{
            if (source.path === '/') throw errCode__default['default'](new Error('Cannot delete root'), 'ERR_INVALID_PARAMS');
        });
        for (const source1 of sources)await removePath(context, source1.path, options);
    }
    return withTimeoutOption.withTimeoutOption(mfsRm);
}
const removePath = async (context, path, options)=>{
    const mfsPath = await toMfsPath.toMfsPath(context, path, options);
    const trail = await toTrail.toTrail(context, mfsPath.mfsPath);
    const child = trail[trail.length - 1];
    trail.pop();
    const parent = trail[trail.length - 1];
    if (!parent) throw errCode__default['default'](new Error(`${path} does not exist`), 'ERR_NOT_FOUND');
    if (child.type === 'directory' && !options.recursive) throw errCode__default['default'](new Error(`${path} is a directory, use -r to remove directories`), 'ERR_WAS_DIR');
    const { cid  } = await removeLink.removeLink(context, {
        parentCid: parent.cid,
        name: child.name,
        hashAlg: options.hashAlg,
        cidVersion: options.cidVersion,
        flush: options.flush,
        shardSplitThreshold: options.shardSplitThreshold
    });
    parent.cid = cid;
    const newRootCid = await updateTree.updateTree(context, trail, options);
    await updateMfsRoot.updateMfsRoot(context, newRootCid, options);
};
exports.createRm = createRm;

},{"err-code":"eQvyh","./utils/update-tree.js":"dTPXZ","./utils/update-mfs-root.js":"fmsnB","./utils/remove-link.js":"aMEFp","./utils/to-mfs-path.js":"kqPho","./utils/to-trail.js":"4VWUQ","ipfs-core-utils/with-timeout-option":"5AiVw","merge-options":"8VjFj"}],"aMEFp":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var dagPB = require('@ipld/dag-pb');
var cid1 = require('multiformats/cid');
var debug = require('debug');
var ipfsUnixfs = require('ipfs-unixfs');
var hamtUtils = require('./hamt-utils.js');
var errCode = require('err-code');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n['default'] = e;
    return Object.freeze(n);
}
var dagPB__namespace = /*#__PURE__*/ _interopNamespace(dagPB);
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
const log = debug__default['default']('ipfs:mfs:core:utils:remove-link');
async function removeLink(context, options) {
    let parent = options.parent;
    if (options.parentCid) {
        const parentCid = cid1.CID.asCID(options.parentCid);
        if (parentCid === null) throw errCode__default['default'](new Error('Invalid CID passed to removeLink'), 'EINVALIDPARENTCID');
        log(`Loading parent node ${parentCid}`);
        const block = await context.repo.blocks.get(parentCid);
        parent = dagPB__namespace.decode(block);
    }
    if (!parent) throw errCode__default['default'](new Error('No parent node or CID passed to removeLink'), 'EINVALIDPARENT');
    if (!options.name) throw errCode__default['default'](new Error('No child name passed to removeLink'), 'EINVALIDCHILDNAME');
    if (!parent.Data) throw errCode__default['default'](new Error('Parent node had no data'), 'ERR_INVALID_NODE');
    const meta = ipfsUnixfs.UnixFS.unmarshal(parent.Data);
    if (meta.type === 'hamt-sharded-directory') {
        log(`Removing ${options.name} from sharded directory`);
        return removeFromShardedDirectory(context, {
            ...options,
            parent
        });
    }
    log(`Removing link ${options.name} regular directory`);
    return removeFromDirectory(context, {
        ...options,
        parent
    });
}
const removeFromDirectory = async (context, options)=>{
    options.parent.Links = options.parent.Links.filter((link)=>{
        return link.Name !== options.name;
    });
    const parentBlock = await dagPB__namespace.encode(options.parent);
    const hasher = await context.hashers.getHasher(options.hashAlg);
    const hash = await hasher.digest(parentBlock);
    const parentCid = cid1.CID.create(options.cidVersion, dagPB__namespace.code, hash);
    await context.repo.blocks.put(parentCid, parentBlock);
    log(`Updated regular directory ${parentCid}`);
    return {
        node: options.parent,
        cid: parentCid
    };
};
const removeFromShardedDirectory = async (context, options)=>{
    const { rootBucket , path  } = await hamtUtils.generatePath(context, options.name, options.parent);
    await rootBucket.del(options.name);
    const { node  } = await updateShard(context, path, options.name, options);
    return hamtUtils.updateHamtDirectory(context, node.Links, rootBucket, options);
};
const updateShard = async (context, positions, name, options)=>{
    const last = positions.pop();
    if (!last) throw errCode__default['default'](new Error('Could not find parent'), 'EINVALIDPARENT');
    const { bucket , prefix , node  } = last;
    if (!node) throw errCode__default['default'](new Error('Could not find parent'), 'EINVALIDPARENT');
    const link1 = node.Links.find((link)=>(link.Name || '').substring(0, 2) === prefix
    );
    if (!link1) throw errCode__default['default'](new Error(`No link found with prefix ${prefix} for file ${name}`), 'ERR_NOT_FOUND');
    if (link1.Name === `${prefix}${name}`) {
        log(`Removing existing link ${link1.Name}`);
        const links = node.Links.filter((nodeLink)=>{
            return nodeLink.Name !== link1.Name;
        });
        await bucket.del(name);
        return hamtUtils.updateHamtDirectory(context, links, bucket, options);
    }
    log(`Descending into sub-shard ${link1.Name} for ${prefix}${name}`);
    const result = await updateShard(context, positions, name, options);
    let cid = result.cid;
    let size = result.size;
    let newName = prefix;
    if (result.node.Links.length === 1) {
        log(`Removing subshard for ${prefix}`);
        const link = result.node.Links[0];
        newName = `${prefix}${(link.Name || '').substring(2)}`;
        cid = link.Hash;
        size = link.Tsize || 0;
    }
    log(`Updating shard ${prefix} with name ${newName}`);
    return updateShardParent(context, bucket, node, prefix, newName, size, cid, options);
};
const updateShardParent = (context, bucket, parent, oldName, newName, size, cid, options)=>{
    const parentLinks = parent.Links.filter((link)=>{
        return link.Name !== oldName;
    });
    parentLinks.push({
        Name: newName,
        Tsize: size,
        Hash: cid
    });
    return hamtUtils.updateHamtDirectory(context, parentLinks, bucket, options);
};
exports.removeLink = removeLink;

},{"@ipld/dag-pb":"e9gy2","multiformats/cid":"fJJnW","debug":"lWlU4","ipfs-unixfs":"fttXc","./hamt-utils.js":"ecFCZ","err-code":"eQvyh"}],"b5xsT":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var stat = require('./stat.js');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
var mergeOpts = require('merge-options');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var mergeOpts__default = /*#__PURE__*/ _interopDefaultLegacy(mergeOpts);
const mergeOptions = mergeOpts__default['default'].bind({
    ignoreUndefined: true
});
const defaultOptions = {
};
function createFlush(context) {
    async function mfsFlush(path, options = {
    }) {
        options = mergeOptions(defaultOptions, options);
        const { cid  } = await stat.createStat(context)(path, options);
        return cid;
    }
    return withTimeoutOption.withTimeoutOption(mfsFlush);
}
exports.createFlush = createFlush;

},{"./stat.js":"b6mWw","ipfs-core-utils/with-timeout-option":"5AiVw","merge-options":"8VjFj"}],"3kE4H":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cp = require('./cp.js');
var rm = require('./rm.js');
var mergeOpts = require('merge-options');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var mergeOpts__default = /*#__PURE__*/ _interopDefaultLegacy(mergeOpts);
const mergeOptions = mergeOpts__default['default'].bind({
    ignoreUndefined: true
});
const defaultOptions = {
    parents: false,
    flush: true,
    cidVersion: 0,
    hashAlg: 'sha2-256',
    shardSplitThreshold: 1000
};
function createMv(context) {
    async function mfsMv(from, to, options = {
    }) {
        const opts = mergeOptions(defaultOptions, options);
        await cp.createCp(context)(from, to, opts);
        await rm.createRm(context)(from, {
            ...opts,
            recursive: true
        });
    }
    return withTimeoutOption.withTimeoutOption(mfsMv);
}
exports.createMv = createMv;

},{"./cp.js":"8fxa7","./rm.js":"bRRGH","merge-options":"8VjFj","ipfs-core-utils/with-timeout-option":"5AiVw"}],"d9D43":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var mergeOpts = require('merge-options');
var toMfsPath = require('./utils/to-mfs-path.js');
var debug = require('debug');
var errCode = require('err-code');
var ipfsUnixfs = require('ipfs-unixfs');
var toTrail = require('./utils/to-trail.js');
var addLink = require('./utils/add-link.js');
var updateTree = require('./utils/update-tree.js');
var updateMfsRoot = require('./utils/update-mfs-root.js');
var dagPB = require('@ipld/dag-pb');
var cid = require('multiformats/cid');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n['default'] = e;
    return Object.freeze(n);
}
var mergeOpts__default = /*#__PURE__*/ _interopDefaultLegacy(mergeOpts);
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
var dagPB__namespace = /*#__PURE__*/ _interopNamespace(dagPB);
const mergeOptions = mergeOpts__default['default'].bind({
    ignoreUndefined: true
});
const log = debug__default['default']('ipfs:mfs:touch');
const defaultOptions = {
    flush: true,
    shardSplitThreshold: 1000,
    cidVersion: 0,
    hashAlg: 'sha2-256'
};
function createTouch(context) {
    async function mfsTouch(path, options = {
    }) {
        const settings = mergeOptions(defaultOptions, options);
        settings.mtime = settings.mtime || new Date();
        log(`Touching ${path} mtime: ${settings.mtime}`);
        const { cid: cid$1 , mfsDirectory , name , exists  } = await toMfsPath.toMfsPath(context, path, settings);
        const hashAlg = options.hashAlg || defaultOptions.hashAlg;
        const hasher = await context.hashers.getHasher(hashAlg);
        let updatedBlock;
        let updatedCid;
        let cidVersion = settings.cidVersion;
        if (!exists) {
            const metadata = new ipfsUnixfs.UnixFS({
                type: 'file',
                mtime: settings.mtime
            });
            updatedBlock = dagPB__namespace.encode({
                Data: metadata.marshal(),
                Links: []
            });
            const hash = await hasher.digest(updatedBlock);
            updatedCid = cid.CID.create(settings.cidVersion, dagPB__namespace.code, hash);
            if (settings.flush) await context.repo.blocks.put(updatedCid, updatedBlock);
        } else {
            if (cid$1.code !== dagPB__namespace.code) throw errCode__default['default'](new Error(`${path} was not a UnixFS node`), 'ERR_NOT_UNIXFS');
            cidVersion = cid$1.version;
            const block = await context.repo.blocks.get(cid$1);
            const node = dagPB__namespace.decode(block);
            if (!node.Data) throw errCode__default['default'](new Error(`${path} had no data`), 'ERR_INVALID_NODE');
            const metadata = ipfsUnixfs.UnixFS.unmarshal(node.Data);
            metadata.mtime = settings.mtime;
            updatedBlock = dagPB__namespace.encode({
                Data: metadata.marshal(),
                Links: node.Links
            });
            const hash = await hasher.digest(updatedBlock);
            updatedCid = cid.CID.create(settings.cidVersion, dagPB__namespace.code, hash);
            if (settings.flush) await context.repo.blocks.put(updatedCid, updatedBlock);
        }
        const trail = await toTrail.toTrail(context, mfsDirectory);
        const parent = trail[trail.length - 1];
        const parentCid = parent.cid;
        const parentBlock = await context.repo.blocks.get(parentCid);
        const parentNode = dagPB__namespace.decode(parentBlock);
        const result = await addLink.addLink(context, {
            parent: parentNode,
            name: name,
            cid: updatedCid,
            size: updatedBlock.length,
            flush: settings.flush,
            shardSplitThreshold: settings.shardSplitThreshold,
            hashAlg: settings.hashAlg,
            cidVersion
        });
        parent.cid = result.cid;
        const newRootCid = await updateTree.updateTree(context, trail, settings);
        await updateMfsRoot.updateMfsRoot(context, newRootCid, settings);
    }
    return withTimeoutOption.withTimeoutOption(mfsTouch);
}
exports.createTouch = createTouch;

},{"merge-options":"8VjFj","./utils/to-mfs-path.js":"kqPho","debug":"lWlU4","err-code":"eQvyh","ipfs-unixfs":"fttXc","./utils/to-trail.js":"4VWUQ","./utils/add-link.js":"bSiQY","./utils/update-tree.js":"dTPXZ","./utils/update-mfs-root.js":"fmsnB","@ipld/dag-pb":"e9gy2","multiformats/cid":"fJJnW","ipfs-core-utils/with-timeout-option":"5AiVw"}],"96jxN":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var ipfsUnixfsExporter = require('ipfs-unixfs-exporter');
var mergeOpts = require('merge-options');
var toMfsPath = require('./utils/to-mfs-path.js');
var errCode = require('err-code');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var mergeOpts__default = /*#__PURE__*/ _interopDefaultLegacy(mergeOpts);
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
const mergeOptions = mergeOpts__default['default'].bind({
    ignoreUndefined: true
});
const defaultOptions = {
    offset: 0,
    length: Infinity
};
function createRead(context) {
    function mfsRead(path, options = {
    }) {
        options = mergeOptions(defaultOptions, options);
        return {
            [Symbol.asyncIterator]: async function* read() {
                const mfsPath = await toMfsPath.toMfsPath(context, path, options);
                const result = await ipfsUnixfsExporter.exporter(mfsPath.mfsPath, context.repo.blocks);
                if (result.type !== 'file') throw errCode__default['default'](new Error(`${path} was not a file`), 'ERR_NOT_FILE');
                if (!result.content) throw errCode__default['default'](new Error(`Could not load content stream from ${path}`), 'ERR_NO_CONTENT');
                for await (const buf of result.content({
                    offset: options.offset,
                    length: options.length
                }))yield buf;
            }
        };
    }
    return withTimeoutOption.withTimeoutOption(mfsRead);
}
exports.createRead = createRead;

},{"ipfs-unixfs-exporter":"Ufvxm","merge-options":"8VjFj","./utils/to-mfs-path.js":"kqPho","err-code":"eQvyh","ipfs-core-utils/with-timeout-option":"5AiVw"}],"juLMo":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var debug = require('debug');
var ipfsUnixfsImporter = require('ipfs-unixfs-importer');
var dagPB = require('@ipld/dag-pb');
var sha2 = require('multiformats/hashes/sha2');
var stat = require('./stat.js');
var mkdir = require('./mkdir.js');
var addLink = require('./utils/add-link.js');
var mergeOpts = require('merge-options');
var createLock = require('./utils/create-lock.js');
var toAsyncIterator = require('./utils/to-async-iterator.js');
var toMfsPath = require('./utils/to-mfs-path.js');
var toPathComponents = require('./utils/to-path-components.js');
var toTrail = require('./utils/to-trail.js');
var updateTree = require('./utils/update-tree.js');
var updateMfsRoot = require('./utils/update-mfs-root.js');
var errCode = require('err-code');
var utils = require('../../utils.js');
var last = require('it-last');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
var ipfsUnixfs = require('ipfs-unixfs');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
var mergeOpts__default = /*#__PURE__*/ _interopDefaultLegacy(mergeOpts);
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
var last__default = /*#__PURE__*/ _interopDefaultLegacy(last);
const mergeOptions = mergeOpts__default['default'].bind({
    ignoreUndefined: true
});
const log = debug__default['default']('ipfs:mfs:write');
const defaultOptions = {
    offset: 0,
    length: Infinity,
    create: false,
    truncate: false,
    rawLeaves: false,
    reduceSingleLeafToSelf: false,
    cidVersion: 0,
    hashAlg: 'sha2-256',
    parents: false,
    progress: (bytes, path)=>{
    },
    strategy: 'trickle',
    flush: true,
    leafType: 'raw',
    shardSplitThreshold: 1000
};
function createWrite(context) {
    async function mfsWrite(path, content, opts = {
    }) {
        const options = mergeOptions(defaultOptions, opts);
        let source;
        let destination;
        let parent;
        log('Reading source, destination and parent');
        await createLock.createLock().readLock(async ()=>{
            source = await toAsyncIterator.toAsyncIterator(content);
            destination = await toMfsPath.toMfsPath(context, path, options);
            parent = await toMfsPath.toMfsPath(context, destination.mfsDirectory, options);
        })();
        log('Read source, destination and parent');
        if (!options.parents && !parent.exists) throw errCode__default['default'](new Error('directory does not exist'), 'ERR_NO_EXIST');
        if (source == null) throw errCode__default['default'](new Error('could not create source'), 'ERR_NO_SOURCE');
        if (destination == null) throw errCode__default['default'](new Error('could not create destination'), 'ERR_NO_DESTINATION');
        if (!options.create && !destination.exists) throw errCode__default['default'](new Error('file does not exist'), 'ERR_NO_EXIST');
        if (destination.entryType !== 'file') throw errCode__default['default'](new Error('not a file'), 'ERR_NOT_A_FILE');
        return updateOrImport(context, path, source, destination, options);
    }
    return withTimeoutOption.withTimeoutOption(mfsWrite);
}
const updateOrImport = async (context, path, source, destination, options)=>{
    const child = await write(context, source, destination, options);
    await createLock.createLock().writeLock(async ()=>{
        const pathComponents = toPathComponents.toPathComponents(path);
        const fileName = pathComponents.pop();
        if (fileName == null) throw errCode__default['default'](new Error('source does not exist'), 'ERR_NO_EXIST');
        let parentExists = false;
        try {
            await stat.createStat(context)(`/${pathComponents.join('/')}`, options);
            parentExists = true;
        } catch (err) {
            if (err.code !== 'ERR_NOT_FOUND') throw err;
        }
        if (!parentExists) await mkdir.createMkdir(context)(`/${pathComponents.join('/')}`, options);
        const updatedPath = await toMfsPath.toMfsPath(context, path, options);
        const trail = await toTrail.toTrail(context, updatedPath.mfsDirectory);
        const parent = trail[trail.length - 1];
        if (!parent) throw errCode__default['default'](new Error('directory does not exist'), 'ERR_NO_EXIST');
        if (!parent.type || !parent.type.includes('directory')) throw errCode__default['default'](new Error(`cannot write to ${parent.name}: Not a directory`), 'ERR_NOT_A_DIRECTORY');
        const parentBlock = await context.repo.blocks.get(parent.cid);
        const parentNode = dagPB.decode(parentBlock);
        const result = await addLink.addLink(context, {
            parent: parentNode,
            name: fileName,
            cid: child.cid,
            size: child.size,
            flush: options.flush,
            shardSplitThreshold: options.shardSplitThreshold,
            hashAlg: options.hashAlg,
            cidVersion: options.cidVersion
        });
        parent.cid = result.cid;
        const newRootCid = await updateTree.updateTree(context, trail, options);
        await updateMfsRoot.updateMfsRoot(context, newRootCid, options);
    })();
};
const write = async (context, source, destination, options)=>{
    if (destination.exists) log(`Overwriting file ${destination.cid} offset ${options.offset} length ${options.length}`);
    else log(`Writing file offset ${options.offset} length ${options.length}`);
    const sources = [];
    if (options.offset > 0) {
        if (destination.unixfs) {
            log(`Writing first ${options.offset} bytes of original file`);
            sources.push(()=>{
                return destination.content({
                    offset: 0,
                    length: options.offset
                });
            });
            if (destination.unixfs.fileSize() < options.offset) {
                const extra = options.offset - destination.unixfs.fileSize();
                log(`Writing zeros for extra ${extra} bytes`);
                sources.push(asyncZeroes(extra));
            }
        } else {
            log(`Writing zeros for first ${options.offset} bytes`);
            sources.push(asyncZeroes(options.offset));
        }
    }
    sources.push(limitAsyncStreamBytes(source, options.length));
    const content = countBytesStreamed(catAsyncIterators(sources), (bytesWritten)=>{
        if (destination.unixfs && !options.truncate) {
            const fileSize = destination.unixfs.fileSize();
            if (fileSize > bytesWritten) {
                log(`Writing last ${fileSize - bytesWritten} of ${fileSize} bytes from original file starting at offset ${bytesWritten}`);
                return destination.content({
                    offset: bytesWritten
                });
            } else log('Not writing last bytes from original file');
        }
        return {
            [Symbol.asyncIterator]: async function*() {
            }
        };
    });
    let mode;
    if (options.mode !== undefined && options.mode !== null) mode = ipfsUnixfs.parseMode(options.mode);
    else if (destination && destination.unixfs) mode = destination.unixfs.mode;
    let mtime;
    if (options.mtime != null) mtime = ipfsUnixfs.parseMtime(options.mtime);
    else if (destination && destination.unixfs) mtime = destination.unixfs.mtime;
    let hasher;
    switch(options.hashAlg){
        case 'sha2-256':
            hasher = sha2.sha256;
            break;
        case 'sha2-512':
            hasher = sha2.sha512;
            break;
        default:
            throw new Error(`TODO vmx 2021-03-31: Proper error message for unsupported hash algorithms like ${options.hashAlg}`);
    }
    const result = await last__default['default'](ipfsUnixfsImporter.importer([
        {
            content: content,
            mode,
            mtime
        }
    ], context.repo.blocks, {
        progress: options.progress,
        hasher,
        cidVersion: options.cidVersion,
        strategy: options.strategy,
        rawLeaves: options.rawLeaves,
        reduceSingleLeafToSelf: options.reduceSingleLeafToSelf,
        leafType: options.leafType
    }));
    if (!result) throw errCode__default['default'](new Error(`cannot write to ${parent.name}`), 'ERR_COULD_NOT_WRITE');
    log(`Wrote ${result.cid}`);
    return {
        cid: result.cid,
        size: result.size
    };
};
const limitAsyncStreamBytes = (stream, limit)=>{
    return async function* _limitAsyncStreamBytes() {
        let emitted = 0;
        for await (const buf of stream){
            emitted += buf.length;
            if (emitted > limit) {
                yield buf.slice(0, limit - emitted);
                return;
            }
            yield buf;
        }
    };
};
const asyncZeroes = (count, chunkSize = utils.MFS_MAX_CHUNK_SIZE)=>{
    const buf = new Uint8Array(chunkSize);
    async function* _asyncZeroes() {
        while(true)yield buf.slice();
    }
    return limitAsyncStreamBytes(_asyncZeroes(), count);
};
const catAsyncIterators = async function*(sources) {
    for(let i = 0; i < sources.length; i++)yield* sources[i]();
};
const countBytesStreamed = async function*(source, notify) {
    let wrote = 0;
    for await (const buf of source){
        wrote += buf.length;
        yield buf;
    }
    for await (const buf1 of notify(wrote)){
        wrote += buf1.length;
        yield buf1;
    }
};
exports.createWrite = createWrite;

},{"debug":"lWlU4","ipfs-unixfs-importer":"6sMoO","@ipld/dag-pb":"e9gy2","multiformats/hashes/sha2":"i8JnP","./stat.js":"b6mWw","./mkdir.js":"j3o6O","./utils/add-link.js":"bSiQY","merge-options":"8VjFj","./utils/create-lock.js":"cNVmu","./utils/to-async-iterator.js":"5cTPV","./utils/to-mfs-path.js":"kqPho","./utils/to-path-components.js":"1zaZd","./utils/to-trail.js":"4VWUQ","./utils/update-tree.js":"dTPXZ","./utils/update-mfs-root.js":"fmsnB","err-code":"eQvyh","../../utils.js":"4LLx8","it-last":"7VTHF","ipfs-core-utils/with-timeout-option":"5AiVw","ipfs-unixfs":"fttXc"}],"5cTPV":[function(require,module,exports) {
var global = arguments[3];
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var errCode = require('err-code');
var debug = require('debug');
var utils = require('../../../utils.js');
var fromString = require('uint8arrays/from-string');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
const log = debug__default['default']('ipfs:mfs:utils:to-async-iterator');
function toAsyncIterator(content) {
    if (!content) throw errCode__default['default'](new Error('paths must start with a leading slash'), 'ERR_INVALID_PATH');
    if (typeof content === 'string' || content instanceof String) {
        log('Content was a string');
        content = fromString.fromString(content.toString());
    }
    if (content.length) {
        log('Content was array-like');
        return {
            [Symbol.asyncIterator]: function* bufferContent() {
                yield content;
            }
        };
    }
    if (content[Symbol.asyncIterator]) {
        log('Content was an async iterator');
        return content;
    }
    if (content[Symbol.iterator]) {
        log('Content was an iterator');
        return content;
    }
    if (global.Blob && content instanceof global.Blob) {
        log('Content was an HTML5 Blob');
        let index = 0;
        const iterator = {
            next: ()=>{
                if (index > content.size) return {
                    done: true
                };
                return new Promise((resolve, reject)=>{
                    const chunk = content.slice(index, utils.MFS_MAX_CHUNK_SIZE);
                    index += utils.MFS_MAX_CHUNK_SIZE;
                    const reader = new global.FileReader();
                    const handleLoad = (ev)=>{
                        reader.removeEventListener('loadend', handleLoad, false);
                        if (ev.error) return reject(ev.error);
                        resolve({
                            done: false,
                            value: new Uint8Array(reader.result)
                        });
                    };
                    reader.addEventListener('loadend', handleLoad);
                    reader.readAsArrayBuffer(chunk);
                });
            }
        };
        return {
            [Symbol.asyncIterator]: ()=>{
                return iterator;
            }
        };
    }
    throw errCode__default['default'](new Error(`Don't know how to convert ${content} into an async iterator`), 'ERR_INVALID_PARAMS');
}
exports.toAsyncIterator = toAsyncIterator;

},{"err-code":"eQvyh","debug":"lWlU4","../../../utils.js":"4LLx8","uint8arrays/from-string":"lo45E"}],"3Eqnu":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var ipfsUnixfsExporter = require('ipfs-unixfs-exporter');
var toMfsPath = require('./utils/to-mfs-path.js');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
var map = require('it-map');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var map__default = /*#__PURE__*/ _interopDefaultLegacy(map);
const toOutput = (fsEntry)=>{
    const output = {
        cid: fsEntry.cid,
        name: fsEntry.name,
        type: fsEntry.type === 'directory' ? 'directory' : 'file',
        size: fsEntry.size
    };
    if (fsEntry.type === 'file' || fsEntry.type === 'directory') {
        output.mode = fsEntry.unixfs.mode;
        output.mtime = fsEntry.unixfs.mtime;
    }
    return output;
};
function createLs(context) {
    async function* mfsLs(path, options = {
    }) {
        const mfsPath = await toMfsPath.toMfsPath(context, path, options);
        const fsEntry = await ipfsUnixfsExporter.exporter(mfsPath.mfsPath, context.repo.blocks);
        if (fsEntry.type === 'directory') {
            yield* map__default['default'](fsEntry.content(options), toOutput);
            return;
        }
        yield toOutput(fsEntry);
    }
    return withTimeoutOption.withTimeoutOption(mfsLs);
}
exports.createLs = createLs;

},{"ipfs-unixfs-exporter":"Ufvxm","./utils/to-mfs-path.js":"kqPho","ipfs-core-utils/with-timeout-option":"5AiVw","it-map":"dOmp3"}],"hjU4j":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var _export = require('./export.js');
var gen = require('./gen.js');
var _import = require('./import.js');
var info = require('./info.js');
var list = require('./list.js');
var rename = require('./rename.js');
var rm = require('./rm.js');
class KeyAPI {
    constructor({ keychain  }){
        this.gen = gen.createGen({
            keychain
        });
        this.list = list.createList({
            keychain
        });
        this.rm = rm.createRm({
            keychain
        });
        this.rename = rename.createRename({
            keychain
        });
        this.export = _export.createExport({
            keychain
        });
        this.import = _import.createImport({
            keychain
        });
        this.info = info.createInfo({
            keychain
        });
    }
}
exports.KeyAPI = KeyAPI;

},{"./export.js":"kcQer","./gen.js":"55f0i","./import.js":"kszce","./info.js":"8c1z8","./list.js":"1TQO7","./rename.js":"4BWsI","./rm.js":"grID1"}],"kcQer":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function createExport({ keychain  }) {
    const exportKey = (name, password)=>keychain.exportKey(name, password)
    ;
    return withTimeoutOption.withTimeoutOption(exportKey);
}
exports.createExport = createExport;

},{"ipfs-core-utils/with-timeout-option":"5AiVw"}],"55f0i":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
const DEFAULT_KEY_TYPE = 'ed25519';
const DEFAULT_KEY_SIZE = 2048;
function createGen({ keychain  }) {
    const gen = (name, options = {
        type: DEFAULT_KEY_TYPE,
        size: DEFAULT_KEY_SIZE
    })=>{
        return keychain.createKey(name, options.type || DEFAULT_KEY_TYPE, options.size || DEFAULT_KEY_SIZE);
    };
    return withTimeoutOption.withTimeoutOption(gen);
}
exports.createGen = createGen;

},{"ipfs-core-utils/with-timeout-option":"5AiVw"}],"kszce":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function createImport({ keychain  }) {
    const importKey = (name, pem, password)=>{
        return keychain.importKey(name, pem, password);
    };
    return withTimeoutOption.withTimeoutOption(importKey);
}
exports.createImport = createImport;

},{"ipfs-core-utils/with-timeout-option":"5AiVw"}],"8c1z8":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function createInfo({ keychain  }) {
    const info = (name)=>keychain.findKeyByName(name)
    ;
    return withTimeoutOption.withTimeoutOption(info);
}
exports.createInfo = createInfo;

},{"ipfs-core-utils/with-timeout-option":"5AiVw"}],"1TQO7":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function createList({ keychain  }) {
    const list = ()=>keychain.listKeys()
    ;
    return withTimeoutOption.withTimeoutOption(list);
}
exports.createList = createList;

},{"ipfs-core-utils/with-timeout-option":"5AiVw"}],"4BWsI":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function createRename({ keychain  }) {
    const rename = async (oldName, newName)=>{
        const key = await keychain.renameKey(oldName, newName);
        return {
            was: oldName,
            now: key.name,
            id: key.id,
            overwrite: false
        };
    };
    return withTimeoutOption.withTimeoutOption(rename);
}
exports.createRename = createRename;

},{"ipfs-core-utils/with-timeout-option":"5AiVw"}],"grID1":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function createRm({ keychain  }) {
    const rm = (name)=>keychain.removeKey(name)
    ;
    return withTimeoutOption.withTimeoutOption(rm);
}
exports.createRm = createRm;

},{"ipfs-core-utils/with-timeout-option":"5AiVw"}],"6z811":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var data = require('./data.js');
var get = require('./get.js');
var links = require('./links.js');
var _new = require('./new.js');
var put = require('./put.js');
var stat = require('./stat.js');
var index = require('./patch/index.js');
class ObjectAPI {
    constructor({ repo , codecs , preload  }){
        this.data = data.createData({
            repo,
            preload
        });
        this.get = get.createGet({
            repo,
            preload
        });
        this.links = links.createLinks({
            repo,
            codecs
        });
        this.new = _new.createNew({
            repo,
            preload
        });
        this.put = put.createPut({
            repo,
            preload
        });
        this.stat = stat.createStat({
            repo,
            preload
        });
        this.patch = new index.ObjectPatchAPI({
            repo,
            preload
        });
    }
}
exports.ObjectAPI = ObjectAPI;

},{"./data.js":"5UnXA","./get.js":"7TTxf","./links.js":"j0oVt","./new.js":"7Mfye","./put.js":"2V7Lq","./stat.js":"3PSlB","./patch/index.js":"7l1Lm"}],"5UnXA":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
var get = require('./get.js');
function createData({ repo , preload  }) {
    const get$1 = get.createGet({
        repo,
        preload
    });
    async function data(multihash, options = {
    }) {
        const node = await get$1(multihash, options);
        return node.Data || new Uint8Array(0);
    }
    return withTimeoutOption.withTimeoutOption(data);
}
exports.createData = createData;

},{"ipfs-core-utils/with-timeout-option":"5AiVw","./get.js":"7TTxf"}],"7TTxf":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var dagPB = require('@ipld/dag-pb');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n['default'] = e;
    return Object.freeze(n);
}
var dagPB__namespace = /*#__PURE__*/ _interopNamespace(dagPB);
function createGet({ repo , preload  }) {
    async function get(cid, options = {
    }) {
        if (options.preload !== false) preload(cid);
        const block = await repo.blocks.get(cid, options);
        return dagPB__namespace.decode(block);
    }
    return withTimeoutOption.withTimeoutOption(get);
}
exports.createGet = createGet;

},{"@ipld/dag-pb":"e9gy2","ipfs-core-utils/with-timeout-option":"5AiVw"}],"j0oVt":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var dagPB = require('@ipld/dag-pb');
var dagCBOR = require('@ipld/dag-cbor');
var raw = require('multiformats/codecs/raw');
var cid1 = require('multiformats/cid');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n['default'] = e;
    return Object.freeze(n);
}
var dagPB__namespace = /*#__PURE__*/ _interopNamespace(dagPB);
var dagCBOR__namespace = /*#__PURE__*/ _interopNamespace(dagCBOR);
var raw__namespace = /*#__PURE__*/ _interopNamespace(raw);
function findLinks(node, links = []) {
    for(const key in node){
        const val = node[key];
        if (key === '/' && Object.keys(node).length === 1) try {
            links.push({
                Name: '',
                Tsize: 0,
                Hash: cid1.CID.parse(val)
            });
            continue;
        } catch (_) {
        }
        const cid$1 = cid1.CID.asCID(val);
        if (cid$1) {
            links.push({
                Name: '',
                Tsize: 0,
                Hash: cid$1
            });
            continue;
        }
        if (Array.isArray(val)) findLinks(val, links);
        if (val && typeof val === 'object') findLinks(val, links);
    }
    return links;
}
function createLinks({ repo , codecs  }) {
    async function links(cid, options = {
    }) {
        const codec = await codecs.getCodec(cid.code);
        const block = await repo.blocks.get(cid, options);
        const node = codec.decode(block);
        if (cid.code === raw__namespace.code) return [];
        if (cid.code === dagPB__namespace.code) return node.Links;
        if (cid.code === dagCBOR__namespace.code) return findLinks(node);
        throw new Error(`Cannot resolve links from codec ${cid.code}`);
    }
    return withTimeoutOption.withTimeoutOption(links);
}
exports.createLinks = createLinks;

},{"@ipld/dag-pb":"e9gy2","@ipld/dag-cbor":"kSG7F","multiformats/codecs/raw":"dkcyY","multiformats/cid":"fJJnW","ipfs-core-utils/with-timeout-option":"5AiVw"}],"7Mfye":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var dagPB = require('@ipld/dag-pb');
var sha2 = require('multiformats/hashes/sha2');
var ipfsUnixfs = require('ipfs-unixfs');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
var cid = require('multiformats/cid');
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n['default'] = e;
    return Object.freeze(n);
}
var dagPB__namespace = /*#__PURE__*/ _interopNamespace(dagPB);
function createNew({ repo , preload  }) {
    async function _new(options = {
    }) {
        let data;
        if (options.template) {
            if (options.template === 'unixfs-dir') data = new ipfsUnixfs.UnixFS({
                type: 'directory'
            }).marshal();
            else throw new Error('unknown template');
        }
        const buf = dagPB__namespace.encode({
            Data: data,
            Links: []
        });
        const hash = await sha2.sha256.digest(buf);
        const cid$1 = cid.CID.createV0(hash);
        await repo.blocks.put(cid$1, buf, {
            signal: options.signal
        });
        if (options.preload !== false) preload(cid$1);
        return cid$1;
    }
    return withTimeoutOption.withTimeoutOption(_new);
}
exports.createNew = createNew;

},{"@ipld/dag-pb":"e9gy2","multiformats/hashes/sha2":"i8JnP","ipfs-unixfs":"fttXc","ipfs-core-utils/with-timeout-option":"5AiVw","multiformats/cid":"fJJnW"}],"2V7Lq":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var dagPB = require('@ipld/dag-pb');
var cid = require('multiformats/cid');
var sha2 = require('multiformats/hashes/sha2');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n['default'] = e;
    return Object.freeze(n);
}
var dagPB__namespace = /*#__PURE__*/ _interopNamespace(dagPB);
function createPut({ repo , preload  }) {
    async function put(obj, options = {
    }) {
        const release = await repo.gcLock.readLock();
        try {
            const buf = dagPB__namespace.encode(obj);
            const hash = await sha2.sha256.digest(buf);
            const cid$1 = cid.CID.createV0(hash);
            await repo.blocks.put(cid$1, buf, {
                signal: options.signal
            });
            if (options.preload !== false) preload(cid$1);
            if (options.pin) await repo.pins.pinRecursively(cid$1, {
                signal: options.signal
            });
            return cid$1;
        } finally{
            release();
        }
    }
    return withTimeoutOption.withTimeoutOption(put);
}
exports.createPut = createPut;

},{"@ipld/dag-pb":"e9gy2","multiformats/cid":"fJJnW","multiformats/hashes/sha2":"i8JnP","ipfs-core-utils/with-timeout-option":"5AiVw"}],"3PSlB":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var dagPB = require('@ipld/dag-pb');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
var get = require('./get.js');
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n['default'] = e;
    return Object.freeze(n);
}
var dagPB__namespace = /*#__PURE__*/ _interopNamespace(dagPB);
function createStat({ repo , preload  }) {
    const get$1 = get.createGet({
        repo,
        preload
    });
    async function stat(cid, options = {
    }) {
        const node = await get$1(cid, options);
        const serialized = dagPB__namespace.encode(node);
        const blockSize = serialized.length;
        const linkLength = node.Links.reduce((a, l)=>a + (l.Tsize || 0)
        , 0);
        return {
            Hash: cid,
            NumLinks: node.Links.length,
            BlockSize: blockSize,
            LinksSize: blockSize - (node.Data || []).length,
            DataSize: (node.Data || []).length,
            CumulativeSize: blockSize + linkLength
        };
    }
    return withTimeoutOption.withTimeoutOption(stat);
}
exports.createStat = createStat;

},{"@ipld/dag-pb":"e9gy2","ipfs-core-utils/with-timeout-option":"5AiVw","./get.js":"7TTxf"}],"7l1Lm":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var addLink = require('./add-link.js');
var appendData = require('./append-data.js');
var rmLink = require('./rm-link.js');
var setData = require('./set-data.js');
class ObjectPatchAPI {
    constructor({ repo , preload  }){
        this.addLink = addLink.createAddLink({
            repo,
            preload
        });
        this.appendData = appendData.createAppendData({
            repo,
            preload
        });
        this.rmLink = rmLink.createRmLink({
            repo,
            preload
        });
        this.setData = setData.createSetData({
            repo,
            preload
        });
    }
}
exports.ObjectPatchAPI = ObjectPatchAPI;

},{"./add-link.js":"iVIU4","./append-data.js":"cvF5D","./rm-link.js":"aGk8o","./set-data.js":"korON"}],"iVIU4":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
var get = require('../get.js');
var put = require('../put.js');
function createAddLink({ repo , preload  }) {
    const get$1 = get.createGet({
        repo,
        preload
    });
    const put$1 = put.createPut({
        repo,
        preload
    });
    async function addLink(cid, link, options = {
    }) {
        const node = await get$1(cid, options);
        return put$1({
            ...node,
            Links: node.Links.concat([
                link
            ])
        }, options);
    }
    return withTimeoutOption.withTimeoutOption(addLink);
}
exports.createAddLink = createAddLink;

},{"ipfs-core-utils/with-timeout-option":"5AiVw","../get.js":"7TTxf","../put.js":"2V7Lq"}],"cvF5D":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
var concat = require('uint8arrays/concat');
var get = require('../get.js');
var put = require('../put.js');
function createAppendData({ repo , preload  }) {
    const get$1 = get.createGet({
        repo,
        preload
    });
    const put$1 = put.createPut({
        repo,
        preload
    });
    async function appendData(cid, data, options = {
    }) {
        const node = await get$1(cid, options);
        const newData = concat.concat([
            node.Data || [],
            data
        ]);
        return put$1({
            ...node,
            Data: newData
        }, options);
    }
    return withTimeoutOption.withTimeoutOption(appendData);
}
exports.createAppendData = createAppendData;

},{"ipfs-core-utils/with-timeout-option":"5AiVw","uint8arrays/concat":"fLIrL","../get.js":"7TTxf","../put.js":"2V7Lq"}],"aGk8o":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
var get = require('../get.js');
var put = require('../put.js');
function createRmLink({ repo , preload  }) {
    const get$1 = get.createGet({
        repo,
        preload
    });
    const put$1 = put.createPut({
        repo,
        preload
    });
    async function rmLink(multihash, linkRef, options = {
    }) {
        const node = await get$1(multihash, options);
        const name = (typeof linkRef === 'string' ? linkRef : linkRef.Name) || '';
        node.Links = node.Links.filter((l)=>l.Name !== name
        );
        return put$1(node, options);
    }
    return withTimeoutOption.withTimeoutOption(rmLink);
}
exports.createRmLink = createRmLink;

},{"ipfs-core-utils/with-timeout-option":"5AiVw","../get.js":"7TTxf","../put.js":"2V7Lq"}],"korON":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
var get = require('../get.js');
var put = require('../put.js');
function createSetData({ repo , preload  }) {
    const get$1 = get.createGet({
        repo,
        preload
    });
    const put$1 = put.createPut({
        repo,
        preload
    });
    async function setData(cid, data, options = {
    }) {
        const node = await get$1(cid, options);
        return put$1({
            ...node,
            Data: data
        }, options);
    }
    return withTimeoutOption.withTimeoutOption(setData);
}
exports.createSetData = createSetData;

},{"ipfs-core-utils/with-timeout-option":"5AiVw","../get.js":"7TTxf","../put.js":"2V7Lq"}],"fcFbR":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var gc = require('./gc.js');
var stat = require('./stat.js');
var version = require('./version.js');
class RepoAPI {
    constructor({ repo , hashers  }){
        this.gc = gc.createGc({
            repo,
            hashers
        });
        this.stat = stat.createStat({
            repo
        });
        this.version = version.createVersion({
            repo
        });
        this.setApiAddr = (addr)=>repo.apiAddr.set(addr)
        ;
    }
}
exports.RepoAPI = RepoAPI;

},{"./gc.js":"gTT4p","./stat.js":"hVrP1","./version.js":"4wSKf"}],"gTT4p":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var debug = require('debug');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
var withMfsRoot = require('../files/utils/with-mfs-root.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
const log = debug__default['default']('ipfs:repo:gc');
function createGc({ repo , hashers  }) {
    async function* gc(options = {
    }) {
        const start = Date.now();
        let mfsRootCid;
        try {
            mfsRootCid = await withMfsRoot.loadMfsRoot({
                repo,
                hashers
            }, options);
            await repo.pins.pinRecursively(mfsRootCid);
            yield* repo.gc();
        } finally{
            if (mfsRootCid) await repo.pins.unpin(mfsRootCid);
        }
        log(`Complete (${Date.now() - start}ms)`);
    }
    return withTimeoutOption.withTimeoutOption(gc);
}
exports.createGc = createGc;

},{"debug":"lWlU4","ipfs-core-utils/with-timeout-option":"5AiVw","../files/utils/with-mfs-root.js":"34O5c"}],"hVrP1":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function createStat({ repo  }) {
    async function stat(options = {
    }) {
        const stats = await repo.stat();
        return {
            numObjects: BigInt(stats.numObjects.toString()),
            repoSize: BigInt(stats.repoSize.toString()),
            repoPath: stats.repoPath,
            version: `${stats.version}`,
            storageMax: BigInt(stats.storageMax.toString())
        };
    }
    return withTimeoutOption.withTimeoutOption(stat);
}
exports.createStat = createStat;

},{"ipfs-core-utils/with-timeout-option":"5AiVw"}],"4wSKf":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
var constants = require('ipfs-repo/constants');
function createVersion({ repo  }) {
    async function version(options = {
    }) {
        try {
            await repo._checkInitialized(options);
        } catch (err) {
            const match = [
                /Key not found in database \[\/version\]/,
                /ENOENT/,
                /repo is not initialized yet/
            ].some((m)=>{
                return m.test(err.message);
            });
            if (match) return constants.repoVersion;
            throw err;
        }
        return repo.version.get();
    }
    return withTimeoutOption.withTimeoutOption(version);
}
exports.createVersion = createVersion;

},{"ipfs-core-utils/with-timeout-option":"5AiVw","ipfs-repo/constants":"5TBOB"}],"5TBOB":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
const repoVersion = 11;
exports.repoVersion = repoVersion;

},{}],"5ncKr":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var bw = require('./bw.js');
var stat = require('../repo/stat.js');
var stat$1 = require('../bitswap/stat.js');
class StatsAPI {
    constructor({ repo , network  }){
        this.repo = stat.createStat({
            repo
        });
        this.bw = bw.createBw({
            network
        });
        this.bitswap = stat$1.createStat({
            network
        });
    }
}
exports.StatsAPI = StatsAPI;

},{"./bw.js":"j4mcK","../repo/stat.js":"hVrP1","../bitswap/stat.js":"6sOnY"}],"j4mcK":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var parseDuration = require('parse-duration');
var errCode = require('err-code');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var parseDuration__default = /*#__PURE__*/ _interopDefaultLegacy(parseDuration);
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
function getBandwidthStats(libp2p, opts) {
    let stats;
    if (!libp2p.metrics) stats = undefined;
    else if (opts.peer) stats = libp2p.metrics.forPeer(opts.peer);
    else if (opts.proto) stats = libp2p.metrics.forProtocol(opts.proto);
    else stats = libp2p.metrics.global;
    if (!stats) return {
        totalIn: BigInt(0),
        totalOut: BigInt(0),
        rateIn: 0,
        rateOut: 0
    };
    const { movingAverages , snapshot  } = stats;
    return {
        totalIn: BigInt(snapshot.dataReceived.integerValue().toString()),
        totalOut: BigInt(snapshot.dataSent.integerValue().toString()),
        rateIn: movingAverages.dataReceived[60000].movingAverage() / 60,
        rateOut: movingAverages.dataSent[60000].movingAverage() / 60
    };
}
function createBw({ network  }) {
    const bw = async function*(options = {
    }) {
        const { libp2p  } = await network.use(options);
        if (!options.poll) {
            yield getBandwidthStats(libp2p, options);
            return;
        }
        const interval = options.interval || 1000;
        let ms = -1;
        try {
            ms = typeof interval === 'string' ? parseDuration__default['default'](interval) || -1 : interval;
            if (!ms || ms < 0) throw new Error('invalid duration');
        } catch (err) {
            throw errCode__default['default'](err, 'ERR_INVALID_POLL_INTERVAL');
        }
        let timeoutId;
        try {
            while(true){
                yield getBandwidthStats(libp2p, options);
                await new Promise((resolve)=>{
                    timeoutId = setTimeout(resolve, ms);
                });
            }
        } finally{
            clearTimeout(timeoutId);
        }
    };
    return withTimeoutOption.withTimeoutOption(bw);
}
exports.createBw = createBw;

},{"parse-duration":"2Fbu7","err-code":"eQvyh","ipfs-core-utils/with-timeout-option":"5AiVw"}],"cFB52":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var debug = require('debug');
var repo2 = require('ipfs-core-config/repo');
var getDefaultConfig = require('ipfs-core-config/config');
var fromString = require('uint8arrays/from-string');
var toString = require('uint8arrays/to-string');
var PeerId = require('peer-id');
var mergeOpts = require('merge-options');
var profiles1 = require('./config/profiles.js');
var errors$1 = require('../errors.js');
var libp2p = require('./libp2p.js');
var errors = require('ipfs-repo/errors');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
var getDefaultConfig__default = /*#__PURE__*/ _interopDefaultLegacy(getDefaultConfig);
var PeerId__default = /*#__PURE__*/ _interopDefaultLegacy(PeerId);
var mergeOpts__default = /*#__PURE__*/ _interopDefaultLegacy(mergeOpts);
const mergeOptions = mergeOpts__default['default'].bind({
    ignoreUndefined: true
});
const log = debug__default['default']('ipfs:components:peer:storage');
class Storage {
    constructor(peerId1, keychain, repo1, print2, isNew){
        this.print = print2;
        this.peerId = peerId1;
        this.keychain = keychain;
        this.repo = repo1;
        this.print = print2;
        this.isNew = isNew;
    }
    static async start(print1, codecs, options1) {
        const { repoAutoMigrate , repo: inputRepo , onMigrationProgress  } = options1;
        const repo$1 = typeof inputRepo === 'string' || inputRepo == null ? repo2.createRepo(print1, codecs, {
            path: inputRepo,
            autoMigrate: repoAutoMigrate,
            onMigrationProgress: onMigrationProgress
        }) : inputRepo;
        const { peerId , keychain , isNew  } = await loadRepo(print1, repo$1, options1);
        return new Storage(peerId, keychain, repo$1, print1, isNew);
    }
}
const loadRepo = async (print, repo, options)=>{
    if (!repo.closed) return {
        ...await configureRepo(repo, options),
        isNew: false
    };
    try {
        await repo.open();
        return {
            ...await configureRepo(repo, options),
            isNew: false
        };
    } catch (err) {
        if (err.code !== errors.ERR_REPO_NOT_INITIALIZED) throw err;
        if (options.init && options.init.allowNew === false) throw new errors$1.NotEnabledError('Initialization of new repos disabled by config, pass `config.init.isNew: true` to enable it');
        return {
            ...await initRepo(print, repo, options),
            isNew: true
        };
    }
};
const initRepo = async (print, repo, options)=>{
    const initOptions = options.init || {
    };
    const exists = await repo.exists();
    log('repo exists?', exists);
    if (exists === true) throw new Error('repo already exists');
    const peerId = initOptions.privateKey ? await decodePeerId(initOptions.privateKey) : await initPeerId(print, initOptions);
    const identity = peerIdToIdentity(peerId);
    log('peer identity: %s', identity.PeerID);
    const config = {
        ...mergeOptions(applyProfiles(getDefaultConfig__default['default'](), initOptions.profiles), options.config),
        Identity: identity
    };
    await repo.init(config);
    await repo.open();
    log('repo opened');
    const keychainConfig = {
        pass: options.pass
    };
    try {
        keychainConfig.dek = await repo.config.get('Keychain.DEK');
    } catch (err) {
        if (err.code !== 'ERR_NOT_FOUND') throw err;
    }
    const libp2p$1 = await libp2p.createLibp2p({
        options: undefined,
        multiaddrs: undefined,
        peerId,
        repo,
        config,
        keychainConfig
    });
    if (libp2p$1.keychain && libp2p$1.keychain.opts) {
        await libp2p$1.loadKeychain();
        await repo.config.set('Keychain', {
            DEK: libp2p$1.keychain.opts.dek
        });
    }
    return {
        peerId,
        keychain: libp2p$1.keychain
    };
};
const decodePeerId = (peerId)=>{
    log('using user-supplied private-key');
    return typeof peerId === 'object' ? peerId : PeerId__default['default'].createFromPrivKey(fromString.fromString(peerId, 'base64pad'));
};
const initPeerId = (print, { algorithm ='Ed25519' , bits =2048  })=>{
    print('generating %s keypair...', algorithm);
    return PeerId__default['default'].create({
        keyType: algorithm,
        bits
    });
};
const peerIdToIdentity = (peerId)=>({
        PeerID: peerId.toB58String(),
        PrivKey: toString.toString(peerId.privKey.bytes, 'base64pad')
    })
;
const configureRepo = async (repo, options)=>{
    const config = options.config;
    const profiles = options.init && options.init.profiles || [];
    const pass = options.pass;
    const original = await repo.config.getAll();
    const changed = mergeConfigs(applyProfiles(original, profiles), config);
    if (original !== changed) await repo.config.replace(changed);
    if (!changed.Identity || !changed.Identity.PrivKey) throw new errors$1.NotInitializedError('No private key was found in the config, please intialize the repo');
    const peerId = await PeerId__default['default'].createFromPrivKey(changed.Identity.PrivKey);
    const libp2p$1 = await libp2p.createLibp2p({
        options: undefined,
        multiaddrs: undefined,
        peerId,
        repo,
        config: changed,
        keychainConfig: {
            pass,
            ...changed.Keychain
        }
    });
    if (libp2p$1.keychain) await libp2p$1.loadKeychain();
    return {
        peerId,
        keychain: libp2p$1.keychain
    };
};
const mergeConfigs = (config, changes)=>changes ? mergeOptions(config, changes) : config
;
const applyProfiles = (config1, profiles$1)=>{
    return (profiles$1 || []).reduce((config, name)=>{
        const profile = profiles1.profiles[name];
        if (!profile) throw new Error(`Could not find profile with name '${name}'`);
        log('applying profile %s', name);
        return profile.transform(config);
    }, config1);
};
exports.Storage = Storage;

},{"debug":"lWlU4","ipfs-core-config/repo":"gkgIZ","ipfs-core-config/config":"i1esH","uint8arrays/from-string":"lo45E","uint8arrays/to-string":"g3mCQ","peer-id":"4VGWt","merge-options":"8VjFj","./config/profiles.js":"6tQxX","../errors.js":"itpk8","./libp2p.js":"78HPV","ipfs-repo/errors":"7UmNp"}],"gkgIZ":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var ipfsRepo = require('ipfs-repo');
var datastoreLevel = require('datastore-level');
var blockstoreDatastoreAdapter = require('blockstore-datastore-adapter');
var memory = require('ipfs-repo/locks/memory');
function createRepo(print, codecs, options) {
    const repoPath = options.path || 'ipfs';
    return ipfsRepo.createRepo(repoPath, (codeOrName)=>codecs.getCodec(codeOrName)
    , {
        root: new datastoreLevel.LevelDatastore(repoPath, {
            prefix: '',
            version: 2
        }),
        blocks: new blockstoreDatastoreAdapter.BlockstoreDatastoreAdapter(new datastoreLevel.LevelDatastore(`${repoPath}/blocks`, {
            prefix: '',
            version: 2
        })),
        datastore: new datastoreLevel.LevelDatastore(`${repoPath}/datastore`, {
            prefix: '',
            version: 2
        }),
        keys: new datastoreLevel.LevelDatastore(`${repoPath}/keys`, {
            prefix: '',
            version: 2
        }),
        pins: new datastoreLevel.LevelDatastore(`${repoPath}/pins`, {
            prefix: '',
            version: 2
        })
    }, {
        autoMigrate: options.autoMigrate,
        onMigrationProgress: options.onMigrationProgress || print,
        repoLock: memory.MemoryLock
    });
}
exports.createRepo = createRepo;

},{"ipfs-repo":"gglG3","datastore-level":"8iLmT","blockstore-datastore-adapter":"k8J0L","ipfs-repo/locks/memory":"g28e0"}],"gglG3":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var _get = require('just-safe-get');
var debug = require('debug');
var errCode = require('err-code');
var migrator = require('ipfs-repo-migrations');
var bytes = require('bytes');
var merge = require('merge-options');
var constants = require('./constants.js');
var version = require('./version.js');
var config = require('./config.js');
var spec1 = require('./spec.js');
var apiAddr = require('./api-addr.js');
var idstore = require('./idstore.js');
var defaultOptions = require('./default-options.js');
var defaultDatastore = require('./default-datastore.js');
var errors = require('./errors.js');
var pinManager = require('./pin-manager.js');
var pinnedBlockstore = require('./pinned-blockstore.js');
var mortice = require('mortice');
var gc = require('./gc.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n["default"] = e;
    return Object.freeze(n);
}
var _get__default = /*#__PURE__*/ _interopDefaultLegacy(_get);
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
var migrator__namespace = /*#__PURE__*/ _interopNamespace(migrator);
var bytes__default = /*#__PURE__*/ _interopDefaultLegacy(bytes);
var merge__default = /*#__PURE__*/ _interopDefaultLegacy(merge);
var mortice__default = /*#__PURE__*/ _interopDefaultLegacy(mortice);
const log = debug__default["default"]('ipfs:repo');
const noLimit = Number.MAX_SAFE_INTEGER;
const AUTO_MIGRATE_CONFIG_KEY = 'repoAutoMigrate';
class Repo {
    constructor(path1, loadCodec1, backends2, options1){
        if (typeof path1 !== 'string') throw new Error('missing repo path');
        if (typeof loadCodec1 !== 'function') throw new Error('missing codec loader');
        this.options = merge__default["default"](defaultOptions, options1);
        this.closed = true;
        this.path = path1;
        this.root = backends2.root;
        this.datastore = backends2.datastore;
        this.keys = backends2.keys;
        const blockstore = backends2.blocks;
        const pinstore = backends2.pins;
        this.pins = new pinManager.PinManager({
            pinstore,
            blockstore,
            loadCodec: loadCodec1
        });
        const pinnedBlockstore$1 = pinnedBlockstore.createPinnedBlockstore(this.pins, blockstore);
        this.blocks = idstore.createIdStore(pinnedBlockstore$1);
        this.version = version.version(this.root);
        this.config = config.config(this.root);
        this.spec = spec1.spec(this.root);
        this.apiAddr = apiAddr.apiAddr(this.root);
        this.gcLock = mortice__default["default"](path1, {
            singleProcess: this.options.repoOwner !== false
        });
        this.gc = gc.gc({
            gcLock: this.gcLock,
            pins: this.pins,
            blockstore: this.blocks,
            root: this.root,
            loadCodec: loadCodec1
        });
    }
    async init(config1) {
        log('initializing at: %s', this.path);
        await this._openRoot();
        await this.config.replace(buildConfig(config1));
        await this.spec.set(buildDatastoreSpec(config1));
        await this.version.set(constants.repoVersion);
    }
    async isInitialized() {
        if (!this.closed) return true;
        try {
            await this._openRoot();
            await this._checkInitialized();
            await this.root.close();
            return true;
        } catch (err) {
            return false;
        }
    }
    async open() {
        if (!this.closed) throw errCode__default["default"](new Error('repo is already open'), errors.ERR_REPO_ALREADY_OPEN);
        log('opening at: %s', this.path);
        try {
            await this._openRoot();
            await this._checkInitialized();
            this._lockfile = await this._openLock();
            log('acquired repo.lock');
            const isCompatible = await this.version.check(constants.repoVersion);
            if (!isCompatible) {
                if (await this._isAutoMigrationEnabled()) await this._migrate(constants.repoVersion, {
                    root: this.root,
                    datastore: this.datastore,
                    pins: this.pins.pinstore,
                    blocks: this.pins.blockstore,
                    keys: this.keys
                });
                else throw new errors.InvalidRepoVersionError('Incompatible repo versions. Automatic migrations disabled. Please migrate the repo manually.');
            }
            log('creating datastore');
            await this.datastore.open();
            log('creating blocks');
            await this.blocks.open();
            log('creating keystore');
            await this.keys.open();
            log('creating pins');
            await this.pins.pinstore.open();
            this.closed = false;
            log('all opened');
        } catch (err) {
            if (this._lockfile) try {
                await this._closeLock();
                this._lockfile = null;
            } catch (err2) {
                log('error removing lock', err2);
            }
            throw err;
        }
    }
    async _openRoot() {
        try {
            await this.root.open();
        } catch (err) {
            if (err.message !== 'Already open') throw err;
        }
    }
    async _openLock() {
        const lockfile = await this.options.repoLock.lock(this.path);
        if (typeof lockfile.close !== 'function') throw errCode__default["default"](new Error('Locks must have a close method'), 'ERR_NO_CLOSE_FUNCTION');
        return lockfile;
    }
    _closeLock() {
        return this._lockfile && this._lockfile.close();
    }
    async _checkInitialized() {
        log('init check');
        let config;
        try {
            [config] = await Promise.all([
                this.config.exists(),
                this.spec.exists(),
                this.version.exists()
            ]);
        } catch (err) {
            if (err.code === 'ERR_NOT_FOUND') throw errCode__default["default"](new Error('repo is not initialized yet'), errors.ERR_REPO_NOT_INITIALIZED, {
                path: this.path
            });
            throw err;
        }
        if (!config) throw errCode__default["default"](new Error('repo is not initialized yet'), errors.ERR_REPO_NOT_INITIALIZED, {
            path: this.path
        });
    }
    async close() {
        if (this.closed) throw errCode__default["default"](new Error('repo is already closed'), errors.ERR_REPO_ALREADY_CLOSED);
        log('closing at: %s', this.path);
        try {
            await this.apiAddr.delete();
        } catch (err) {
            if (err.code !== errors.ERR_REPO_NOT_INITIALIZED && !err.message.startsWith('ENOENT')) throw err;
        }
        await Promise.all([
            this.root,
            this.blocks,
            this.keys,
            this.datastore,
            this.pins.pinstore
        ].map((store)=>store && store.close()
        ));
        log('unlocking');
        this.closed = true;
        await this._closeLock();
    }
    exists() {
        return this.version.exists();
    }
    async stat() {
        if (this.datastore && this.keys) {
            const [storageMax, blocks, version, datastore, keys] = await Promise.all([
                this._storageMaxStat(),
                this._blockStat(),
                this.version.get(),
                getSize(this.datastore),
                getSize(this.keys)
            ]);
            const size = blocks.size + datastore + keys;
            return {
                repoPath: this.path,
                storageMax,
                version: version,
                numObjects: blocks.count,
                repoSize: size
            };
        }
        throw errCode__default["default"](new Error('repo is not initialized yet'), errors.ERR_REPO_NOT_INITIALIZED, {
            path: this.path
        });
    }
    async _isAutoMigrationEnabled() {
        if (this.options.autoMigrate !== undefined) return this.options.autoMigrate;
        let autoMigrateConfig;
        try {
            autoMigrateConfig = await this.config.get(AUTO_MIGRATE_CONFIG_KEY);
        } catch (e) {
            if (e.code === errors.NotFoundError.code) autoMigrateConfig = true;
            else throw e;
        }
        return autoMigrateConfig;
    }
    async _migrate(toVersion, backends1) {
        const currentRepoVersion = await this.version.get();
        if (currentRepoVersion > toVersion) {
            log(`reverting to version ${toVersion}`);
            return migrator__namespace.revert(this.path, backends1, this.options, toVersion, {
                ignoreLock: true,
                onProgress: this.options.onMigrationProgress
            });
        } else {
            log(`migrating to version ${toVersion}`);
            return migrator__namespace.migrate(this.path, backends1, this.options, toVersion, {
                ignoreLock: true,
                onProgress: this.options.onMigrationProgress
            });
        }
    }
    async _storageMaxStat() {
        try {
            const max = await this.config.get('Datastore.StorageMax');
            return BigInt(bytes__default["default"](max));
        } catch (err) {
            return BigInt(noLimit);
        }
    }
    async _blockStat() {
        let count = BigInt(0);
        let size = BigInt(0);
        if (this.blocks) for await (const { key , value  } of this.blocks.query({
        })){
            count += BigInt(1);
            size += BigInt(value.byteLength);
            size += BigInt(key.bytes.byteLength);
        }
        return {
            count,
            size
        };
    }
}
async function getSize(datastore) {
    let sum = BigInt(0);
    for await (const block of datastore.query({
    })){
        sum += BigInt(block.value.byteLength);
        sum += BigInt(block.key.uint8Array().byteLength);
    }
    return sum;
}
function createRepo(path, loadCodec, backends, options) {
    return new Repo(path, loadCodec, backends, options);
}
function buildConfig(_config) {
    _config.Datastore = Object.assign({
    }, defaultDatastore, _get__default["default"](_config, 'datastore'));
    return _config;
}
function buildDatastoreSpec(_config) {
    const spec = {
        ...defaultDatastore.Spec,
        ..._get__default["default"](_config, 'Datastore.Spec')
    };
    return {
        type: spec.type,
        mounts: spec.mounts.map((mounting)=>({
                mountpoint: mounting.mountpoint,
                type: mounting.child.type,
                path: mounting.child.path,
                shardFunc: mounting.child.shardFunc
            })
        )
    };
}
exports.createRepo = createRepo;

},{"just-safe-get":"2nGd3","debug":"lWlU4","err-code":"eQvyh","ipfs-repo-migrations":"hcsdN","bytes":"eL1Ft","merge-options":"8VjFj","./constants.js":"5TBOB","./version.js":"kkcrh","./config.js":"37tgW","./spec.js":"5G4sj","./api-addr.js":"hF0IH","./idstore.js":"7sykp","./default-options.js":"hkFtx","./default-datastore.js":"cPM4s","./errors.js":"7UmNp","./pin-manager.js":"2sfAy","./pinned-blockstore.js":"hwoye","mortice":"lcmcW","./gc.js":"iIDzf"}],"2nGd3":[function(require,module,exports) {
module.exports = get;
/*
  const obj = {a: {aa: {aaa: 2}}, b: 4};

  get(obj, 'a.aa.aaa'); // 2
  get(obj, ['a', 'aa', 'aaa']); // 2

  get(obj, 'b.bb.bbb'); // undefined
  get(obj, ['b', 'bb', 'bbb']); // undefined

  get(obj.a, 'aa.aaa'); // 2
  get(obj.a, ['aa', 'aaa']); // 2

  get(obj.b, 'bb.bbb'); // undefined
  get(obj.b, ['bb', 'bbb']); // undefined

  get(obj.b, 'bb.bbb', 42); // 42
  get(obj.b, ['bb', 'bbb'], 42); // 42

  get(null, 'a'); // undefined
  get(undefined, ['a']); // undefined

  get(null, 'a', 42); // 42
  get(undefined, ['a'], 42); // 42

  const obj = {a: {}};
  const sym = Symbol();
  obj.a[sym] = 4;
  get(obj.a, sym); // 4
*/ function get(obj, propsArg, defaultValue) {
    if (!obj) return defaultValue;
    var props, prop;
    if (Array.isArray(propsArg)) props = propsArg.slice(0);
    if (typeof propsArg == 'string') props = propsArg.split('.');
    if (typeof propsArg == 'symbol') props = [
        propsArg
    ];
    if (!Array.isArray(props)) throw new Error('props arg must be an array, a string or a symbol');
    while(props.length){
        prop = props.shift();
        if (!obj) return defaultValue;
        obj = obj[prop];
        if (obj === undefined) return defaultValue;
    }
    return obj;
}

},{}],"hcsdN":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var index = require('../migrations/index.js');
var version = require('./repo/version.js');
var errors$1 = require('./errors.js');
var utils = require('./utils.js');
var debug = require('debug');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
const log = debug__default["default"]('ipfs:repo:migrator');
function getLatestMigrationVersion(migrations) {
    migrations = migrations || index;
    if (!Array.isArray(migrations) || migrations.length === 0) return 0;
    return migrations[migrations.length - 1].version;
}
async function migrate(path, backends, repoOptions, toVersion, { ignoreLock =false , onProgress , isDryRun =false , migrations  }) {
    migrations = migrations || index;
    if (!path) throw new errors.RequiredParameterError('Path argument is required!');
    if (!repoOptions) throw new errors.RequiredParameterError('repoOptions argument is required!');
    if (!toVersion) throw new errors.RequiredParameterError('toVersion argument is required!');
    if (!Number.isInteger(toVersion) || toVersion <= 0) throw new errors.InvalidValueError('Version has to be positive integer!');
    backends = utils.wrapBackends(backends);
    const currentVersion = await version.getVersion(backends);
    if (currentVersion === toVersion) {
        log('Nothing to migrate.');
        return;
    }
    if (currentVersion > toVersion) throw new errors.InvalidValueError(`Current repo's version (${currentVersion}) is higher then toVersion (${toVersion}), you probably wanted to revert it?`);
    verifyAvailableMigrations(migrations, currentVersion, toVersion);
    let lock;
    if (!isDryRun && !ignoreLock) lock = await repoOptions.repoLock.lock(path);
    try {
        for (const migration of migrations){
            if (toVersion !== undefined && migration.version > toVersion) break;
            if (migration.version <= currentVersion) continue;
            log(`Migrating version ${migration.version}`);
            try {
                if (!isDryRun) {
                    let progressCallback = ()=>{
                    };
                    if (onProgress) progressCallback = (percent, message)=>onProgress(migration.version, percent.toFixed(2), message)
                    ;
                    await migration.migrate(backends, progressCallback);
                }
            } catch (e) {
                const lastSuccessfullyMigratedVersion = migration.version - 1;
                log(`An exception was raised during execution of migration. Setting the repo's version to last successfully migrated version: ${lastSuccessfullyMigratedVersion}`);
                await version.setVersion(lastSuccessfullyMigratedVersion, backends);
                throw new Error(`During migration to version ${migration.version} exception was raised: ${e.stack || e.message || e}`);
            }
            log(`Migrating to version ${migration.version} finished`);
        }
        if (!isDryRun) await version.setVersion(toVersion || getLatestMigrationVersion(migrations), backends);
        log('Repo successfully migrated', toVersion !== undefined ? `to version ${toVersion}!` : 'to latest version!');
    } finally{
        if (!isDryRun && !ignoreLock && lock) await lock.close();
    }
}
async function revert(path, backends, repoOptions, toVersion, { ignoreLock =false , onProgress , isDryRun =false , migrations  }) {
    migrations = migrations || index;
    if (!path) throw new errors.RequiredParameterError('Path argument is required!');
    if (!repoOptions) throw new errors.RequiredParameterError('repoOptions argument is required!');
    if (!toVersion) throw new errors.RequiredParameterError('When reverting migrations, you have to specify to which version to revert!');
    if (!Number.isInteger(toVersion) || toVersion <= 0) throw new errors.InvalidValueError('Version has to be positive integer!');
    backends = utils.wrapBackends(backends);
    const currentVersion = await version.getVersion(backends);
    if (currentVersion === toVersion) {
        log('Nothing to revert.');
        return;
    }
    if (currentVersion < toVersion) throw new errors.InvalidValueError(`Current repo's version (${currentVersion}) is lower then toVersion (${toVersion}), you probably wanted to migrate it?`);
    verifyAvailableMigrations(migrations, toVersion, currentVersion, true);
    let lock;
    if (!isDryRun && !ignoreLock) lock = await repoOptions.repoLock.lock(path);
    log(`Reverting from version ${currentVersion} to ${toVersion}`);
    try {
        const reversedMigrationArray = migrations.slice().reverse();
        for (const migration of reversedMigrationArray){
            if (migration.version <= toVersion) break;
            if (migration.version > currentVersion) continue;
            log(`Reverting migration version ${migration.version}`);
            try {
                if (!isDryRun) {
                    let progressCallback = ()=>{
                    };
                    if (onProgress) progressCallback = (percent, message)=>onProgress(migration.version, percent.toFixed(2), message)
                    ;
                    await migration.revert(backends, progressCallback);
                }
            } catch (e) {
                const lastSuccessfullyRevertedVersion = migration.version;
                log(`An exception was raised during execution of migration. Setting the repo's version to last successfully reverted version: ${lastSuccessfullyRevertedVersion}`);
                await version.setVersion(lastSuccessfullyRevertedVersion, backends);
                e.message = `During reversion to version ${migration.version} exception was raised: ${e.message}`;
                throw e;
            }
            log(`Reverting to version ${migration.version} finished`);
        }
        if (!isDryRun) await version.setVersion(toVersion, backends);
        log(`All migrations successfully reverted to version ${toVersion}!`);
    } finally{
        if (!isDryRun && !ignoreLock && lock) await lock.close();
    }
}
function verifyAvailableMigrations(migrations, fromVersion, toVersion, checkReversibility = false) {
    let migrationCounter = 0;
    for (const migration of migrations){
        if (migration.version > toVersion) break;
        if (migration.version > fromVersion) {
            if (checkReversibility && !migration.revert) throw new errors.NonReversibleMigrationError(`It is not possible to revert to version ${fromVersion} because migration version ${migration.version} is not reversible. Cancelling reversion.`);
            migrationCounter++;
        }
    }
    if (migrationCounter !== toVersion - fromVersion) throw new errors.InvalidValueError(`The ipfs-repo-migrations package does not have all migration to migrate from version ${fromVersion} to ${toVersion}`);
}
const getCurrentRepoVersion = version.getVersion;
const errors = errors$1;
const migrations1 = index;
exports.errors = errors;
exports.getCurrentRepoVersion = getCurrentRepoVersion;
exports.getLatestMigrationVersion = getLatestMigrationVersion;
exports.migrate = migrate;
exports.migrations = migrations1;
exports.revert = revert;

},{"../migrations/index.js":"eXQEB","./repo/version.js":"8KYZw","./errors.js":"2t05i","./utils.js":"kjXDZ","debug":"lWlU4"}],"eXQEB":[function(require,module,exports) {
'use strict';
var index = require('./migration-8/index.js');
var index$1 = require('./migration-9/index.js');
var index$2 = require('./migration-10/index.js');
var index$3 = require('./migration-11/index.js');
const emptyMigration = {
    description: 'Empty migration.',
    migrate: ()=>{
    },
    revert: ()=>{
    },
    empty: true
};
var defaultMigrations = [
    Object.assign({
        version: 1
    }, emptyMigration),
    Object.assign({
        version: 2
    }, emptyMigration),
    Object.assign({
        version: 3
    }, emptyMigration),
    Object.assign({
        version: 4
    }, emptyMigration),
    Object.assign({
        version: 5
    }, emptyMigration),
    Object.assign({
        version: 6
    }, emptyMigration),
    Object.assign({
        version: 7
    }, emptyMigration),
    index.migration,
    index$1.migration,
    index$2.migration,
    index$3.migration
];
module.exports = defaultMigrations;

},{"./migration-8/index.js":"i1qd2","./migration-9/index.js":"6WOly","./migration-10/index.js":"3NdjG","./migration-11/index.js":"if5sA"}],"i1qd2":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
var key1 = require('interface-datastore/key');
var debug = require('debug');
var length = require('it-length');
var base32 = require('multiformats/bases/base32');
var raw = require('multiformats/codecs/raw');
var mhd = require('multiformats/hashes/digest');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n["default"] = e;
    return Object.freeze(n);
}
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
var length__default = /*#__PURE__*/ _interopDefaultLegacy(length);
var raw__namespace = /*#__PURE__*/ _interopNamespace(raw);
var mhd__namespace = /*#__PURE__*/ _interopNamespace(mhd);
const log = debug__default["default"]('ipfs:repo:migrator:migration-8');
function unwrap(blockstore) {
    if (blockstore.child) return unwrap(blockstore.child);
    return blockstore;
}
function keyToMultihash(key$1) {
    try {
        const buf = base32.base32.decode(`b${key$1.toString().toLowerCase().slice(1)}`);
        const multihash = cid.CID.decode(buf).multihash.bytes;
        const multihashStr = base32.base32.encode(multihash).slice(1).toUpperCase();
        return new key1.Key(`/${multihashStr}`, false);
    } catch (err) {
        return key$1;
    }
}
function keyToCid(key$1) {
    try {
        const buf = base32.base32.decode(`b${key$1.toString().toLowerCase().slice(1)}`);
        const digest = mhd__namespace.decode(buf);
        const multihash = base32.base32.encode(cid.CID.createV1(raw__namespace.code, digest).bytes).slice(1);
        return new key1.Key(`/${multihash.toUpperCase()}`, false);
    } catch  {
        return key$1;
    }
}
async function process(backends, onProgress, keyFunction) {
    const blockstore = backends.blocks;
    await blockstore.open();
    const unwrapped = unwrap(blockstore);
    const blockCount = await length__default["default"](unwrapped.queryKeys({
        filters: [
            (key)=>{
                const newKey = keyFunction(key);
                return newKey.toString() !== key.toString();
            }
        ]
    }));
    try {
        let counter = 0;
        for await (const block of unwrapped.query({
        })){
            const newKey = keyFunction(block.key);
            if (newKey.toString() !== block.key.toString()) {
                counter += 1;
                log(`Migrating Block from ${block.key} to ${newKey}`, await unwrapped.has(block.key));
                await unwrapped.delete(block.key);
                await unwrapped.put(newKey, block.value);
                onProgress(counter / blockCount * 100, `Migrated Block from ${block.key} to ${newKey}`);
            }
        }
    } finally{
        await blockstore.close();
    }
}
const migration = {
    version: 8,
    description: 'Transforms key names into base32 encoding and converts Block store to use bare multihashes encoded as base32',
    migrate: (backends, onProgress = ()=>{
    })=>{
        return process(backends, onProgress, keyToMultihash);
    },
    revert: (backends, onProgress = ()=>{
    })=>{
        return process(backends, onProgress, keyToCid);
    }
};
exports.migration = migration;

},{"multiformats/cid":"fJJnW","interface-datastore/key":"ccQWS","debug":"lWlU4","it-length":"6wGCy","multiformats/bases/base32":"63xDB","multiformats/codecs/raw":"dkcyY","multiformats/hashes/digest":"fkA58"}],"6wGCy":[function(require,module,exports) {
'use strict';
/**
 * Consumes the passed iterator and returns the number of items it contained.
 *
 * @param {AsyncIterable<any> | Iterable<any>} iterator
 * @returns {Promise<number>}
 */ const length = async (iterator)=>{
    let count = 0;
    for await (const _ of iterator)count++;
    return count;
};
module.exports = length;

},{}],"6WOly":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
var dagPb = require('@ipld/dag-pb');
var cbor = require('cborg');
var pinSet = require('./pin-set.js');
var utils = require('./utils.js');
var length = require('it-length');
var sha2 = require('multiformats/hashes/sha2');
var mhd = require('multiformats/hashes/digest');
var base32 = require('multiformats/bases/base32');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n["default"] = e;
    return Object.freeze(n);
}
var dagPb__namespace = /*#__PURE__*/ _interopNamespace(dagPb);
var cbor__namespace = /*#__PURE__*/ _interopNamespace(cbor);
var length__default = /*#__PURE__*/ _interopDefaultLegacy(length);
var mhd__namespace = /*#__PURE__*/ _interopNamespace(mhd);
async function pinsToDatastore(blockstore, datastore, pinstore, onProgress) {
    if (!await datastore.has(utils.PIN_DS_KEY)) return;
    const mh = await datastore.get(utils.PIN_DS_KEY);
    const cid$1 = cid.CID.decode(mh);
    const pinRootBuf = await blockstore.get(cid$1);
    const pinRoot = dagPb__namespace.decode(pinRootBuf);
    let counter = 0;
    const pinCount = await length__default["default"](pinSet.loadSet(blockstore, pinRoot, utils.PinTypes.recursive)) + await length__default["default"](pinSet.loadSet(blockstore, pinRoot, utils.PinTypes.direct));
    for await (const cid2 of pinSet.loadSet(blockstore, pinRoot, utils.PinTypes.recursive)){
        counter++;
        const pin = {
            depth: Infinity
        };
        if (cid2.version !== 0) pin.version = cid2.version;
        if (cid2.code !== dagPb__namespace.code) pin.codec = cid2.code;
        await pinstore.put(utils.cidToKey(cid2), cbor__namespace.encode(pin));
        onProgress(counter / pinCount * 100, `Migrated recursive pin ${cid2}`);
    }
    for await (const cid1 of pinSet.loadSet(blockstore, pinRoot, utils.PinTypes.direct)){
        counter++;
        const pin = {
            depth: 0
        };
        if (cid1.version !== 0) pin.version = cid1.version;
        if (cid1.code !== dagPb__namespace.code) pin.codec = cid1.code;
        await pinstore.put(utils.cidToKey(cid1), cbor__namespace.encode(pin));
        onProgress(counter / pinCount * 100, `Migrated direct pin ${cid1}`);
    }
    await blockstore.delete(cid$1);
    await datastore.delete(utils.PIN_DS_KEY);
}
async function pinsToDAG(blockstore, datastore, pinstore, onProgress) {
    const recursivePins = [];
    const directPins = [];
    let counter = 0;
    const pinCount = await length__default["default"](pinstore.queryKeys({
    }));
    for await (const { key , value  } of pinstore.query({
    })){
        counter++;
        const pin = cbor__namespace.decode(value);
        const cid$1 = cid.CID.create(pin.version || 0, pin.codec || dagPb__namespace.code, mhd__namespace.decode(base32.base32.decode('b' + key.toString().toLowerCase().split('/').pop())));
        if (pin.depth === 0) {
            onProgress(counter / pinCount * 100, `Reverted direct pin ${cid$1}`);
            directPins.push(cid$1);
        } else {
            onProgress(counter / pinCount * 100, `Reverted recursive pin ${cid$1}`);
            recursivePins.push(cid$1);
        }
    }
    onProgress(100, 'Updating pin root');
    const pinRoot = {
        Links: [
            await pinSet.storeSet(blockstore, utils.PinTypes.direct, directPins),
            await pinSet.storeSet(blockstore, utils.PinTypes.recursive, recursivePins)
        ]
    };
    const buf = dagPb__namespace.encode(pinRoot);
    const digest = await sha2.sha256.digest(buf);
    const cid$1 = cid.CID.createV0(digest);
    await blockstore.put(cid$1, buf);
    await datastore.put(utils.PIN_DS_KEY, cid$1.bytes);
}
async function process(backends, onProgress, fn) {
    const blockstore = backends.blocks;
    const datastore = backends.datastore;
    const pinstore = backends.pins;
    await blockstore.open();
    await datastore.open();
    await pinstore.open();
    try {
        await fn(blockstore, datastore, pinstore, onProgress);
    } finally{
        await pinstore.close();
        await datastore.close();
        await blockstore.close();
    }
}
const migration = {
    version: 9,
    description: 'Migrates pins to datastore',
    migrate: (backends, onProgress = ()=>{
    })=>{
        return process(backends, onProgress, pinsToDatastore);
    },
    revert: (backends, onProgress = ()=>{
    })=>{
        return process(backends, onProgress, pinsToDAG);
    }
};
exports.migration = migration;

},{"multiformats/cid":"fJJnW","@ipld/dag-pb":"e9gy2","cborg":"6ZYxo","./pin-set.js":"b9HT8","./utils.js":"rbvua","it-length":"6wGCy","multiformats/hashes/sha2":"i8JnP","multiformats/hashes/digest":"fkA58","multiformats/bases/base32":"63xDB"}],"b9HT8":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid1 = require('multiformats/cid');
var pin1 = require('./pin.js');
var fnv1a = require('fnv1a');
var varint = require('varint');
var dagPb = require('@ipld/dag-pb');
var utils = require('./utils.js');
var concat = require('uint8arrays/concat');
var compare = require('uint8arrays/compare');
var toString = require('uint8arrays/to-string');
var fromString = require('uint8arrays/from-string');
var sha2 = require('multiformats/hashes/sha2');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n["default"] = e;
    return Object.freeze(n);
}
var fnv1a__default = /*#__PURE__*/ _interopDefaultLegacy(fnv1a);
var varint__default = /*#__PURE__*/ _interopDefaultLegacy(varint);
var dagPb__namespace = /*#__PURE__*/ _interopNamespace(dagPb);
const PinSet = pin1.ipfs.pin.Set;
function readHeader(rootNode) {
    const rootData = rootNode.Data;
    if (!rootData) throw new Error('No data present');
    const hdrLength = varint__default["default"].decode(rootData);
    const vBytes = varint__default["default"].decode.bytes;
    if (vBytes <= 0) throw new Error('Invalid Set header length');
    if (vBytes + hdrLength > rootData.length) throw new Error('Impossibly large set header length');
    const hdrSlice = rootData.slice(vBytes, hdrLength + vBytes);
    const header = PinSet.toObject(PinSet.decode(hdrSlice), {
        defaults: false,
        arrays: true,
        longs: Number,
        objects: false
    });
    if (header.version !== 1) throw new Error(`Unsupported Set version: ${header.version}`);
    if (header.fanout > rootNode.Links.length) throw new Error('Impossibly large fanout');
    return {
        header: header,
        data: rootData.slice(hdrLength + vBytes)
    };
}
function hash(seed, key) {
    const buffer = new Uint8Array(4);
    const dataView = new DataView(buffer.buffer);
    dataView.setUint32(0, seed, true);
    const encodedKey = fromString.fromString(key.toString());
    const data = concat.concat([
        buffer,
        encodedKey
    ], buffer.byteLength + encodedKey.byteLength);
    return fnv1a__default["default"](toString.toString(data));
}
async function* walkItems(blockstore, node) {
    const pbh = readHeader(node);
    let idx = 0;
    for (const link of node.Links){
        if (idx < pbh.header.fanout) {
            const linkHash = link.Hash;
            if (!utils.EMPTY_KEY.equals(linkHash)) {
                const buf = await blockstore.get(linkHash);
                const node = dagPb__namespace.decode(buf);
                yield* walkItems(blockstore, node);
            }
        } else yield link.Hash;
        idx++;
    }
}
async function* loadSet(blockstore, rootNode, name) {
    const link = rootNode.Links.find((l)=>l.Name === name
    );
    if (!link) throw new Error('No link found with name ' + name);
    const buf = await blockstore.get(link.Hash);
    const node = dagPb__namespace.decode(buf);
    yield* walkItems(blockstore, node);
}
function storeItems(blockstore, items) {
    async function storePins(pins, depth) {
        const pbHeader = PinSet.encode({
            version: 1,
            fanout: utils.DEFAULT_FANOUT,
            seed: depth
        }).finish();
        const header = varint__default["default"].encode(pbHeader.length);
        const headerBuf = concat.concat([
            header,
            pbHeader
        ]);
        const fanoutLinks = [];
        for(let i = 0; i < utils.DEFAULT_FANOUT; i++){
            fanoutLinks.push({
                Name: '',
                Tsize: 1,
                Hash: utils.EMPTY_KEY
            });
        }
        if (pins.length <= utils.MAX_ITEMS) {
            const nodes = pins.map((item)=>{
                return {
                    link: {
                        Name: '',
                        Tsize: 1,
                        Hash: item.key
                    },
                    data: item.data || new Uint8Array()
                };
            }).sort((a, b)=>{
                return compare.compare(a.link.Hash.bytes, b.link.Hash.bytes);
            });
            const rootLinks = fanoutLinks.concat(nodes.map((item)=>item.link
            ));
            const rootData = concat.concat([
                headerBuf,
                ...nodes.map((item)=>item.data
                )
            ]);
            return {
                Data: rootData,
                Links: rootLinks
            };
        } else {
            const bins1 = pins.reduce((bins, pin)=>{
                const n = hash(depth, pin.key) % utils.DEFAULT_FANOUT;
                bins[n] = n in bins ? bins[n].concat([
                    pin
                ]) : [
                    pin
                ];
                return bins;
            }, []);
            let idx = 0;
            for (const bin of bins1){
                const child = await storePins(bin, depth + 1);
                await storeChild(child, idx);
                idx++;
            }
            return {
                Data: headerBuf,
                Links: fanoutLinks
            };
        }
        async function storeChild(child, binIdx) {
            const buf = dagPb__namespace.encode(child);
            const digest = await sha2.sha256.digest(buf);
            const cid$1 = cid1.CID.createV0(digest);
            await blockstore.put(cid$1, buf);
            const size = child.Links.reduce((acc, curr)=>acc + (curr.Tsize || 0)
            , 0) + buf.length;
            fanoutLinks[binIdx] = {
                Name: '',
                Tsize: size,
                Hash: cid$1
            };
        }
    }
    return storePins(items, 0);
}
async function storeSet(blockstore, type, cids) {
    const rootNode = await storeItems(blockstore, cids.map((cid)=>{
        return {
            key: cid
        };
    }));
    const buf = dagPb__namespace.encode(rootNode);
    const digest = await sha2.sha256.digest(buf);
    const cid$1 = cid1.CID.createV0(digest);
    await blockstore.put(cid$1, buf);
    const size = rootNode.Links.reduce((acc, curr)=>acc + curr.Tsize
    , 0) + buf.length;
    return {
        Name: type,
        Tsize: size,
        Hash: cid$1
    };
}
exports.loadSet = loadSet;
exports.storeSet = storeSet;

},{"multiformats/cid":"fJJnW","./pin.js":"5qSc0","fnv1a":"2yaXz","varint":"l84uL","@ipld/dag-pb":"e9gy2","./utils.js":"rbvua","uint8arrays/concat":"fLIrL","uint8arrays/compare":"m8amP","uint8arrays/to-string":"g3mCQ","uint8arrays/from-string":"lo45E","multiformats/hashes/sha2":"i8JnP"}],"5qSc0":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var $protobuf = require('protobufjs/minimal.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var $protobuf__default = /*#__PURE__*/ _interopDefaultLegacy($protobuf);
const $Reader = $protobuf__default["default"].Reader, $Writer = $protobuf__default["default"].Writer, $util = $protobuf__default["default"].util;
const $root = $protobuf__default["default"].roots['default'] || ($protobuf__default["default"].roots['default'] = {
});
const ipfs1 = $root.ipfs = (()=>{
    const ipfs = {
    };
    ipfs.pin = (function() {
        const pin = {
        };
        pin.Set = (function() {
            function Set(p) {
                if (p) {
                    for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
                }
            }
            Set.prototype.version = 0;
            Set.prototype.fanout = 0;
            Set.prototype.seed = 0;
            Set.encode = function encode(m, w) {
                if (!w) w = $Writer.create();
                if (m.version != null && Object.hasOwnProperty.call(m, 'version')) w.uint32(8).uint32(m.version);
                if (m.fanout != null && Object.hasOwnProperty.call(m, 'fanout')) w.uint32(16).uint32(m.fanout);
                if (m.seed != null && Object.hasOwnProperty.call(m, 'seed')) w.uint32(29).fixed32(m.seed);
                return w;
            };
            Set.decode = function decode(r, l) {
                if (!(r instanceof $Reader)) r = $Reader.create(r);
                var c = l === undefined ? r.len : r.pos + l, m = new $root.ipfs.pin.Set();
                while(r.pos < c){
                    var t = r.uint32();
                    switch(t >>> 3){
                        case 1:
                            m.version = r.uint32();
                            break;
                        case 2:
                            m.fanout = r.uint32();
                            break;
                        case 3:
                            m.seed = r.fixed32();
                            break;
                        default:
                            r.skipType(t & 7);
                            break;
                    }
                }
                return m;
            };
            Set.fromObject = function fromObject(d) {
                if (d instanceof $root.ipfs.pin.Set) return d;
                var m = new $root.ipfs.pin.Set();
                if (d.version != null) m.version = d.version >>> 0;
                if (d.fanout != null) m.fanout = d.fanout >>> 0;
                if (d.seed != null) m.seed = d.seed >>> 0;
                return m;
            };
            Set.toObject = function toObject(m, o) {
                if (!o) o = {
                };
                var d = {
                };
                if (o.defaults) {
                    d.version = 0;
                    d.fanout = 0;
                    d.seed = 0;
                }
                if (m.version != null && m.hasOwnProperty('version')) d.version = m.version;
                if (m.fanout != null && m.hasOwnProperty('fanout')) d.fanout = m.fanout;
                if (m.seed != null && m.hasOwnProperty('seed')) d.seed = m.seed;
                return d;
            };
            Set.prototype.toJSON = function toJSON() {
                return this.constructor.toObject(this, $protobuf__default["default"].util.toJSONOptions);
            };
            return Set;
        })();
        return pin;
    })();
    return ipfs;
})();
exports["default"] = $root;
exports.ipfs = ipfs1;

},{"protobufjs/minimal.js":"9Jmso"}],"2yaXz":[function(require,module,exports) {
/**
 * Created by schwarzkopfb on 15/11/17.
 */ /**
 * FNV-1a hash generation init value.
 * It's exposed, because this allows user to override it.
 *
 * @type {number}
 */ hash.BASE = 2166136261;
/**
 * Generates 32 bit FNV-1a hash from the given string.
 * As explained here: http://isthe.com/chongo/tech/comp/fnv/
 *
 * @param s {string} String to generate hash from.
 * @returns {number} The result integer hash.
 */ function hash(s) {
    var h = hash.BASE;
    for(var i = 0, l = s.length; i < l; i++){
        h ^= s.charCodeAt(i);
        h += (h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24);
    }
    return h >>> 0;
}
module.exports = hash;

},{}],"rbvua":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var key = require('interface-datastore/key');
var base32 = require('multiformats/bases/base32');
var cid1 = require('multiformats/cid');
const PIN_DS_KEY = new key.Key('/local/pins');
const DEFAULT_FANOUT = 256;
const MAX_ITEMS = 8192;
const EMPTY_KEY = cid1.CID.parse('QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n');
const PinTypes = {
    direct: 'direct',
    recursive: 'recursive'
};
function cidToKey(cid) {
    return new key.Key(`/${base32.base32.encode(cid.multihash.bytes).toUpperCase().substring(1)}`);
}
exports.DEFAULT_FANOUT = DEFAULT_FANOUT;
exports.EMPTY_KEY = EMPTY_KEY;
exports.MAX_ITEMS = MAX_ITEMS;
exports.PIN_DS_KEY = PIN_DS_KEY;
exports.PinTypes = PinTypes;
exports.cidToKey = cidToKey;

},{"interface-datastore/key":"ccQWS","multiformats/bases/base32":"63xDB","multiformats/cid":"fJJnW"}],"m8amP":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
function compare(a, b) {
    for(let i = 0; i < a.byteLength; i++){
        if (a[i] < b[i]) return -1;
        if (a[i] > b[i]) return 1;
    }
    if (a.byteLength > b.byteLength) return 1;
    if (a.byteLength < b.byteLength) return -1;
    return 0;
}
exports.compare = compare;

},{}],"3NdjG":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var utils = require('../../src/utils.js');
var fromString = require('uint8arrays/from-string');
var toString = require('uint8arrays/to-string');
async function keysToBinary(name, store, onProgress = ()=>{
}) {
    const db = utils.findLevelJs(store);
    if (!db) {
        onProgress(`${name} did not need an upgrade`);
        return;
    }
    onProgress(`Upgrading ${name}`);
    const upgrade = (key, value)=>{
        return [
            {
                type: 'del',
                key: key
            },
            {
                type: 'put',
                key: fromString.fromString(key),
                value: value
            }
        ];
    };
    await withEach(db, upgrade);
}
async function keysToStrings(name, store, onProgress = ()=>{
}) {
    const db = utils.findLevelJs(store);
    if (!db) {
        onProgress(`${name} did not need a downgrade`);
        return;
    }
    onProgress(`Downgrading ${name}`);
    const downgrade = (key, value)=>{
        return [
            {
                type: 'del',
                key: key
            },
            {
                type: 'put',
                key: toString.toString(key),
                value: value
            }
        ];
    };
    await withEach(db, downgrade);
}
function unwrap(store) {
    if (store.child) return unwrap(store.child);
    return store;
}
async function process(backends, onProgress, fn) {
    const datastores = Object.entries(backends).map(([key, backend])=>({
            key,
            backend: unwrap(backend)
        })
    ).filter(({ key , backend  })=>backend.constructor.name === 'LevelDatastore'
    ).map(({ key , backend  })=>({
            name: key,
            store: backend
        })
    );
    onProgress(0, `Migrating ${datastores.length} dbs`);
    let migrated = 0;
    const progress = (message)=>{
        onProgress(Math.round(migrated / datastores.length * 100), message);
    };
    for (const { name , store  } of datastores){
        await store.open();
        try {
            await fn(name, store, progress);
        } finally{
            migrated++;
            await store.close();
        }
    }
    onProgress(100, `Migrated ${datastores.length} dbs`);
}
const migration = {
    version: 10,
    description: 'Migrates datastore-level keys to binary',
    migrate: (backends, onProgress = ()=>{
    })=>{
        return process(backends, onProgress, keysToBinary);
    },
    revert: (backends, onProgress = ()=>{
    })=>{
        return process(backends, onProgress, keysToStrings);
    }
};
function withEach(db, fn) {
    function batch(operations, next) {
        const store = db.store('readwrite');
        const transaction = store.transaction;
        let index = 0;
        let error;
        transaction.onabort = ()=>next(error || transaction.error || new Error('aborted by user'))
        ;
        transaction.oncomplete = ()=>next()
        ;
        function loop() {
            const op = operations[index++];
            const key = op.key;
            let req;
            try {
                req = op.type === 'del' ? store.delete(key) : store.put(op.value, key);
            } catch (err) {
                error = err;
                transaction.abort();
                return;
            }
            if (index < operations.length) req.onsuccess = loop;
        }
        loop();
    }
    return new Promise((resolve, reject)=>{
        const it = db.iterator();
        const id = (data)=>data
        ;
        it._deserializeKey = it._deserializeValue = id;
        next();
        function next() {
            const handleNext = (err, key, value)=>{
                if (err || key === undefined) {
                    const handleEnd = (err2)=>{
                        if (err2) {
                            reject(err2);
                            return;
                        }
                        resolve();
                    };
                    it.end(handleEnd);
                    return;
                }
                batch(fn(key, value), next);
            };
            it.next(handleNext);
        }
    });
}
exports.migration = migration;

},{"../../src/utils.js":"kjXDZ","uint8arrays/from-string":"lo45E","uint8arrays/to-string":"g3mCQ"}],"kjXDZ":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var key1 = require('interface-datastore/key');
var errors = require('datastore-core/errors');
const CONFIG_KEY = new key1.Key('/config');
const VERSION_KEY = new key1.Key('/version');
function findLevelJs(store) {
    let db = store;
    while(db.db || db.child){
        db = db.db || db.child;
        if (db.type === 'level-js' || db.constructor.name === 'Level') return db;
    }
}
async function hasWithFallback(key, has, store) {
    const result = await has(key);
    if (result) return result;
    const levelJs = findLevelJs(store);
    if (!levelJs) return false;
    return new Promise((resolve, reject)=>{
        const req = levelJs.store('readonly').get(key.toString());
        req.transaction.onabort = ()=>{
            reject(req.transaction.error);
        };
        req.transaction.oncomplete = ()=>{
            resolve(Boolean(req.result));
        };
    });
}
async function getWithFallback(key, get, has, store) {
    if (await has(key)) return get(key);
    const levelJs = findLevelJs(store);
    if (!levelJs) throw errors.notFoundError();
    return new Promise((resolve, reject)=>{
        const req = levelJs.store('readonly').get(key.toString());
        req.transaction.onabort = ()=>{
            reject(req.transaction.error);
        };
        req.transaction.oncomplete = ()=>{
            if (req.result) return resolve(req.result);
            reject(errors.notFoundError());
        };
    });
}
function wrapStore(store) {
    const originalGet = store.get.bind(store);
    const originalHas = store.has.bind(store);
    store.get = (key)=>getWithFallback(key, originalGet, originalHas, store)
    ;
    store.has = (key)=>hasWithFallback(key, originalHas, store)
    ;
    return store;
}
function wrapBackends(backends) {
    return {
        ...backends,
        root: wrapStore(backends.root),
        datastore: wrapStore(backends.datastore),
        pins: wrapStore(backends.pins),
        keys: wrapStore(backends.keys)
    };
}
exports.CONFIG_KEY = CONFIG_KEY;
exports.VERSION_KEY = VERSION_KEY;
exports.findLevelJs = findLevelJs;
exports.hasWithFallback = hasWithFallback;
exports.wrapBackends = wrapBackends;

},{"interface-datastore/key":"ccQWS","datastore-core/errors":"hKmom"}],"if5sA":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var key = require('interface-datastore/key');
const MFS_ROOT_KEY = new key.Key('/local/filesroot');
async function storeMfsRootInDatastore(backends, onProgress = ()=>{
}) {
    onProgress(100, 'Migrating MFS root to repo datastore');
    await backends.root.open();
    await backends.datastore.open();
    if (await backends.root.has(MFS_ROOT_KEY)) {
        const root = await backends.root.get(MFS_ROOT_KEY);
        await backends.datastore.put(MFS_ROOT_KEY, root);
        await backends.root.delete(MFS_ROOT_KEY);
    }
    await backends.datastore.close();
    await backends.root.close();
    onProgress(100, 'Stored MFS root in repo datastore');
}
async function storeMfsRootInRoot(backends, onProgress = ()=>{
}) {
    onProgress(100, 'Migrating MFS root to repo root datastore');
    await backends.root.open();
    await backends.datastore.open();
    if (await backends.datastore.has(MFS_ROOT_KEY)) {
        const root = await backends.datastore.get(MFS_ROOT_KEY);
        await backends.root.put(MFS_ROOT_KEY, root);
        await backends.datastore.delete(MFS_ROOT_KEY);
    }
    await backends.datastore.close();
    await backends.root.close();
    onProgress(100, 'Stored MFS root in repo root datastore');
}
const migration = {
    version: 11,
    description: 'Store mfs root in the datastore',
    migrate: storeMfsRootInDatastore,
    revert: storeMfsRootInRoot
};
exports.migration = migration;

},{"interface-datastore/key":"ccQWS"}],"8KYZw":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var init = require('./init.js');
var errors = require('../errors.js');
var utils = require('../utils.js');
var fromString = require('uint8arrays/from-string');
var toString = require('uint8arrays/to-string');
async function getVersion(backends) {
    if (!await init.isRepoInitialized(backends)) throw new errors.NotInitializedRepoError('Repo is not initialized!');
    const store = backends.root;
    await store.open();
    try {
        return parseInt(toString.toString(await store.get(utils.VERSION_KEY)));
    } finally{
        await store.close();
    }
}
async function setVersion(version, backends) {
    if (!backends) throw new errors.MissingRepoOptionsError('Please pass repo options when trying to open a repo');
    const store = backends.root;
    await store.open();
    await store.put(utils.VERSION_KEY, fromString.fromString(String(version)));
    await store.close();
}
exports.getVersion = getVersion;
exports.setVersion = setVersion;

},{"./init.js":"iY56l","../errors.js":"2t05i","../utils.js":"kjXDZ","uint8arrays/from-string":"lo45E","uint8arrays/to-string":"g3mCQ"}],"iY56l":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var debug = require('debug');
var utils = require('../utils.js');
var errors = require('../errors.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
const log = debug__default["default"]('ipfs:repo:migrator:repo:init');
async function isRepoInitialized(backends) {
    if (!backends) throw new errors.MissingRepoOptionsError('Please pass repo options when trying to open a repo');
    const root = backends.root;
    try {
        await root.open();
        const versionCheck = await root.has(utils.VERSION_KEY);
        const configCheck = await root.has(utils.CONFIG_KEY);
        if (!versionCheck || !configCheck) {
            log(`Version entry present: ${versionCheck}`);
            log(`Config entry present: ${configCheck}`);
            return false;
        }
        return true;
    } catch (e) {
        log('While checking if repo is initialized error was thrown: ' + e.message);
        return false;
    } finally{
        if (root !== undefined) try {
            await root.close();
        } catch  {
        }
    }
}
exports.isRepoInitialized = isRepoInitialized;

},{"debug":"lWlU4","../utils.js":"kjXDZ","../errors.js":"2t05i"}],"2t05i":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
class NonReversibleMigrationError extends Error {
    constructor(message){
        super(message);
        this.name = 'NonReversibleMigrationError';
        this.code = NonReversibleMigrationError.code;
        this.message = message;
    }
}
NonReversibleMigrationError.code = 'ERR_NON_REVERSIBLE_MIGRATION';
class NotInitializedRepoError extends Error {
    constructor(message1){
        super(message1);
        this.name = 'NotInitializedRepoError';
        this.code = NotInitializedRepoError.code;
        this.message = message1;
    }
}
NotInitializedRepoError.code = 'ERR_NOT_INITIALIZED_REPO';
class RequiredParameterError extends Error {
    constructor(message2){
        super(message2);
        this.name = 'RequiredParameterError';
        this.code = RequiredParameterError.code;
        this.message = message2;
    }
}
RequiredParameterError.code = 'ERR_REQUIRED_PARAMETER';
class InvalidValueError extends Error {
    constructor(message3){
        super(message3);
        this.name = 'InvalidValueError';
        this.code = InvalidValueError.code;
        this.message = message3;
    }
}
InvalidValueError.code = 'ERR_INVALID_VALUE';
class MissingRepoOptionsError extends Error {
    constructor(message4){
        super(message4);
        this.name = 'MissingRepoOptionsError';
        this.code = MissingRepoOptionsError.code;
        this.message = message4;
    }
}
MissingRepoOptionsError.code = 'ERR_MISSING_REPO_OPTIONS';
exports.InvalidValueError = InvalidValueError;
exports.MissingRepoOptionsError = MissingRepoOptionsError;
exports.NonReversibleMigrationError = NonReversibleMigrationError;
exports.NotInitializedRepoError = NotInitializedRepoError;
exports.RequiredParameterError = RequiredParameterError;

},{}],"eL1Ft":[function(require,module,exports) {
/*!
 * bytes
 * Copyright(c) 2012-2014 TJ Holowaychuk
 * Copyright(c) 2015 Jed Watson
 * MIT Licensed
 */ 'use strict';
/**
 * Module exports.
 * @public
 */ module.exports = bytes;
module.exports.format = format;
module.exports.parse = parse;
/**
 * Module variables.
 * @private
 */ var formatThousandsRegExp = /\B(?=(\d{3})+(?!\d))/g;
var formatDecimalsRegExp = /(?:\.0*|(\.[^0]+)0+)$/;
var map = {
    b: 1,
    kb: 1024,
    mb: 1048576,
    gb: 1073741824,
    tb: Math.pow(1024, 4),
    pb: Math.pow(1024, 5)
};
var parseRegExp = /^((-|\+)?(\d+(?:\.\d+)?)) *(kb|mb|gb|tb|pb)$/i;
/**
 * Convert the given value in bytes into a string or parse to string to an integer in bytes.
 *
 * @param {string|number} value
 * @param {{
 *  case: [string],
 *  decimalPlaces: [number]
 *  fixedDecimals: [boolean]
 *  thousandsSeparator: [string]
 *  unitSeparator: [string]
 *  }} [options] bytes options.
 *
 * @returns {string|number|null}
 */ function bytes(value, options) {
    if (typeof value === 'string') return parse(value);
    if (typeof value === 'number') return format(value, options);
    return null;
}
/**
 * Format the given value in bytes into a string.
 *
 * If the value is negative, it is kept as such. If it is a float,
 * it is rounded.
 *
 * @param {number} value
 * @param {object} [options]
 * @param {number} [options.decimalPlaces=2]
 * @param {number} [options.fixedDecimals=false]
 * @param {string} [options.thousandsSeparator=]
 * @param {string} [options.unit=]
 * @param {string} [options.unitSeparator=]
 *
 * @returns {string|null}
 * @public
 */ function format(value, options) {
    if (!Number.isFinite(value)) return null;
    var mag = Math.abs(value);
    var thousandsSeparator = options && options.thousandsSeparator || '';
    var unitSeparator = options && options.unitSeparator || '';
    var decimalPlaces = options && options.decimalPlaces !== undefined ? options.decimalPlaces : 2;
    var fixedDecimals = Boolean(options && options.fixedDecimals);
    var unit = options && options.unit || '';
    if (!unit || !map[unit.toLowerCase()]) {
        if (mag >= map.pb) unit = 'PB';
        else if (mag >= map.tb) unit = 'TB';
        else if (mag >= map.gb) unit = 'GB';
        else if (mag >= map.mb) unit = 'MB';
        else if (mag >= map.kb) unit = 'KB';
        else unit = 'B';
    }
    var val = value / map[unit.toLowerCase()];
    var str = val.toFixed(decimalPlaces);
    if (!fixedDecimals) str = str.replace(formatDecimalsRegExp, '$1');
    if (thousandsSeparator) str = str.split('.').map(function(s, i) {
        return i === 0 ? s.replace(formatThousandsRegExp, thousandsSeparator) : s;
    }).join('.');
    return str + unitSeparator + unit;
}
/**
 * Parse the string value into an integer in bytes.
 *
 * If no unit is given, it is assumed the value is in bytes.
 *
 * @param {number|string} val
 *
 * @returns {number|null}
 * @public
 */ function parse(val) {
    if (typeof val === 'number' && !isNaN(val)) return val;
    if (typeof val !== 'string') return null;
    // Test if the string passed is valid
    var results = parseRegExp.exec(val);
    var floatValue;
    var unit = 'b';
    if (!results) {
        // Nothing could be extracted from the given string
        floatValue = parseInt(val, 10);
        unit = 'b';
    } else {
        // Retrieve the value and the unit
        floatValue = parseFloat(results[1]);
        unit = results[4].toLowerCase();
    }
    return Math.floor(map[unit] * floatValue);
}

},{}],"kkcrh":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var key = require('interface-datastore/key');
var debug = require('debug');
var toString = require('uint8arrays/to-string');
var fromString = require('uint8arrays/from-string');
var level = require('./utils/level.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
const log = debug__default["default"]('ipfs:repo:version');
const versionKey = new key.Key('version');
function version1(store) {
    return {
        async exists () {
            return level.hasWithFallback(versionKey, store.has.bind(store), store);
        },
        async get () {
            const buf = await level.getWithFallback(versionKey, store.get.bind(store), store.has.bind(store), store);
            return parseInt(toString.toString(buf), 10);
        },
        set (version) {
            return store.put(versionKey, fromString.fromString(String(version)));
        },
        async check (expected) {
            const version = await this.get();
            log('comparing version: %s and %s', version, expected);
            const compatibleVersion = version === 6 && expected === 7 || expected === 6 && version === 7;
            return version === expected || compatibleVersion;
        }
    };
}
exports.version = version1;

},{"interface-datastore/key":"ccQWS","debug":"lWlU4","uint8arrays/to-string":"g3mCQ","uint8arrays/from-string":"lo45E","./utils/level.js":"hcEOJ"}],"hcEOJ":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var errors = require('../errors.js');
async function hasWithFallback(key, has, store) {
    const result = await has(key);
    if (result) return result;
    const levelJs = findLevelJs(store);
    if (!levelJs) return false;
    return new Promise((resolve, reject)=>{
        const req = levelJs.store('readonly').get(key.toString());
        req.transaction.onabort = ()=>{
            reject(req.transaction.error);
        };
        req.transaction.oncomplete = ()=>{
            resolve(Boolean(req.result));
        };
    });
}
async function getWithFallback(key, get, has, store) {
    if (await has(key)) return get(key);
    const levelJs = findLevelJs(store);
    if (!levelJs) throw new errors.NotFoundError();
    return new Promise((resolve, reject)=>{
        const req = levelJs.store('readonly').get(key.toString());
        req.transaction.onabort = ()=>{
            reject(req.transaction.error);
        };
        req.transaction.oncomplete = ()=>{
            if (req.result) return resolve(req.result);
            reject(new errors.NotFoundError());
        };
    });
}
function findLevelJs(store) {
    let db = store;
    while(db.db || db.child){
        db = db.db || db.child;
        if (db.type === 'level-js' || db.constructor.name === 'Level') return db;
    }
}
exports.getWithFallback = getWithFallback;
exports.hasWithFallback = hasWithFallback;

},{"../errors.js":"7UmNp"}],"7UmNp":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
class LockExistsError extends Error {
    constructor(message){
        super(message);
        this.name = 'LockExistsError';
        this.code = LockExistsError.code;
    }
}
LockExistsError.code = 'ERR_LOCK_EXISTS';
class NotFoundError extends Error {
    constructor(message1){
        super(message1);
        this.name = 'NotFoundError';
        this.code = NotFoundError.code;
    }
}
NotFoundError.code = 'ERR_NOT_FOUND';
class InvalidRepoVersionError extends Error {
    constructor(message2){
        super(message2);
        this.name = 'InvalidRepoVersionError';
        this.code = InvalidRepoVersionError.code;
    }
}
InvalidRepoVersionError.code = 'ERR_INVALID_REPO_VERSION';
const ERR_REPO_NOT_INITIALIZED = 'ERR_REPO_NOT_INITIALIZED';
const ERR_REPO_ALREADY_OPEN = 'ERR_REPO_ALREADY_OPEN';
const ERR_REPO_ALREADY_CLOSED = 'ERR_REPO_ALREADY_CLOSED';
exports.ERR_REPO_ALREADY_CLOSED = ERR_REPO_ALREADY_CLOSED;
exports.ERR_REPO_ALREADY_OPEN = ERR_REPO_ALREADY_OPEN;
exports.ERR_REPO_NOT_INITIALIZED = ERR_REPO_NOT_INITIALIZED;
exports.InvalidRepoVersionError = InvalidRepoVersionError;
exports.LockExistsError = LockExistsError;
exports.NotFoundError = NotFoundError;

},{}],"37tgW":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var key1 = require('interface-datastore/key');
var PQueue = require('p-queue');
var _get = require('just-safe-get');
var _set = require('just-safe-set');
var errCode = require('err-code');
var errors = require('./errors.js');
var toString = require('uint8arrays/to-string');
var fromString = require('uint8arrays/from-string');
var level = require('./utils/level.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var PQueue__default = /*#__PURE__*/ _interopDefaultLegacy(PQueue);
var _get__default = /*#__PURE__*/ _interopDefaultLegacy(_get);
var _set__default = /*#__PURE__*/ _interopDefaultLegacy(_set);
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
const Queue = PQueue__default["default"].default ? PQueue__default["default"].default : PQueue__default["default"];
const configKey = new key1.Key('config');
function config1(store) {
    const setQueue = new Queue({
        concurrency: 1
    });
    const configStore = {
        async getAll (options = {
        }) {
            const encodedValue = await level.getWithFallback(configKey, store.get.bind(store), store.has.bind(store), store);
            return JSON.parse(toString.toString(encodedValue));
        },
        async get (key, options = {
        }) {
            if (key == null) throw new errors.NotFoundError(`Key ${key} does not exist in config`);
            const config = await this.getAll(options);
            const value = _get__default["default"](config, key);
            if (value === undefined) throw new errors.NotFoundError(`Key ${key} does not exist in config`);
            return value;
        },
        set (key, value, options = {
        }) {
            if (typeof key !== 'string' && !(key instanceof String)) throw errCode__default["default"](new Error('Invalid key type: ' + typeof key), 'ERR_INVALID_KEY');
            if (value === undefined || value instanceof Uint8Array) throw errCode__default["default"](new Error('Invalid value type: ' + typeof value), 'ERR_INVALID_VALUE');
            return setQueue.add(()=>_maybeDoSet({
                    key: key,
                    value: value
                }, options.signal)
            );
        },
        replace (value, options = {
        }) {
            if (!value || value instanceof Uint8Array) throw errCode__default["default"](new Error('Invalid value type: ' + typeof value), 'ERR_INVALID_VALUE');
            return setQueue.add(()=>_maybeDoSet({
                    key: undefined,
                    value: value
                }, options.signal)
            );
        },
        async exists () {
            return level.hasWithFallback(configKey, store.has.bind(store), store);
        }
    };
    async function _maybeDoSet(m, signal) {
        if (signal && signal.aborted) {
            return;
        }
        const key = m.key;
        const value = m.value;
        if (key) {
            const config = await configStore.getAll();
            if (typeof config === 'object' && config !== null) {
                _set__default["default"](config, key, value);
            }
            return _saveAll(config);
        }
        return _saveAll(value);
    }
    function _saveAll(config) {
        const buf = fromString.fromString(JSON.stringify(config, null, 2));
        return store.put(configKey, buf);
    }
    return configStore;
}
exports.config = config1;

},{"interface-datastore/key":"ccQWS","p-queue":"ccCVf","just-safe-get":"2nGd3","just-safe-set":"c9js5","err-code":"eQvyh","./errors.js":"7UmNp","uint8arrays/to-string":"g3mCQ","uint8arrays/from-string":"lo45E","./utils/level.js":"hcEOJ"}],"5G4sj":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var interfaceDatastore = require('interface-datastore');
var sortKeys = require('sort-keys');
var toString = require('uint8arrays/to-string');
var fromString = require('uint8arrays/from-string');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var sortKeys__default = /*#__PURE__*/ _interopDefaultLegacy(sortKeys);
const specKey = new interfaceDatastore.Key('datastore_spec');
function spec1(store) {
    return {
        exists () {
            return store.has(specKey);
        },
        async get () {
            const buf = await store.get(specKey);
            return JSON.parse(toString.toString(buf));
        },
        async set (spec) {
            return store.put(specKey, fromString.fromString(JSON.stringify(sortKeys__default["default"](spec, {
                deep: true
            }))));
        }
    };
}
exports.spec = spec1;

},{"interface-datastore":"9B36y","sort-keys":"8HtX2","uint8arrays/to-string":"g3mCQ","uint8arrays/from-string":"lo45E"}],"8HtX2":[function(require,module,exports) {
'use strict';
const isPlainObject = require('is-plain-obj');
module.exports = (object1, options = {
})=>{
    if (!isPlainObject(object1) && !Array.isArray(object1)) throw new TypeError('Expected a plain object or array');
    const { deep  } = options;
    const seenInput = [];
    const seenOutput = [];
    const deepSortArray = (array)=>{
        const seenIndex = seenInput.indexOf(array);
        if (seenIndex !== -1) return seenOutput[seenIndex];
        const result = [];
        seenInput.push(array);
        seenOutput.push(result);
        result.push(...array.map((item)=>{
            if (Array.isArray(item)) return deepSortArray(item);
            if (isPlainObject(item)) return sortKeys(item);
            return item;
        }));
        return result;
    };
    const sortKeys = (object)=>{
        const seenIndex = seenInput.indexOf(object);
        if (seenIndex !== -1) return seenOutput[seenIndex];
        const result = {
        };
        const keys = Object.keys(object).sort(options.compare);
        seenInput.push(object);
        seenOutput.push(result);
        for (const key of keys){
            const value = object[key];
            let newValue;
            if (deep && Array.isArray(value)) newValue = deepSortArray(value);
            else newValue = deep && isPlainObject(value) ? sortKeys(value) : value;
            Object.defineProperty(result, key, {
                ...Object.getOwnPropertyDescriptor(object, key),
                value: newValue
            });
        }
        return result;
    };
    if (Array.isArray(object1)) return deep ? deepSortArray(object1) : object1.slice();
    return sortKeys(object1);
};

},{"is-plain-obj":"96KLh"}],"hF0IH":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var key = require('interface-datastore/key');
var fromString = require('uint8arrays/from-string');
const apiFile = new key.Key('api');
function apiAddr(store) {
    return {
        async get () {
            const value = await store.get(apiFile);
            return value && value.toString();
        },
        set (value) {
            return store.put(apiFile, fromString.fromString(value.toString()));
        },
        delete () {
            return store.delete(apiFile);
        }
    };
}
exports.apiAddr = apiAddr;

},{"interface-datastore/key":"ccQWS","uint8arrays/from-string":"lo45E"}],"7sykp":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var filter = require('it-filter');
var pushable = require('it-pushable');
var drain = require('it-drain');
var cid1 = require('multiformats/cid');
var errCode = require('err-code');
var identity = require('multiformats/hashes/identity');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var filter__default = /*#__PURE__*/ _interopDefaultLegacy(filter);
var pushable__default = /*#__PURE__*/ _interopDefaultLegacy(pushable);
var drain__default = /*#__PURE__*/ _interopDefaultLegacy(drain);
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
function createIdStore(store) {
    return {
        open () {
            return store.open();
        },
        close () {
            return store.close();
        },
        query (query, options) {
            return store.query(query, options);
        },
        queryKeys (query, options) {
            return store.queryKeys(query, options);
        },
        async get (cid, options) {
            const extracted = extractContents(cid);
            if (extracted.isIdentity) return Promise.resolve(extracted.digest);
            return store.get(cid, options);
        },
        async *getMany (cids, options) {
            for await (const cid of cids)yield this.get(cid, options);
        },
        async put (cid, buf, options) {
            const { isIdentity  } = extractContents(cid);
            if (isIdentity) return;
            await store.put(cid, buf, options);
        },
        async *putMany (pairs, options) {
            const output = pushable__default["default"]();
            const runner = globalThis.process && globalThis.process.nextTick ? globalThis.process.nextTick : globalThis.setImmediate || globalThis.setTimeout;
            runner(async ()=>{
                try {
                    await drain__default["default"](store.putMany(async function*() {
                        for await (const { key , value  } of pairs){
                            if (!extractContents(key).isIdentity) yield {
                                key,
                                value
                            };
                            output.push({
                                key,
                                value
                            });
                        }
                    }()));
                    output.end();
                } catch (err) {
                    output.end(err);
                }
            });
            yield* output;
        },
        has (cid, options) {
            const { isIdentity  } = extractContents(cid);
            if (isIdentity) return Promise.resolve(true);
            return store.has(cid, options);
        },
        delete (cid, options) {
            const { isIdentity  } = extractContents(cid);
            if (isIdentity) return Promise.resolve();
            return store.delete(cid, options);
        },
        deleteMany (cids, options) {
            return store.deleteMany(filter__default["default"](cids, (cid)=>!extractContents(cid).isIdentity
            ), options);
        },
        batch () {
            const batch = store.batch();
            return {
                put (cid, buf) {
                    const { isIdentity  } = extractContents(cid);
                    if (isIdentity) return;
                    batch.put(cid, buf);
                },
                delete (cid) {
                    const { isIdentity  } = extractContents(cid);
                    if (isIdentity) return;
                    batch.delete(cid);
                },
                commit: (options)=>{
                    return batch.commit(options);
                }
            };
        }
    };
}
function extractContents(k) {
    const cid$1 = cid1.CID.asCID(k);
    if (cid$1 == null) throw errCode__default["default"](new Error('Not a valid cid'), 'ERR_INVALID_CID');
    if (cid$1.multihash.code !== identity.identity.code) return {
        isIdentity: false
    };
    return {
        isIdentity: true,
        digest: cid$1.multihash.digest
    };
}
exports.createIdStore = createIdStore;

},{"it-filter":"7NtwB","it-pushable":"hRi4l","it-drain":"h63K2","multiformats/cid":"fJJnW","err-code":"eQvyh","multiformats/hashes/identity":"7Cndu"}],"hkFtx":[function(require,module,exports) {
'use strict';
var memory = require('./locks/memory.js');
var defaultOptions = {
    autoMigrate: true,
    onMigrationProgress: ()=>{
    },
    repoOwner: true,
    repoLock: memory.MemoryLock
};
module.exports = defaultOptions;

},{"./locks/memory.js":"g28e0"}],"g28e0":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var errors = require('../errors.js');
var debug = require('debug');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
const log = debug__default["default"]('ipfs:repo:lock:memory');
const lockFile = 'repo.lock';
const LOCKS = {
};
async function lock(dir) {
    const file = dir + '/' + lockFile;
    log('locking %s', file);
    if (LOCKS[file] === true) throw new errors.LockExistsError(`Lock already being held for file: ${file}`);
    LOCKS[file] = true;
    const closer = {
        async close () {
            if (LOCKS[file]) delete LOCKS[file];
        }
    };
    return closer;
}
async function locked(dir) {
    const file = dir + '/' + lockFile;
    log(`checking lock: ${file}`);
    return Boolean(LOCKS[file]);
}
const MemoryLock = {
    lock,
    locked
};
exports.MemoryLock = MemoryLock;

},{"../errors.js":"7UmNp","debug":"lWlU4"}],"cPM4s":[function(require,module,exports) {
'use strict';
var defaultDatastore = {
    Spec: {
        type: 'mount',
        mounts: [
            {
                mountpoint: '/blocks',
                type: 'measure',
                prefix: 'flatfs.datastore',
                child: {
                    type: 'flatfs',
                    path: 'blocks',
                    sync: true,
                    shardFunc: '/repo/flatfs/shard/v1/next-to-last/2'
                }
            },
            {
                mountpoint: '/',
                type: 'measure',
                prefix: 'leveldb.datastore',
                child: {
                    type: 'levelds',
                    path: 'datastore',
                    compression: 'none'
                }
            }
        ]
    }
};
module.exports = defaultDatastore;

},{}],"2sfAy":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid6 = require('multiformats/cid');
var errCode = require('err-code');
var debug = require('debug');
var first = require('it-first');
var block = require('multiformats/block');
var cborg = require('cborg');
var dagPb = require('@ipld/dag-pb');
var blockstore = require('./utils/blockstore.js');
var walkDag = require('./utils/walk-dag.js');
var pinTypes = require('./pin-types.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n["default"] = e;
    return Object.freeze(n);
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
var first__default = /*#__PURE__*/ _interopDefaultLegacy(first);
var cborg__namespace = /*#__PURE__*/ _interopNamespace(cborg);
var dagPb__namespace = /*#__PURE__*/ _interopNamespace(dagPb);
function invalidPinTypeErr(type) {
    const errMsg = `Invalid type '${type}', must be one of {direct, indirect, recursive, all}`;
    return errCode__default["default"](new Error(errMsg), 'ERR_INVALID_PIN_TYPE');
}
class PinManager {
    constructor({ pinstore , blockstore: blockstore1 , loadCodec  }){
        this.pinstore = pinstore;
        this.blockstore = blockstore1;
        this.loadCodec = loadCodec;
        this.log = debug__default["default"]('ipfs:repo:pin');
        this.directPins = new Set();
        this.recursivePins = new Set();
    }
    async pinDirectly(cid1, options8 = {
    }) {
        await this.blockstore.get(cid1, options8);
        const pin = {
            depth: 0
        };
        if (cid1.version !== 0) pin.version = cid1.version;
        if (cid1.code !== dagPb__namespace.code) pin.codec = cid1.code;
        if (options8.metadata) pin.metadata = options8.metadata;
        return this.pinstore.put(blockstore.cidToKey(cid1), cborg__namespace.encode(pin));
    }
    unpin(cid2, options1) {
        return this.pinstore.delete(blockstore.cidToKey(cid2), options1);
    }
    async pinRecursively(cid3, options2 = {
    }) {
        await this.fetchCompleteDag(cid3, options2);
        const pin = {
            depth: Infinity
        };
        if (cid3.version !== 0) pin.version = cid3.version;
        if (cid3.code !== dagPb__namespace.code) pin.codec = cid3.code;
        if (options2.metadata) pin.metadata = options2.metadata;
        await this.pinstore.put(blockstore.cidToKey(cid3), cborg__namespace.encode(pin));
    }
    async *directKeys(options3) {
        for await (const entry1 of this.pinstore.query({
            filters: [
                (entry)=>{
                    const pin = cborg__namespace.decode(entry.value);
                    return pin.depth === 0;
                }
            ]
        })){
            const pin = cborg__namespace.decode(entry1.value);
            const version = pin.version || 0;
            const codec = pin.codec != null ? pin.codec : dagPb__namespace.code;
            const multihash = blockstore.keyToMultihash(entry1.key);
            yield {
                cid: cid6.CID.create(version, codec, multihash),
                metadata: pin.metadata
            };
        }
    }
    async *recursiveKeys(options4) {
        for await (const entry2 of this.pinstore.query({
            filters: [
                (entry)=>{
                    const pin = cborg__namespace.decode(entry.value);
                    return pin.depth === Infinity;
                }
            ]
        })){
            const pin = cborg__namespace.decode(entry2.value);
            const version = pin.version || 0;
            const codec = pin.codec != null ? pin.codec : dagPb__namespace.code;
            const multihash = blockstore.keyToMultihash(entry2.key);
            yield {
                cid: cid6.CID.create(version, codec, multihash),
                metadata: pin.metadata
            };
        }
    }
    async *indirectKeys(options5) {
        for await (const { cid  } of this.recursiveKeys())for await (const childCid of walkDag.walkDag(cid, this.blockstore, this.loadCodec, options5)){
            const types = [
                pinTypes.PinTypes.recursive
            ];
            const result = await this.isPinnedWithType(childCid, types);
            if (result.pinned) continue;
            yield childCid;
        }
    }
    async isPinnedWithType(cid4, types, options6) {
        if (!Array.isArray(types)) types = [
            types
        ];
        const all = types.includes(pinTypes.PinTypes.all);
        const direct = types.includes(pinTypes.PinTypes.direct);
        const recursive = types.includes(pinTypes.PinTypes.recursive);
        const indirect = types.includes(pinTypes.PinTypes.indirect);
        if (recursive || direct || all) {
            const result = await first__default["default"](this.pinstore.query({
                prefix: blockstore.cidToKey(cid4).toString(),
                filters: [
                    (entry)=>{
                        if (all) return true;
                        const pin = cborg__namespace.decode(entry.value);
                        return types.includes(pin.depth === 0 ? pinTypes.PinTypes.direct : pinTypes.PinTypes.recursive);
                    }
                ],
                limit: 1
            }));
            if (result) {
                const pin = cborg__namespace.decode(result.value);
                return {
                    cid: cid4,
                    pinned: true,
                    reason: pin.depth === 0 ? pinTypes.PinTypes.direct : pinTypes.PinTypes.recursive,
                    metadata: pin.metadata
                };
            }
        }
        const self = this;
        async function* findChild(key, source) {
            for await (const { cid: parentCid  } of source){
                for await (const childCid of walkDag.walkDag(parentCid, self.blockstore, self.loadCodec))if (childCid.equals(key)) {
                    yield parentCid;
                    return;
                }
            }
        }
        if (all || indirect) {
            const parentCid = await first__default["default"](findChild(cid4, this.recursiveKeys()));
            if (parentCid) return {
                cid: cid4,
                pinned: true,
                reason: pinTypes.PinTypes.indirect,
                parent: parentCid
            };
        }
        return {
            cid: cid4,
            pinned: false
        };
    }
    async fetchCompleteDag(cid5, options7) {
        const seen = new Set();
        const walkDag = async (cid, options)=>{
            if (seen.has(cid.toString())) return;
            seen.add(cid.toString());
            const bytes = await this.blockstore.get(cid, options);
            const codec = await this.loadCodec(cid.code);
            const block$1 = block.createUnsafe({
                bytes,
                cid,
                codec
            });
            await Promise.all([
                ...block$1.links()
            ].map(([, childCid])=>walkDag(childCid, options)
            ));
        };
        await walkDag(cid5, options7);
    }
    static checkPinType(type) {
        if (typeof type !== 'string' || !Object.keys(pinTypes.PinTypes).includes(type)) throw invalidPinTypeErr(type);
        return true;
    }
}
exports.PinManager = PinManager;

},{"multiformats/cid":"fJJnW","err-code":"eQvyh","debug":"lWlU4","it-first":"imIGO","multiformats/block":"8J6Pf","cborg":"6ZYxo","@ipld/dag-pb":"e9gy2","./utils/blockstore.js":"fg2fQ","./utils/walk-dag.js":"7akgu","./pin-types.js":"5TeDb"}],"fg2fQ":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var key1 = require('interface-datastore/key');
var multiformats = require('multiformats');
var raw = require('multiformats/codecs/raw');
var errCode = require('err-code');
var base32 = require('multiformats/bases/base32');
var Digest = require('multiformats/hashes/digest');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n["default"] = e;
    return Object.freeze(n);
}
var raw__namespace = /*#__PURE__*/ _interopNamespace(raw);
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
var Digest__namespace = /*#__PURE__*/ _interopNamespace(Digest);
function cidToKey(c) {
    const cid = multiformats.CID.asCID(c);
    if (cid == null) throw errCode__default["default"](new Error('Not a valid cid'), 'ERR_INVALID_CID');
    const encoded = base32.base32.encode(cid.multihash.bytes);
    return new key1.Key('/' + encoded.slice(1).toUpperCase(), false);
}
function keyToCid(key) {
    return multiformats.CID.createV1(raw__namespace.code, keyToMultihash(key));
}
function keyToMultihash(key) {
    return Digest__namespace.decode(base32.base32.decode(`b${key.toString().toLowerCase().substring(1)}`));
}
exports.cidToKey = cidToKey;
exports.keyToCid = keyToCid;
exports.keyToMultihash = keyToMultihash;

},{"interface-datastore/key":"ccQWS","multiformats":"8T5ng","multiformats/codecs/raw":"dkcyY","err-code":"eQvyh","multiformats/bases/base32":"63xDB","multiformats/hashes/digest":"fkA58"}],"7akgu":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var debug = require('debug');
var block = require('multiformats/block');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
const log = debug__default["default"]('ipfs:repo:utils:walk-dag');
async function* walkDag(cid, blockstore, loadCodec, options) {
    try {
        const bytes = await blockstore.get(cid, options);
        const codec = await loadCodec(cid.code);
        const block$1 = block.createUnsafe({
            bytes,
            cid,
            codec
        });
        for (const [, childCid] of block$1.links()){
            yield childCid;
            yield* walkDag(childCid, blockstore, loadCodec, options);
        }
    } catch (err) {
        log('Could not walk DAG for CID', cid.toString(), err);
        throw err;
    }
}
exports.walkDag = walkDag;

},{"debug":"lWlU4","multiformats/block":"8J6Pf"}],"hwoye":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var map = require('it-map');
var errCode = require('err-code');
var pinTypes = require('./pin-types.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var map__default = /*#__PURE__*/ _interopDefaultLegacy(map);
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
function createPinnedBlockstore(pins, store) {
    return {
        open () {
            return store.open();
        },
        close () {
            return store.close();
        },
        query (query, options) {
            return store.query(query, options);
        },
        queryKeys (query, options) {
            return store.queryKeys(query, options);
        },
        async get (cid, options) {
            return store.get(cid, options);
        },
        async *getMany (cids, options) {
            yield* store.getMany(cids, options);
        },
        async put (cid, buf, options) {
            await store.put(cid, buf, options);
        },
        async *putMany (pairs, options) {
            yield* store.putMany(pairs, options);
        },
        has (cid, options) {
            return store.has(cid, options);
        },
        async delete (cid, options) {
            await ensureNotPinned(cid, pins);
            return store.delete(cid, options);
        },
        deleteMany (cids, options) {
            return store.deleteMany(map__default["default"](cids, async (cid)=>{
                await ensureNotPinned(cid, pins);
                return cid;
            }), options);
        },
        batch () {
            return store.batch();
        }
    };
}
async function ensureNotPinned(cid, pins) {
    const { pinned , reason  } = await pins.isPinnedWithType(cid, pinTypes.PinTypes.all);
    if (pinned) throw errCode__default["default"](new Error(`pinned: ${reason}`), 'ERR_BLOCK_PINNED');
}
exports.createPinnedBlockstore = createPinnedBlockstore;

},{"it-map":"dOmp3","err-code":"eQvyh","./pin-types.js":"5TeDb"}],"iIDzf":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid2 = require('multiformats/cid');
var debug = require('debug');
var errors = require('datastore-core/errors');
var parallelBatch = require('it-parallel-batch');
var itPipe = require('it-pipe');
var merge = require('it-merge');
var map = require('it-map');
var filter = require('it-filter');
var key = require('interface-datastore/key');
var base32 = require('multiformats/bases/base32');
var walkDag = require('./utils/walk-dag.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
var parallelBatch__default = /*#__PURE__*/ _interopDefaultLegacy(parallelBatch);
var merge__default = /*#__PURE__*/ _interopDefaultLegacy(merge);
var map__default = /*#__PURE__*/ _interopDefaultLegacy(map);
var filter__default = /*#__PURE__*/ _interopDefaultLegacy(filter);
const log = debug__default["default"]('ipfs:repo:gc');
const ERR_NOT_FOUND = errors.notFoundError().code;
const BLOCK_RM_CONCURRENCY = 256;
const MFS_ROOT_KEY = new key.Key('/local/filesroot');
function gc1({ gcLock , pins , blockstore , root , loadCodec  }) {
    async function* gc() {
        const start = Date.now();
        log('Creating set of marked blocks');
        const release = await gcLock.writeLock();
        try {
            const markedSet = await createMarkedSet({
                pins,
                blockstore,
                root,
                loadCodec
            });
            const blockKeys = blockstore.queryKeys({
            });
            yield* deleteUnmarkedBlocks({
                blockstore
            }, markedSet, blockKeys);
            log(`Complete (${Date.now() - start}ms)`);
        } finally{
            release();
        }
    }
    return gc;
}
async function createMarkedSet({ pins , blockstore , loadCodec , root  }) {
    const mfsSource = async function*() {
        let mh;
        try {
            mh = await root.get(MFS_ROOT_KEY);
        } catch (err) {
            if (err.code === ERR_NOT_FOUND) {
                log('No blocks in MFS');
                return;
            }
            throw err;
        }
        const rootCid = cid2.CID.decode(mh);
        yield rootCid;
        yield* walkDag.walkDag(rootCid, blockstore, loadCodec);
    }();
    const pinsSource = merge__default["default"](map__default["default"](pins.recursiveKeys(), ({ cid  })=>cid
    ), pins.indirectKeys(), map__default["default"](pins.directKeys(), ({ cid  })=>cid
    ), mfsSource);
    const output = new Set();
    for await (const cid1 of merge__default["default"](pinsSource, mfsSource))output.add(base32.base32.encode(cid1.multihash.bytes));
    return output;
}
async function* deleteUnmarkedBlocks({ blockstore  }, markedSet, blockKeys) {
    let blocksCount = 0;
    let removedBlocksCount = 0;
    const removeBlock = async (cid)=>{
        return async function remove() {
            blocksCount++;
            try {
                const b32 = base32.base32.encode(cid.multihash.bytes);
                if (markedSet.has(b32)) return null;
                try {
                    await blockstore.delete(cid);
                    removedBlocksCount++;
                } catch (err) {
                    return {
                        err: new Error(`Could not delete block with CID ${cid}: ${err.message}`)
                    };
                }
                return {
                    cid
                };
            } catch (err) {
                const msg = `Could delete block with CID ${cid}`;
                log(msg, err);
                return {
                    err: new Error(msg + `: ${err.message}`)
                };
            }
        };
    };
    yield* itPipe.pipe(parallelBatch__default["default"](map__default["default"](blockKeys, removeBlock), BLOCK_RM_CONCURRENCY), (source)=>filter__default["default"](source, Boolean)
    );
    log(`Marked set has ${markedSet.size} unique blocks. Blockstore has ${blocksCount} blocks. ` + `Deleted ${removedBlocksCount} blocks.`);
}
exports.gc = gc1;

},{"multiformats/cid":"fJJnW","debug":"lWlU4","datastore-core/errors":"hKmom","it-parallel-batch":"4B5jX","it-pipe":"4jukm","it-merge":"7iKAo","it-map":"dOmp3","it-filter":"7NtwB","interface-datastore/key":"ccQWS","multiformats/bases/base32":"63xDB","./utils/walk-dag.js":"7akgu"}],"8iLmT":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var interfaceDatastore = require('interface-datastore');
var datastoreCore = require('datastore-core');
var filter = require('it-filter');
var map = require('it-map');
var take = require('it-take');
var sort = require('it-sort');
var Level = require('level');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var filter__default = /*#__PURE__*/ _interopDefaultLegacy(filter);
var map__default = /*#__PURE__*/ _interopDefaultLegacy(map);
var take__default = /*#__PURE__*/ _interopDefaultLegacy(take);
var sort__default = /*#__PURE__*/ _interopDefaultLegacy(sort);
var Level__default = /*#__PURE__*/ _interopDefaultLegacy(Level);
class LevelDatastore extends datastoreCore.BaseDatastore {
    constructor(path, opts){
        super();
        this.path = path;
        this.opts = opts;
        if (opts && opts.db) {
            this.database = opts.db;
            delete opts.db;
        } else this.database = Level__default['default'];
    }
    _initDb() {
        return new Promise((resolve, reject)=>{
            this.db = this.database(this.path, {
                ...this.opts,
                valueEncoding: 'binary',
                compression: false
            }, (err)=>{
                if (err) return reject(err);
                resolve(this.db);
            });
        });
    }
    async open() {
        try {
            if (this.db) await this.db.open();
            else this.db = await this._initDb();
        } catch (err) {
            throw datastoreCore.Errors.dbOpenFailedError(err);
        }
    }
    async put(key4, value1) {
        try {
            await this.db.put(key4.toString(), value1);
        } catch (err) {
            throw datastoreCore.Errors.dbWriteFailedError(err);
        }
    }
    async get(key1) {
        let data;
        try {
            data = await this.db.get(key1.toString());
        } catch (err) {
            if (err.notFound) throw datastoreCore.Errors.notFoundError(err);
            throw datastoreCore.Errors.dbWriteFailedError(err);
        }
        return data;
    }
    async has(key2) {
        try {
            await this.db.get(key2.toString());
        } catch (err) {
            if (err.notFound) return false;
            throw err;
        }
        return true;
    }
    async delete(key3) {
        try {
            await this.db.del(key3.toString());
        } catch (err) {
            throw datastoreCore.Errors.dbDeleteFailedError(err);
        }
    }
    close() {
        return this.db && this.db.close();
    }
    batch() {
        const ops = [];
        return {
            put: (key, value)=>{
                ops.push({
                    type: 'put',
                    key: key.toString(),
                    value: value
                });
            },
            delete: (key)=>{
                ops.push({
                    type: 'del',
                    key: key.toString()
                });
            },
            commit: ()=>{
                return this.db.batch(ops);
            }
        };
    }
    query(q) {
        let it1 = this._query({
            values: true,
            prefix: q.prefix
        });
        if (Array.isArray(q.filters)) it1 = q.filters.reduce((it, f)=>filter__default['default'](it, f)
        , it1);
        if (Array.isArray(q.orders)) it1 = q.orders.reduce((it, f)=>sort__default['default'](it, f)
        , it1);
        const { offset , limit  } = q;
        if (offset) {
            let i = 0;
            it1 = filter__default['default'](it1, ()=>(i++) >= offset
            );
        }
        if (limit) it1 = take__default['default'](it1, limit);
        return it1;
    }
    queryKeys(q1) {
        let it2 = map__default['default'](this._query({
            values: false,
            prefix: q1.prefix
        }), ({ key  })=>key
        );
        if (Array.isArray(q1.filters)) it2 = q1.filters.reduce((it, f)=>filter__default['default'](it, f)
        , it2);
        if (Array.isArray(q1.orders)) it2 = q1.orders.reduce((it, f)=>sort__default['default'](it, f)
        , it2);
        const { offset , limit  } = q1;
        if (offset) {
            let i = 0;
            it2 = filter__default['default'](it2, ()=>(i++) >= offset
            );
        }
        if (limit) it2 = take__default['default'](it2, limit);
        return it2;
    }
    _query(opts1) {
        const iteratorOpts = {
            keys: true,
            keyAsBuffer: true,
            values: opts1.values
        };
        if (opts1.prefix != null) {
            const prefix = opts1.prefix.toString();
            iteratorOpts.gte = prefix;
            iteratorOpts.lt = prefix + 'ÿ';
        }
        return levelIteratorToIterator(this.db.iterator(iteratorOpts));
    }
}
function levelIteratorToIterator(li) {
    return {
        [Symbol.asyncIterator] () {
            return {
                next: ()=>new Promise((resolve, reject)=>{
                        li.next((err1, key, value)=>{
                            if (err1) return reject(err1);
                            if (key == null) return li.end((err)=>{
                                if (err) return reject(err);
                                resolve({
                                    done: true,
                                    value: undefined
                                });
                            });
                            resolve({
                                done: false,
                                value: {
                                    key: new interfaceDatastore.Key(key, false),
                                    value
                                }
                            });
                        });
                    })
                ,
                return: ()=>new Promise((resolve, reject)=>{
                        li.end((err)=>{
                            if (err) return reject(err);
                            resolve({
                                done: true,
                                value: undefined
                            });
                        });
                    })
            };
        }
    };
}
exports.LevelDatastore = LevelDatastore;

},{"interface-datastore":"9B36y","datastore-core":"8BFN9","it-filter":"7NtwB","it-map":"dOmp3","it-take":"8hPk7","it-sort":"5bOcw","level":"4L5MH"}],"5bOcw":[function(require,module,exports) {
'use strict';
const all = require('it-all');
/**
 * Collects all values from an async iterator, sorts them
 * using the passed function and yields them
 *
 * @template T
 * @param {AsyncIterable<T> | Iterable<T>} source
 * @param {(a: T, b: T) => -1 | 0 | 1} sorter
 */ const sort = async function*(source, sorter) {
    const arr = await all(source);
    yield* arr.sort(sorter);
};
module.exports = sort;

},{"it-all":"hynpN"}],"4L5MH":[function(require,module,exports) {
module.exports = require('level-packager')(require('level-js'));

},{"level-packager":"25ixL","level-js":"klBIM"}],"25ixL":[function(require,module,exports) {
'use strict';
const levelup = require('levelup');
const encode = require('encoding-down');
function packager(leveldown) {
    function Level(location, options, callback) {
        if (typeof location === 'function') callback = location;
        else if (typeof options === 'function') callback = options;
        if (!isObject(options)) options = isObject(location) ? location : {
        };
        return levelup(encode(leveldown(location, options), options), options, callback);
    }
    function isObject(o) {
        return typeof o === 'object' && o !== null;
    }
    for (const m of [
        'destroy',
        'repair'
    ])if (typeof leveldown[m] === 'function') Level[m] = function(...args) {
        leveldown[m](...args);
    };
    Level.errors = levelup.errors;
    return Level;
}
module.exports = packager;

},{"levelup":"81yFL","encoding-down":"6MJSj"}],"81yFL":[function(require,module,exports) {
'use strict';
const EventEmitter = require('events').EventEmitter;
const inherits = require('util').inherits;
const DeferredLevelDOWN = require('deferred-leveldown');
const IteratorStream = require('level-iterator-stream');
const Batch = require('./batch');
const errors = require('level-errors');
const supports = require('level-supports');
const catering = require('catering');
const getCallback = require('./common').getCallback;
const getOptions = require('./common').getOptions;
// TODO: after we drop node 10, also use queueMicrotask() in node
const nextTick = require('./next-tick');
const WriteError = errors.WriteError;
const ReadError = errors.ReadError;
const NotFoundError = errors.NotFoundError;
const OpenError = errors.OpenError;
const InitializationError = errors.InitializationError;
function LevelUP(db, options, callback) {
    if (!(this instanceof LevelUP)) return new LevelUP(db, options, callback);
    let error;
    EventEmitter.call(this);
    this.setMaxListeners(Infinity);
    if (typeof options === 'function') {
        callback = options;
        options = {
        };
    }
    options = options || {
    };
    if (!db || typeof db !== 'object') {
        error = new InitializationError('First argument must be an abstract-leveldown compliant store');
        if (typeof callback === 'function') return nextTick(callback, error);
        throw error;
    }
    if (typeof db.status !== 'string') throw new Error('.status required, old abstract-leveldown');
    this.options = getOptions(options);
    this._db = db;
    this.db = null;
    this.open(callback || ((err)=>{
        if (err) this.emit('error', err);
    }));
    // Create manifest based on deferred-leveldown's
    this.supports = supports(this.db.supports, {
        status: true,
        deferredOpen: true,
        openCallback: true,
        promises: true,
        streams: true
    });
    // Experimental: enrich levelup interface
    for (const method of Object.keys(this.supports.additionalMethods)){
        if (this[method] != null) continue;
        // Don't do this.db[method].bind() because this.db is dynamic.
        this[method] = function(...args) {
            return this.db[method](...args);
        };
    }
}
LevelUP.prototype.emit = EventEmitter.prototype.emit;
LevelUP.prototype.once = EventEmitter.prototype.once;
inherits(LevelUP, EventEmitter);
// TODO: tests
Object.defineProperty(LevelUP.prototype, 'status', {
    enumerable: true,
    get () {
        return this.db.status;
    }
});
// TODO: tests
LevelUP.prototype.isOperational = function() {
    return this.db.status === 'open' || this.db.status === 'opening';
};
LevelUP.prototype.open = function(opts, callback) {
    if (typeof opts === 'function') {
        callback = opts;
        opts = null;
    }
    callback = catering.fromCallback(callback);
    if (!opts) opts = this.options;
    // 1) Don't check db.status until levelup has opened,
    // in order for levelup events to be consistent
    if (this.db && this.isOpen()) {
        nextTick(callback, null, this);
        return callback.promise;
    }
    if (this.db && this._isOpening()) {
        this.once('open', ()=>{
            callback(null, this);
        });
        return callback.promise;
    }
    // 2) Instead let deferred-leveldown handle already-open cases.
    // TODO: ideally though, levelup would have its own status
    this.db = new DeferredLevelDOWN(this._db);
    this.emit('opening');
    this.db.open(opts, (err)=>{
        if (err) return callback(new OpenError(err));
        this.db = this._db;
        callback(null, this);
        this.emit('open');
        this.emit('ready');
    });
    return callback.promise;
};
LevelUP.prototype.close = function(callback) {
    callback = catering.fromCallback(callback);
    if (this.isOpen()) {
        this.db.close((err, ...rest)=>{
            this.emit('closed');
            callback(err, ...rest);
        });
        this.emit('closing');
    } else if (this.isClosed()) nextTick(callback);
    else if (this.db.status === 'closing') this.once('closed', callback);
    else if (this._isOpening()) this.once('open', ()=>{
        this.close(callback);
    });
    return callback.promise;
};
// TODO: remove in future major
LevelUP.prototype.isOpen = function() {
    return this.db.status === 'open';
};
// TODO: remove in future major
LevelUP.prototype._isOpening = function() {
    return this.db.status === 'opening';
};
// TODO: remove in future major
LevelUP.prototype.isClosed = function() {
    return /^clos|new/.test(this.db.status);
};
LevelUP.prototype.get = function(key, options, callback) {
    callback = getCallback(options, callback);
    callback = catering.fromCallback(callback);
    if (maybeError(this, callback)) return callback.promise;
    options = getOptions(options);
    this.db.get(key, options, function(err, value) {
        if (err) {
            if (/notfound/i.test(err) || err.notFound) err = new NotFoundError('Key not found in database [' + key + ']', err);
            else err = new ReadError(err);
            return callback(err);
        }
        callback(null, value);
    });
    return callback.promise;
};
LevelUP.prototype.getMany = function(keys, options, callback) {
    return this.db.getMany(keys, options, callback);
};
LevelUP.prototype.put = function(key, value, options, callback) {
    callback = getCallback(options, callback);
    callback = catering.fromCallback(callback);
    if (maybeError(this, callback)) return callback.promise;
    options = getOptions(options);
    this.db.put(key, value, options, (err)=>{
        if (err) return callback(new WriteError(err));
        this.emit('put', key, value);
        callback();
    });
    return callback.promise;
};
LevelUP.prototype.del = function(key, options, callback) {
    callback = getCallback(options, callback);
    callback = catering.fromCallback(callback);
    if (maybeError(this, callback)) return callback.promise;
    options = getOptions(options);
    this.db.del(key, options, (err)=>{
        if (err) return callback(new WriteError(err));
        this.emit('del', key);
        callback();
    });
    return callback.promise;
};
LevelUP.prototype.batch = function(arr, options, callback) {
    if (!arguments.length) return new Batch(this);
    if (typeof arr === 'function') callback = arr;
    else callback = getCallback(options, callback);
    callback = catering.fromCallback(callback);
    if (maybeError(this, callback)) return callback.promise;
    options = getOptions(options);
    this.db.batch(arr, options, (err)=>{
        if (err) return callback(new WriteError(err));
        this.emit('batch', arr);
        callback();
    });
    return callback.promise;
};
LevelUP.prototype.iterator = function(options) {
    return this.db.iterator(options);
};
LevelUP.prototype.clear = function(options, callback) {
    callback = getCallback(options, callback);
    options = getOptions(options);
    callback = catering.fromCallback(callback);
    if (maybeError(this, callback)) return callback.promise;
    this.db.clear(options, (err)=>{
        if (err) return callback(new WriteError(err));
        this.emit('clear', options);
        callback();
    });
    return callback.promise;
};
LevelUP.prototype.readStream = LevelUP.prototype.createReadStream = function(options) {
    options = Object.assign({
        keys: true,
        values: true
    }, options);
    if (typeof options.limit !== 'number') options.limit = -1;
    return new IteratorStream(this.db.iterator(options), options);
};
LevelUP.prototype.keyStream = LevelUP.prototype.createKeyStream = function(options) {
    return this.createReadStream(Object.assign({
    }, options, {
        keys: true,
        values: false
    }));
};
LevelUP.prototype.valueStream = LevelUP.prototype.createValueStream = function(options) {
    return this.createReadStream(Object.assign({
    }, options, {
        keys: false,
        values: true
    }));
};
LevelUP.prototype.toString = function() {
    return 'LevelUP';
};
LevelUP.prototype.type = 'levelup';
// Expose nextTick for API parity with abstract-leveldown
LevelUP.prototype._nextTick = nextTick;
function maybeError(db, callback) {
    if (!db.isOperational()) {
        nextTick(callback, new ReadError('Database is not open'));
        return true;
    }
    return false;
}
LevelUP.errors = errors;
module.exports = LevelUP;

},{"events":"bHM3D","util":"fZQoa","deferred-leveldown":"emkVv","level-iterator-stream":"sfkOa","./batch":"8xgxr","level-errors":"jUsAO","level-supports":"1scZb","catering":"hpV8E","./common":"3vVgQ","./next-tick":"63Tpw"}],"fZQoa":[function(require,module,exports) {
var process = require("process");
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var getOwnPropertyDescriptors = Object.getOwnPropertyDescriptors || function getOwnPropertyDescriptors(obj) {
    var keys = Object.keys(obj);
    var descriptors = {
    };
    for(var i = 0; i < keys.length; i++)descriptors[keys[i]] = Object.getOwnPropertyDescriptor(obj, keys[i]);
    return descriptors;
};
var formatRegExp = /%[sdj%]/g;
exports.format = function(f) {
    if (!isString(f)) {
        var objects = [];
        for(var i = 0; i < arguments.length; i++)objects.push(inspect(arguments[i]));
        return objects.join(' ');
    }
    var i = 1;
    var args = arguments;
    var len = args.length;
    var str = String(f).replace(formatRegExp, function(x) {
        if (x === '%%') return '%';
        if (i >= len) return x;
        switch(x){
            case '%s':
                return String(args[i++]);
            case '%d':
                return Number(args[i++]);
            case '%j':
                try {
                    return JSON.stringify(args[i++]);
                } catch (_) {
                    return '[Circular]';
                }
            default:
                return x;
        }
    });
    for(var x1 = args[i]; i < len; x1 = args[++i])if (isNull(x1) || !isObject(x1)) str += ' ' + x1;
    else str += ' ' + inspect(x1);
    return str;
};
// Mark that a method should not be used.
// Returns a modified function which warns once by default.
// If --no-deprecation is set, then it is a no-op.
exports.deprecate = function(fn, msg) {
    if (typeof process !== 'undefined' && process.noDeprecation === true) return fn;
    // Allow for deprecating things in the process of starting up.
    if (typeof process === 'undefined') return function() {
        return exports.deprecate(fn, msg).apply(this, arguments);
    };
    var warned = false;
    function deprecated() {
        if (!warned) {
            if (process.throwDeprecation) throw new Error(msg);
            else if (process.traceDeprecation) console.trace(msg);
            else console.error(msg);
            warned = true;
        }
        return fn.apply(this, arguments);
    }
    return deprecated;
};
var debugs = {
};
var debugEnvRegex = /^$/;
var debugEnv;
exports.debuglog = function(set) {
    set = set.toUpperCase();
    if (!debugs[set]) {
        if (debugEnvRegex.test(set)) {
            var pid = process.pid;
            debugs[set] = function() {
                var msg = exports.format.apply(exports, arguments);
                console.error('%s %d: %s', set, pid, msg);
            };
        } else debugs[set] = function() {
        };
    }
    return debugs[set];
};
/**
 * Echos the value of a value. Trys to print the value out
 * in the best way possible given the different types.
 *
 * @param {Object} obj The object to print out.
 * @param {Object} opts Optional options object that alters the output.
 */ /* legacy: obj, showHidden, depth, colors*/ function inspect(obj, opts) {
    // default options
    var ctx = {
        seen: [],
        stylize: stylizeNoColor
    };
    // legacy...
    if (arguments.length >= 3) ctx.depth = arguments[2];
    if (arguments.length >= 4) ctx.colors = arguments[3];
    if (isBoolean(opts)) // legacy...
    ctx.showHidden = opts;
    else if (opts) // got an "options" object
    exports._extend(ctx, opts);
    // set default options
    if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
    if (isUndefined(ctx.depth)) ctx.depth = 2;
    if (isUndefined(ctx.colors)) ctx.colors = false;
    if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
    if (ctx.colors) ctx.stylize = stylizeWithColor;
    return formatValue(ctx, obj, ctx.depth);
}
exports.inspect = inspect;
// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
inspect.colors = {
    'bold': [
        1,
        22
    ],
    'italic': [
        3,
        23
    ],
    'underline': [
        4,
        24
    ],
    'inverse': [
        7,
        27
    ],
    'white': [
        37,
        39
    ],
    'grey': [
        90,
        39
    ],
    'black': [
        30,
        39
    ],
    'blue': [
        34,
        39
    ],
    'cyan': [
        36,
        39
    ],
    'green': [
        32,
        39
    ],
    'magenta': [
        35,
        39
    ],
    'red': [
        31,
        39
    ],
    'yellow': [
        33,
        39
    ]
};
// Don't use 'blue' not visible on cmd.exe
inspect.styles = {
    'special': 'cyan',
    'number': 'yellow',
    'boolean': 'yellow',
    'undefined': 'grey',
    'null': 'bold',
    'string': 'green',
    'date': 'magenta',
    // "name": intentionally not styling
    'regexp': 'red'
};
function stylizeWithColor(str, styleType) {
    var style = inspect.styles[styleType];
    if (style) return '\u001b[' + inspect.colors[style][0] + 'm' + str + '\u001b[' + inspect.colors[style][1] + 'm';
    else return str;
}
function stylizeNoColor(str, styleType) {
    return str;
}
function arrayToHash(array) {
    var hash = {
    };
    array.forEach(function(val, idx) {
        hash[val] = true;
    });
    return hash;
}
function formatValue(ctx, value, recurseTimes) {
    // Provide a hook for user-specified inspect functions.
    // Check that value is an object with an inspect function on it
    if (ctx.customInspect && value && isFunction(value.inspect) && // Filter out the util module, it's inspect function is special
    value.inspect !== exports.inspect && // Also filter out any prototype objects using the circular check.
    !(value.constructor && value.constructor.prototype === value)) {
        var ret = value.inspect(recurseTimes, ctx);
        if (!isString(ret)) ret = formatValue(ctx, ret, recurseTimes);
        return ret;
    }
    // Primitive types cannot have properties
    var primitive = formatPrimitive(ctx, value);
    if (primitive) return primitive;
    // Look up the keys of the object.
    var keys = Object.keys(value);
    var visibleKeys = arrayToHash(keys);
    if (ctx.showHidden) keys = Object.getOwnPropertyNames(value);
    // IE doesn't make error fields non-enumerable
    // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
    if (isError(value) && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) return formatError(value);
    // Some type of object without properties can be shortcutted.
    if (keys.length === 0) {
        if (isFunction(value)) {
            var name = value.name ? ': ' + value.name : '';
            return ctx.stylize('[Function' + name + ']', 'special');
        }
        if (isRegExp(value)) return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
        if (isDate(value)) return ctx.stylize(Date.prototype.toString.call(value), 'date');
        if (isError(value)) return formatError(value);
    }
    var base = '', array = false, braces = [
        '{',
        '}'
    ];
    // Make Array say that they are Array
    if (isArray(value)) {
        array = true;
        braces = [
            '[',
            ']'
        ];
    }
    // Make functions say that they are functions
    if (isFunction(value)) {
        var n = value.name ? ': ' + value.name : '';
        base = ' [Function' + n + ']';
    }
    // Make RegExps say that they are RegExps
    if (isRegExp(value)) base = ' ' + RegExp.prototype.toString.call(value);
    // Make dates with properties first say the date
    if (isDate(value)) base = ' ' + Date.prototype.toUTCString.call(value);
    // Make error with message first say the error
    if (isError(value)) base = ' ' + formatError(value);
    if (keys.length === 0 && (!array || value.length == 0)) return braces[0] + base + braces[1];
    if (recurseTimes < 0) {
        if (isRegExp(value)) return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
        else return ctx.stylize('[Object]', 'special');
    }
    ctx.seen.push(value);
    var output;
    if (array) output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
    else output = keys.map(function(key) {
        return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
    });
    ctx.seen.pop();
    return reduceToSingleString(output, base, braces);
}
function formatPrimitive(ctx, value) {
    if (isUndefined(value)) return ctx.stylize('undefined', 'undefined');
    if (isString(value)) {
        var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '').replace(/'/g, "\\'").replace(/\\"/g, '"') + '\'';
        return ctx.stylize(simple, 'string');
    }
    if (isNumber(value)) return ctx.stylize('' + value, 'number');
    if (isBoolean(value)) return ctx.stylize('' + value, 'boolean');
    // For some reason typeof null is "object", so special case here.
    if (isNull(value)) return ctx.stylize('null', 'null');
}
function formatError(value) {
    return '[' + Error.prototype.toString.call(value) + ']';
}
function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
    var output = [];
    for(var i = 0, l = value.length; i < l; ++i)if (hasOwnProperty(value, String(i))) output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, String(i), true));
    else output.push('');
    keys.forEach(function(key) {
        if (!key.match(/^\d+$/)) output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, key, true));
    });
    return output;
}
function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
    var name, str, desc;
    desc = Object.getOwnPropertyDescriptor(value, key) || {
        value: value[key]
    };
    if (desc.get) {
        if (desc.set) str = ctx.stylize('[Getter/Setter]', 'special');
        else str = ctx.stylize('[Getter]', 'special');
    } else if (desc.set) str = ctx.stylize('[Setter]', 'special');
    if (!hasOwnProperty(visibleKeys, key)) name = '[' + key + ']';
    if (!str) {
        if (ctx.seen.indexOf(desc.value) < 0) {
            if (isNull(recurseTimes)) str = formatValue(ctx, desc.value, null);
            else str = formatValue(ctx, desc.value, recurseTimes - 1);
            if (str.indexOf('\n') > -1) {
                if (array) str = str.split('\n').map(function(line) {
                    return '  ' + line;
                }).join('\n').substr(2);
                else str = '\n' + str.split('\n').map(function(line) {
                    return '   ' + line;
                }).join('\n');
            }
        } else str = ctx.stylize('[Circular]', 'special');
    }
    if (isUndefined(name)) {
        if (array && key.match(/^\d+$/)) return str;
        name = JSON.stringify('' + key);
        if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
            name = name.substr(1, name.length - 2);
            name = ctx.stylize(name, 'name');
        } else {
            name = name.replace(/'/g, "\\'").replace(/\\"/g, '"').replace(/(^"|"$)/g, "'");
            name = ctx.stylize(name, 'string');
        }
    }
    return name + ': ' + str;
}
function reduceToSingleString(output, base, braces) {
    var numLinesEst = 0;
    var length = output.reduce(function(prev, cur) {
        numLinesEst++;
        if (cur.indexOf('\n') >= 0) numLinesEst++;
        return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
    }, 0);
    if (length > 60) return braces[0] + (base === '' ? '' : base + '\n ') + ' ' + output.join(',\n  ') + ' ' + braces[1];
    return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
}
// NOTE: These type checking functions intentionally don't use `instanceof`
// because it is fragile and can be easily faked with `Object.create()`.
exports.types = require('./support/types');
function isArray(ar) {
    return Array.isArray(ar);
}
exports.isArray = isArray;
function isBoolean(arg) {
    return typeof arg === 'boolean';
}
exports.isBoolean = isBoolean;
function isNull(arg) {
    return arg === null;
}
exports.isNull = isNull;
function isNullOrUndefined(arg) {
    return arg == null;
}
exports.isNullOrUndefined = isNullOrUndefined;
function isNumber(arg) {
    return typeof arg === 'number';
}
exports.isNumber = isNumber;
function isString(arg) {
    return typeof arg === 'string';
}
exports.isString = isString;
function isSymbol(arg) {
    return typeof arg === 'symbol';
}
exports.isSymbol = isSymbol;
function isUndefined(arg) {
    return arg === void 0;
}
exports.isUndefined = isUndefined;
function isRegExp(re) {
    return isObject(re) && objectToString(re) === '[object RegExp]';
}
exports.isRegExp = isRegExp;
exports.types.isRegExp = isRegExp;
function isObject(arg) {
    return typeof arg === 'object' && arg !== null;
}
exports.isObject = isObject;
function isDate(d) {
    return isObject(d) && objectToString(d) === '[object Date]';
}
exports.isDate = isDate;
exports.types.isDate = isDate;
function isError(e) {
    return isObject(e) && (objectToString(e) === '[object Error]' || e instanceof Error);
}
exports.isError = isError;
exports.types.isNativeError = isError;
function isFunction(arg) {
    return typeof arg === 'function';
}
exports.isFunction = isFunction;
function isPrimitive(arg) {
    return arg === null || typeof arg === 'boolean' || typeof arg === 'number' || typeof arg === 'string' || typeof arg === 'symbol' || typeof arg === 'undefined';
}
exports.isPrimitive = isPrimitive;
exports.isBuffer = require('./support/isBuffer');
function objectToString(o) {
    return Object.prototype.toString.call(o);
}
function pad(n) {
    return n < 10 ? '0' + n.toString(10) : n.toString(10);
}
var months = [
    'Jan',
    'Feb',
    'Mar',
    'Apr',
    'May',
    'Jun',
    'Jul',
    'Aug',
    'Sep',
    'Oct',
    'Nov',
    'Dec'
];
// 26 Feb 16:19:34
function timestamp() {
    var d = new Date();
    var time = [
        pad(d.getHours()),
        pad(d.getMinutes()),
        pad(d.getSeconds())
    ].join(':');
    return [
        d.getDate(),
        months[d.getMonth()],
        time
    ].join(' ');
}
// log is just a thin wrapper to console.log that prepends a timestamp
exports.log = function() {
    console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
};
/**
 * Inherit the prototype methods from one constructor into another.
 *
 * The Function.prototype.inherits from lang.js rewritten as a standalone
 * function (not on Function.prototype). NOTE: If this file is to be loaded
 * during bootstrapping this function needs to be rewritten using some native
 * functions as prototype setup using normal JavaScript does not work as
 * expected during bootstrapping (see mirror.js in r114903).
 *
 * @param {function} ctor Constructor function which needs to inherit the
 *     prototype.
 * @param {function} superCtor Constructor function to inherit prototype from.
 */ exports.inherits = require('inherits');
exports._extend = function(origin, add) {
    // Don't do anything if add isn't an object
    if (!add || !isObject(add)) return origin;
    var keys = Object.keys(add);
    var i = keys.length;
    while(i--)origin[keys[i]] = add[keys[i]];
    return origin;
};
function hasOwnProperty(obj, prop) {
    return Object.prototype.hasOwnProperty.call(obj, prop);
}
var kCustomPromisifiedSymbol = typeof Symbol !== 'undefined' ? Symbol('util.promisify.custom') : undefined;
exports.promisify = function promisify(original) {
    if (typeof original !== 'function') throw new TypeError('The "original" argument must be of type Function');
    if (kCustomPromisifiedSymbol && original[kCustomPromisifiedSymbol]) {
        var fn = original[kCustomPromisifiedSymbol];
        if (typeof fn !== 'function') throw new TypeError('The "util.promisify.custom" argument must be of type Function');
        Object.defineProperty(fn, kCustomPromisifiedSymbol, {
            value: fn,
            enumerable: false,
            writable: false,
            configurable: true
        });
        return fn;
    }
    function fn() {
        var promiseResolve, promiseReject;
        var promise = new Promise(function(resolve, reject) {
            promiseResolve = resolve;
            promiseReject = reject;
        });
        var args = [];
        for(var i = 0; i < arguments.length; i++)args.push(arguments[i]);
        args.push(function(err, value) {
            if (err) promiseReject(err);
            else promiseResolve(value);
        });
        try {
            original.apply(this, args);
        } catch (err) {
            promiseReject(err);
        }
        return promise;
    }
    Object.setPrototypeOf(fn, Object.getPrototypeOf(original));
    if (kCustomPromisifiedSymbol) Object.defineProperty(fn, kCustomPromisifiedSymbol, {
        value: fn,
        enumerable: false,
        writable: false,
        configurable: true
    });
    return Object.defineProperties(fn, getOwnPropertyDescriptors(original));
};
exports.promisify.custom = kCustomPromisifiedSymbol;
function callbackifyOnRejected(reason, cb) {
    // `!reason` guard inspired by bluebird (Ref: https://goo.gl/t5IS6M).
    // Because `null` is a special error value in callbacks which means "no error
    // occurred", we error-wrap so the callback consumer can distinguish between
    // "the promise rejected with null" or "the promise fulfilled with undefined".
    if (!reason) {
        var newReason = new Error('Promise was rejected with a falsy value');
        newReason.reason = reason;
        reason = newReason;
    }
    return cb(reason);
}
function callbackify(original) {
    if (typeof original !== 'function') throw new TypeError('The "original" argument must be of type Function');
    // We DO NOT return the promise as it gives the user a false sense that
    // the promise is actually somehow related to the callback's execution
    // and that the callback throwing will reject the promise.
    function callbackified() {
        var args = [];
        for(var i = 0; i < arguments.length; i++)args.push(arguments[i]);
        var maybeCb = args.pop();
        if (typeof maybeCb !== 'function') throw new TypeError('The last argument must be of type Function');
        var self = this;
        var cb = function() {
            return maybeCb.apply(self, arguments);
        };
        // In true node style we process the callback on `nextTick` with all the
        // implications (stack, `uncaughtException`, `async_hooks`)
        original.apply(this, args).then(function(ret) {
            process.nextTick(cb.bind(null, null, ret));
        }, function(rej) {
            process.nextTick(callbackifyOnRejected.bind(null, rej, cb));
        });
    }
    Object.setPrototypeOf(callbackified, Object.getPrototypeOf(original));
    Object.defineProperties(callbackified, getOwnPropertyDescriptors(original));
    return callbackified;
}
exports.callbackify = callbackify;

},{"process":"lDnB8","./support/types":"9tAOj","./support/isBuffer":"k1wGR","inherits":"d3hL2"}],"9tAOj":[function(require,module,exports) {
// Currently in sync with Node.js lib/internal/util/types.js
// https://github.com/nodejs/node/commit/112cc7c27551254aa2b17098fb774867f05ed0d9
'use strict';
var isArgumentsObject = require('is-arguments');
var isGeneratorFunction = require('is-generator-function');
var whichTypedArray = require('which-typed-array');
var isTypedArray = require('is-typed-array');
function uncurryThis(f) {
    return f.call.bind(f);
}
var BigIntSupported = typeof BigInt !== 'undefined';
var SymbolSupported = typeof Symbol !== 'undefined';
var ObjectToString = uncurryThis(Object.prototype.toString);
var numberValue = uncurryThis(Number.prototype.valueOf);
var stringValue = uncurryThis(String.prototype.valueOf);
var booleanValue = uncurryThis(Boolean.prototype.valueOf);
if (BigIntSupported) var bigIntValue = uncurryThis(BigInt.prototype.valueOf);
if (SymbolSupported) var symbolValue = uncurryThis(Symbol.prototype.valueOf);
function checkBoxedPrimitive(value, prototypeValueOf) {
    if (typeof value !== 'object') return false;
    try {
        prototypeValueOf(value);
        return true;
    } catch (e) {
        return false;
    }
}
exports.isArgumentsObject = isArgumentsObject;
exports.isGeneratorFunction = isGeneratorFunction;
exports.isTypedArray = isTypedArray;
// Taken from here and modified for better browser support
// https://github.com/sindresorhus/p-is-promise/blob/cda35a513bda03f977ad5cde3a079d237e82d7ef/index.js
function isPromise(input) {
    return typeof Promise !== 'undefined' && input instanceof Promise || input !== null && typeof input === 'object' && typeof input.then === 'function' && typeof input.catch === 'function';
}
exports.isPromise = isPromise;
function isArrayBufferView(value) {
    if (typeof ArrayBuffer !== 'undefined' && ArrayBuffer.isView) return ArrayBuffer.isView(value);
    return isTypedArray(value) || isDataView(value);
}
exports.isArrayBufferView = isArrayBufferView;
function isUint8Array(value) {
    return whichTypedArray(value) === 'Uint8Array';
}
exports.isUint8Array = isUint8Array;
function isUint8ClampedArray(value) {
    return whichTypedArray(value) === 'Uint8ClampedArray';
}
exports.isUint8ClampedArray = isUint8ClampedArray;
function isUint16Array(value) {
    return whichTypedArray(value) === 'Uint16Array';
}
exports.isUint16Array = isUint16Array;
function isUint32Array(value) {
    return whichTypedArray(value) === 'Uint32Array';
}
exports.isUint32Array = isUint32Array;
function isInt8Array(value) {
    return whichTypedArray(value) === 'Int8Array';
}
exports.isInt8Array = isInt8Array;
function isInt16Array(value) {
    return whichTypedArray(value) === 'Int16Array';
}
exports.isInt16Array = isInt16Array;
function isInt32Array(value) {
    return whichTypedArray(value) === 'Int32Array';
}
exports.isInt32Array = isInt32Array;
function isFloat32Array(value) {
    return whichTypedArray(value) === 'Float32Array';
}
exports.isFloat32Array = isFloat32Array;
function isFloat64Array(value) {
    return whichTypedArray(value) === 'Float64Array';
}
exports.isFloat64Array = isFloat64Array;
function isBigInt64Array(value) {
    return whichTypedArray(value) === 'BigInt64Array';
}
exports.isBigInt64Array = isBigInt64Array;
function isBigUint64Array(value) {
    return whichTypedArray(value) === 'BigUint64Array';
}
exports.isBigUint64Array = isBigUint64Array;
function isMapToString(value) {
    return ObjectToString(value) === '[object Map]';
}
isMapToString.working = typeof Map !== 'undefined' && isMapToString(new Map());
function isMap(value) {
    if (typeof Map === 'undefined') return false;
    return isMapToString.working ? isMapToString(value) : value instanceof Map;
}
exports.isMap = isMap;
function isSetToString(value) {
    return ObjectToString(value) === '[object Set]';
}
isSetToString.working = typeof Set !== 'undefined' && isSetToString(new Set());
function isSet(value) {
    if (typeof Set === 'undefined') return false;
    return isSetToString.working ? isSetToString(value) : value instanceof Set;
}
exports.isSet = isSet;
function isWeakMapToString(value) {
    return ObjectToString(value) === '[object WeakMap]';
}
isWeakMapToString.working = typeof WeakMap !== 'undefined' && isWeakMapToString(new WeakMap());
function isWeakMap(value) {
    if (typeof WeakMap === 'undefined') return false;
    return isWeakMapToString.working ? isWeakMapToString(value) : value instanceof WeakMap;
}
exports.isWeakMap = isWeakMap;
function isWeakSetToString(value) {
    return ObjectToString(value) === '[object WeakSet]';
}
isWeakSetToString.working = typeof WeakSet !== 'undefined' && isWeakSetToString(new WeakSet());
function isWeakSet(value) {
    return isWeakSetToString(value);
}
exports.isWeakSet = isWeakSet;
function isArrayBufferToString(value) {
    return ObjectToString(value) === '[object ArrayBuffer]';
}
isArrayBufferToString.working = typeof ArrayBuffer !== 'undefined' && isArrayBufferToString(new ArrayBuffer());
function isArrayBuffer(value) {
    if (typeof ArrayBuffer === 'undefined') return false;
    return isArrayBufferToString.working ? isArrayBufferToString(value) : value instanceof ArrayBuffer;
}
exports.isArrayBuffer = isArrayBuffer;
function isDataViewToString(value) {
    return ObjectToString(value) === '[object DataView]';
}
isDataViewToString.working = typeof ArrayBuffer !== 'undefined' && typeof DataView !== 'undefined' && isDataViewToString(new DataView(new ArrayBuffer(1), 0, 1));
function isDataView(value) {
    if (typeof DataView === 'undefined') return false;
    return isDataViewToString.working ? isDataViewToString(value) : value instanceof DataView;
}
exports.isDataView = isDataView;
// Store a copy of SharedArrayBuffer in case it's deleted elsewhere
var SharedArrayBufferCopy = typeof SharedArrayBuffer !== 'undefined' ? SharedArrayBuffer : undefined;
function isSharedArrayBufferToString(value) {
    return ObjectToString(value) === '[object SharedArrayBuffer]';
}
function isSharedArrayBuffer(value) {
    if (typeof SharedArrayBufferCopy === 'undefined') return false;
    if (typeof isSharedArrayBufferToString.working === 'undefined') isSharedArrayBufferToString.working = isSharedArrayBufferToString(new SharedArrayBufferCopy());
    return isSharedArrayBufferToString.working ? isSharedArrayBufferToString(value) : value instanceof SharedArrayBufferCopy;
}
exports.isSharedArrayBuffer = isSharedArrayBuffer;
function isAsyncFunction(value) {
    return ObjectToString(value) === '[object AsyncFunction]';
}
exports.isAsyncFunction = isAsyncFunction;
function isMapIterator(value) {
    return ObjectToString(value) === '[object Map Iterator]';
}
exports.isMapIterator = isMapIterator;
function isSetIterator(value) {
    return ObjectToString(value) === '[object Set Iterator]';
}
exports.isSetIterator = isSetIterator;
function isGeneratorObject(value) {
    return ObjectToString(value) === '[object Generator]';
}
exports.isGeneratorObject = isGeneratorObject;
function isWebAssemblyCompiledModule(value) {
    return ObjectToString(value) === '[object WebAssembly.Module]';
}
exports.isWebAssemblyCompiledModule = isWebAssemblyCompiledModule;
function isNumberObject(value) {
    return checkBoxedPrimitive(value, numberValue);
}
exports.isNumberObject = isNumberObject;
function isStringObject(value) {
    return checkBoxedPrimitive(value, stringValue);
}
exports.isStringObject = isStringObject;
function isBooleanObject(value) {
    return checkBoxedPrimitive(value, booleanValue);
}
exports.isBooleanObject = isBooleanObject;
function isBigIntObject(value) {
    return BigIntSupported && checkBoxedPrimitive(value, bigIntValue);
}
exports.isBigIntObject = isBigIntObject;
function isSymbolObject(value) {
    return SymbolSupported && checkBoxedPrimitive(value, symbolValue);
}
exports.isSymbolObject = isSymbolObject;
function isBoxedPrimitive(value) {
    return isNumberObject(value) || isStringObject(value) || isBooleanObject(value) || isBigIntObject(value) || isSymbolObject(value);
}
exports.isBoxedPrimitive = isBoxedPrimitive;
function isAnyArrayBuffer(value) {
    return typeof Uint8Array !== 'undefined' && (isArrayBuffer(value) || isSharedArrayBuffer(value));
}
exports.isAnyArrayBuffer = isAnyArrayBuffer;
[
    'isProxy',
    'isExternal',
    'isModuleNamespaceObject'
].forEach(function(method) {
    Object.defineProperty(exports, method, {
        enumerable: false,
        value: function() {
            throw new Error(method + ' is not supported in userland');
        }
    });
});

},{"is-arguments":"8gHs4","is-generator-function":"kT8Ou","which-typed-array":"iDM4O","is-typed-array":"6c7tM"}],"8gHs4":[function(require,module,exports) {
'use strict';
var hasToStringTag = require('has-tostringtag/shams')();
var callBound = require('call-bind/callBound');
var $toString = callBound('Object.prototype.toString');
var isStandardArguments = function isArguments(value) {
    if (hasToStringTag && value && typeof value === 'object' && Symbol.toStringTag in value) return false;
    return $toString(value) === '[object Arguments]';
};
var isLegacyArguments = function isArguments(value) {
    if (isStandardArguments(value)) return true;
    return value !== null && typeof value === 'object' && typeof value.length === 'number' && value.length >= 0 && $toString(value) !== '[object Array]' && $toString(value.callee) === '[object Function]';
};
var supportsStandardArguments = function() {
    return isStandardArguments(arguments);
}();
isStandardArguments.isLegacyArguments = isLegacyArguments; // for tests
module.exports = supportsStandardArguments ? isStandardArguments : isLegacyArguments;

},{"has-tostringtag/shams":"7aneK","call-bind/callBound":"f0fyo"}],"7aneK":[function(require,module,exports) {
'use strict';
var hasSymbols = require('has-symbols/shams');
module.exports = function hasToStringTagShams() {
    return hasSymbols() && !!Symbol.toStringTag;
};

},{"has-symbols/shams":"lhOu9"}],"lhOu9":[function(require,module,exports) {
'use strict';
/* eslint complexity: [2, 18], max-statements: [2, 33] */ module.exports = function hasSymbols() {
    if (typeof Symbol !== 'function' || typeof Object.getOwnPropertySymbols !== 'function') return false;
    if (typeof Symbol.iterator === 'symbol') return true;
    var obj = {
    };
    var sym = Symbol('test');
    var symObj = Object(sym);
    if (typeof sym === 'string') return false;
    if (Object.prototype.toString.call(sym) !== '[object Symbol]') return false;
    if (Object.prototype.toString.call(symObj) !== '[object Symbol]') return false;
    // temp disabled per https://github.com/ljharb/object.assign/issues/17
    // if (sym instanceof Symbol) { return false; }
    // temp disabled per https://github.com/WebReflection/get-own-property-symbols/issues/4
    // if (!(symObj instanceof Symbol)) { return false; }
    // if (typeof Symbol.prototype.toString !== 'function') { return false; }
    // if (String(sym) !== Symbol.prototype.toString.call(sym)) { return false; }
    var symVal = 42;
    obj[sym] = symVal;
    for(sym in obj)return false;
     // eslint-disable-line no-restricted-syntax, no-unreachable-loop
    if (typeof Object.keys === 'function' && Object.keys(obj).length !== 0) return false;
    if (typeof Object.getOwnPropertyNames === 'function' && Object.getOwnPropertyNames(obj).length !== 0) return false;
    var syms = Object.getOwnPropertySymbols(obj);
    if (syms.length !== 1 || syms[0] !== sym) return false;
    if (!Object.prototype.propertyIsEnumerable.call(obj, sym)) return false;
    if (typeof Object.getOwnPropertyDescriptor === 'function') {
        var descriptor = Object.getOwnPropertyDescriptor(obj, sym);
        if (descriptor.value !== symVal || descriptor.enumerable !== true) return false;
    }
    return true;
};

},{}],"f0fyo":[function(require,module,exports) {
'use strict';
var GetIntrinsic = require('get-intrinsic');
var callBind = require('./');
var $indexOf = callBind(GetIntrinsic('String.prototype.indexOf'));
module.exports = function callBoundIntrinsic(name, allowMissing) {
    var intrinsic = GetIntrinsic(name, !!allowMissing);
    if (typeof intrinsic === 'function' && $indexOf(name, '.prototype.') > -1) return callBind(intrinsic);
    return intrinsic;
};

},{"get-intrinsic":"4hk6k","./":"bPDkM"}],"4hk6k":[function(require,module,exports) {
'use strict';
var undefined;
var $SyntaxError = SyntaxError;
var $Function = Function;
var $TypeError = TypeError;
// eslint-disable-next-line consistent-return
var getEvalledConstructor = function(expressionSyntax) {
    try {
        return $Function('"use strict"; return (' + expressionSyntax + ').constructor;')();
    } catch (e) {
    }
};
var $gOPD = Object.getOwnPropertyDescriptor;
if ($gOPD) try {
    $gOPD({
    }, '');
} catch (e) {
    $gOPD = null; // this is IE 8, which has a broken gOPD
}
var throwTypeError = function() {
    throw new $TypeError();
};
var ThrowTypeError = $gOPD ? function() {
    try {
        // eslint-disable-next-line no-unused-expressions, no-caller, no-restricted-properties
        arguments.callee; // IE 8 does not throw here
        return throwTypeError;
    } catch (calleeThrows) {
        try {
            // IE 8 throws on Object.getOwnPropertyDescriptor(arguments, '')
            return $gOPD(arguments, 'callee').get;
        } catch (gOPDthrows) {
            return throwTypeError;
        }
    }
}() : throwTypeError;
var hasSymbols = require('has-symbols')();
var getProto = Object.getPrototypeOf || function(x) {
    return x.__proto__;
}; // eslint-disable-line no-proto
var needsEval = {
};
var TypedArray = typeof Uint8Array === 'undefined' ? undefined : getProto(Uint8Array);
var INTRINSICS = {
    '%AggregateError%': typeof AggregateError === 'undefined' ? undefined : AggregateError,
    '%Array%': Array,
    '%ArrayBuffer%': typeof ArrayBuffer === 'undefined' ? undefined : ArrayBuffer,
    '%ArrayIteratorPrototype%': hasSymbols ? getProto([][Symbol.iterator]()) : undefined,
    '%AsyncFromSyncIteratorPrototype%': undefined,
    '%AsyncFunction%': needsEval,
    '%AsyncGenerator%': needsEval,
    '%AsyncGeneratorFunction%': needsEval,
    '%AsyncIteratorPrototype%': needsEval,
    '%Atomics%': typeof Atomics === 'undefined' ? undefined : Atomics,
    '%BigInt%': typeof BigInt === 'undefined' ? undefined : BigInt,
    '%Boolean%': Boolean,
    '%DataView%': typeof DataView === 'undefined' ? undefined : DataView,
    '%Date%': Date,
    '%decodeURI%': decodeURI,
    '%decodeURIComponent%': decodeURIComponent,
    '%encodeURI%': encodeURI,
    '%encodeURIComponent%': encodeURIComponent,
    '%Error%': Error,
    '%eval%': eval,
    '%EvalError%': EvalError,
    '%Float32Array%': typeof Float32Array === 'undefined' ? undefined : Float32Array,
    '%Float64Array%': typeof Float64Array === 'undefined' ? undefined : Float64Array,
    '%FinalizationRegistry%': typeof FinalizationRegistry === 'undefined' ? undefined : FinalizationRegistry,
    '%Function%': $Function,
    '%GeneratorFunction%': needsEval,
    '%Int8Array%': typeof Int8Array === 'undefined' ? undefined : Int8Array,
    '%Int16Array%': typeof Int16Array === 'undefined' ? undefined : Int16Array,
    '%Int32Array%': typeof Int32Array === 'undefined' ? undefined : Int32Array,
    '%isFinite%': isFinite,
    '%isNaN%': isNaN,
    '%IteratorPrototype%': hasSymbols ? getProto(getProto([][Symbol.iterator]())) : undefined,
    '%JSON%': typeof JSON === 'object' ? JSON : undefined,
    '%Map%': typeof Map === 'undefined' ? undefined : Map,
    '%MapIteratorPrototype%': typeof Map === 'undefined' || !hasSymbols ? undefined : getProto(new Map()[Symbol.iterator]()),
    '%Math%': Math,
    '%Number%': Number,
    '%Object%': Object,
    '%parseFloat%': parseFloat,
    '%parseInt%': parseInt,
    '%Promise%': typeof Promise === 'undefined' ? undefined : Promise,
    '%Proxy%': typeof Proxy === 'undefined' ? undefined : Proxy,
    '%RangeError%': RangeError,
    '%ReferenceError%': ReferenceError,
    '%Reflect%': typeof Reflect === 'undefined' ? undefined : Reflect,
    '%RegExp%': RegExp,
    '%Set%': typeof Set === 'undefined' ? undefined : Set,
    '%SetIteratorPrototype%': typeof Set === 'undefined' || !hasSymbols ? undefined : getProto(new Set()[Symbol.iterator]()),
    '%SharedArrayBuffer%': typeof SharedArrayBuffer === 'undefined' ? undefined : SharedArrayBuffer,
    '%String%': String,
    '%StringIteratorPrototype%': hasSymbols ? getProto(''[Symbol.iterator]()) : undefined,
    '%Symbol%': hasSymbols ? Symbol : undefined,
    '%SyntaxError%': $SyntaxError,
    '%ThrowTypeError%': ThrowTypeError,
    '%TypedArray%': TypedArray,
    '%TypeError%': $TypeError,
    '%Uint8Array%': typeof Uint8Array === 'undefined' ? undefined : Uint8Array,
    '%Uint8ClampedArray%': typeof Uint8ClampedArray === 'undefined' ? undefined : Uint8ClampedArray,
    '%Uint16Array%': typeof Uint16Array === 'undefined' ? undefined : Uint16Array,
    '%Uint32Array%': typeof Uint32Array === 'undefined' ? undefined : Uint32Array,
    '%URIError%': URIError,
    '%WeakMap%': typeof WeakMap === 'undefined' ? undefined : WeakMap,
    '%WeakRef%': typeof WeakRef === 'undefined' ? undefined : WeakRef,
    '%WeakSet%': typeof WeakSet === 'undefined' ? undefined : WeakSet
};
var doEval1 = function doEval(name) {
    var value;
    if (name === '%AsyncFunction%') value = getEvalledConstructor('async function () {}');
    else if (name === '%GeneratorFunction%') value = getEvalledConstructor('function* () {}');
    else if (name === '%AsyncGeneratorFunction%') value = getEvalledConstructor('async function* () {}');
    else if (name === '%AsyncGenerator%') {
        var fn = doEval('%AsyncGeneratorFunction%');
        if (fn) value = fn.prototype;
    } else if (name === '%AsyncIteratorPrototype%') {
        var gen = doEval('%AsyncGenerator%');
        if (gen) value = getProto(gen.prototype);
    }
    INTRINSICS[name] = value;
    return value;
};
var LEGACY_ALIASES = {
    '%ArrayBufferPrototype%': [
        'ArrayBuffer',
        'prototype'
    ],
    '%ArrayPrototype%': [
        'Array',
        'prototype'
    ],
    '%ArrayProto_entries%': [
        'Array',
        'prototype',
        'entries'
    ],
    '%ArrayProto_forEach%': [
        'Array',
        'prototype',
        'forEach'
    ],
    '%ArrayProto_keys%': [
        'Array',
        'prototype',
        'keys'
    ],
    '%ArrayProto_values%': [
        'Array',
        'prototype',
        'values'
    ],
    '%AsyncFunctionPrototype%': [
        'AsyncFunction',
        'prototype'
    ],
    '%AsyncGenerator%': [
        'AsyncGeneratorFunction',
        'prototype'
    ],
    '%AsyncGeneratorPrototype%': [
        'AsyncGeneratorFunction',
        'prototype',
        'prototype'
    ],
    '%BooleanPrototype%': [
        'Boolean',
        'prototype'
    ],
    '%DataViewPrototype%': [
        'DataView',
        'prototype'
    ],
    '%DatePrototype%': [
        'Date',
        'prototype'
    ],
    '%ErrorPrototype%': [
        'Error',
        'prototype'
    ],
    '%EvalErrorPrototype%': [
        'EvalError',
        'prototype'
    ],
    '%Float32ArrayPrototype%': [
        'Float32Array',
        'prototype'
    ],
    '%Float64ArrayPrototype%': [
        'Float64Array',
        'prototype'
    ],
    '%FunctionPrototype%': [
        'Function',
        'prototype'
    ],
    '%Generator%': [
        'GeneratorFunction',
        'prototype'
    ],
    '%GeneratorPrototype%': [
        'GeneratorFunction',
        'prototype',
        'prototype'
    ],
    '%Int8ArrayPrototype%': [
        'Int8Array',
        'prototype'
    ],
    '%Int16ArrayPrototype%': [
        'Int16Array',
        'prototype'
    ],
    '%Int32ArrayPrototype%': [
        'Int32Array',
        'prototype'
    ],
    '%JSONParse%': [
        'JSON',
        'parse'
    ],
    '%JSONStringify%': [
        'JSON',
        'stringify'
    ],
    '%MapPrototype%': [
        'Map',
        'prototype'
    ],
    '%NumberPrototype%': [
        'Number',
        'prototype'
    ],
    '%ObjectPrototype%': [
        'Object',
        'prototype'
    ],
    '%ObjProto_toString%': [
        'Object',
        'prototype',
        'toString'
    ],
    '%ObjProto_valueOf%': [
        'Object',
        'prototype',
        'valueOf'
    ],
    '%PromisePrototype%': [
        'Promise',
        'prototype'
    ],
    '%PromiseProto_then%': [
        'Promise',
        'prototype',
        'then'
    ],
    '%Promise_all%': [
        'Promise',
        'all'
    ],
    '%Promise_reject%': [
        'Promise',
        'reject'
    ],
    '%Promise_resolve%': [
        'Promise',
        'resolve'
    ],
    '%RangeErrorPrototype%': [
        'RangeError',
        'prototype'
    ],
    '%ReferenceErrorPrototype%': [
        'ReferenceError',
        'prototype'
    ],
    '%RegExpPrototype%': [
        'RegExp',
        'prototype'
    ],
    '%SetPrototype%': [
        'Set',
        'prototype'
    ],
    '%SharedArrayBufferPrototype%': [
        'SharedArrayBuffer',
        'prototype'
    ],
    '%StringPrototype%': [
        'String',
        'prototype'
    ],
    '%SymbolPrototype%': [
        'Symbol',
        'prototype'
    ],
    '%SyntaxErrorPrototype%': [
        'SyntaxError',
        'prototype'
    ],
    '%TypedArrayPrototype%': [
        'TypedArray',
        'prototype'
    ],
    '%TypeErrorPrototype%': [
        'TypeError',
        'prototype'
    ],
    '%Uint8ArrayPrototype%': [
        'Uint8Array',
        'prototype'
    ],
    '%Uint8ClampedArrayPrototype%': [
        'Uint8ClampedArray',
        'prototype'
    ],
    '%Uint16ArrayPrototype%': [
        'Uint16Array',
        'prototype'
    ],
    '%Uint32ArrayPrototype%': [
        'Uint32Array',
        'prototype'
    ],
    '%URIErrorPrototype%': [
        'URIError',
        'prototype'
    ],
    '%WeakMapPrototype%': [
        'WeakMap',
        'prototype'
    ],
    '%WeakSetPrototype%': [
        'WeakSet',
        'prototype'
    ]
};
var bind = require('function-bind');
var hasOwn = require('has');
var $concat = bind.call(Function.call, Array.prototype.concat);
var $spliceApply = bind.call(Function.apply, Array.prototype.splice);
var $replace = bind.call(Function.call, String.prototype.replace);
var $strSlice = bind.call(Function.call, String.prototype.slice);
/* adapted from https://github.com/lodash/lodash/blob/4.17.15/dist/lodash.js#L6735-L6744 */ var rePropName = /[^%.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|%$))/g;
var reEscapeChar = /\\(\\)?/g; /** Used to match backslashes in property paths. */ 
var stringToPath = function stringToPath(string) {
    var first = $strSlice(string, 0, 1);
    var last = $strSlice(string, -1);
    if (first === '%' && last !== '%') throw new $SyntaxError('invalid intrinsic syntax, expected closing `%`');
    else if (last === '%' && first !== '%') throw new $SyntaxError('invalid intrinsic syntax, expected opening `%`');
    var result = [];
    $replace(string, rePropName, function(match, number, quote, subString) {
        result[result.length] = quote ? $replace(subString, reEscapeChar, '$1') : number || match;
    });
    return result;
};
/* end adaptation */ var getBaseIntrinsic = function getBaseIntrinsic(name, allowMissing) {
    var intrinsicName = name;
    var alias;
    if (hasOwn(LEGACY_ALIASES, intrinsicName)) {
        alias = LEGACY_ALIASES[intrinsicName];
        intrinsicName = '%' + alias[0] + '%';
    }
    if (hasOwn(INTRINSICS, intrinsicName)) {
        var value = INTRINSICS[intrinsicName];
        if (value === needsEval) value = doEval1(intrinsicName);
        if (typeof value === 'undefined' && !allowMissing) throw new $TypeError('intrinsic ' + name + ' exists, but is not available. Please file an issue!');
        return {
            alias: alias,
            name: intrinsicName,
            value: value
        };
    }
    throw new $SyntaxError('intrinsic ' + name + ' does not exist!');
};
module.exports = function GetIntrinsic(name, allowMissing) {
    if (typeof name !== 'string' || name.length === 0) throw new $TypeError('intrinsic name must be a non-empty string');
    if (arguments.length > 1 && typeof allowMissing !== 'boolean') throw new $TypeError('"allowMissing" argument must be a boolean');
    var parts = stringToPath(name);
    var intrinsicBaseName = parts.length > 0 ? parts[0] : '';
    var intrinsic = getBaseIntrinsic('%' + intrinsicBaseName + '%', allowMissing);
    var intrinsicRealName = intrinsic.name;
    var value = intrinsic.value;
    var skipFurtherCaching = false;
    var alias = intrinsic.alias;
    if (alias) {
        intrinsicBaseName = alias[0];
        $spliceApply(parts, $concat([
            0,
            1
        ], alias));
    }
    for(var i = 1, isOwn = true; i < parts.length; i += 1){
        var part = parts[i];
        var first = $strSlice(part, 0, 1);
        var last = $strSlice(part, -1);
        if ((first === '"' || first === "'" || first === '`' || last === '"' || last === "'" || last === '`') && first !== last) throw new $SyntaxError('property names with quotes must have matching quotes');
        if (part === 'constructor' || !isOwn) skipFurtherCaching = true;
        intrinsicBaseName += '.' + part;
        intrinsicRealName = '%' + intrinsicBaseName + '%';
        if (hasOwn(INTRINSICS, intrinsicRealName)) value = INTRINSICS[intrinsicRealName];
        else if (value != null) {
            if (!(part in value)) {
                if (!allowMissing) throw new $TypeError('base intrinsic for ' + name + ' exists, but the property is not available.');
                return void 0;
            }
            if ($gOPD && i + 1 >= parts.length) {
                var desc = $gOPD(value, part);
                isOwn = !!desc;
                // By convention, when a data property is converted to an accessor
                // property to emulate a data property that does not suffer from
                // the override mistake, that accessor's getter is marked with
                // an `originalValue` property. Here, when we detect this, we
                // uphold the illusion by pretending to see that original data
                // property, i.e., returning the value rather than the getter
                // itself.
                if (isOwn && 'get' in desc && !('originalValue' in desc.get)) value = desc.get;
                else value = value[part];
            } else {
                isOwn = hasOwn(value, part);
                value = value[part];
            }
            if (isOwn && !skipFurtherCaching) INTRINSICS[intrinsicRealName] = value;
        }
    }
    return value;
};

},{"has-symbols":"iwqSm","function-bind":"13Udp","has":"6Inba"}],"iwqSm":[function(require,module,exports) {
'use strict';
var origSymbol = typeof Symbol !== 'undefined' && Symbol;
var hasSymbolSham = require('./shams');
module.exports = function hasNativeSymbols() {
    if (typeof origSymbol !== 'function') return false;
    if (typeof Symbol !== 'function') return false;
    if (typeof origSymbol('foo') !== 'symbol') return false;
    if (typeof Symbol('bar') !== 'symbol') return false;
    return hasSymbolSham();
};

},{"./shams":"lhOu9"}],"13Udp":[function(require,module,exports) {
'use strict';
var implementation = require('./implementation');
module.exports = Function.prototype.bind || implementation;

},{"./implementation":"iyrnl"}],"iyrnl":[function(require,module,exports) {
'use strict';
/* eslint no-invalid-this: 1 */ var ERROR_MESSAGE = 'Function.prototype.bind called on incompatible ';
var slice = Array.prototype.slice;
var toStr = Object.prototype.toString;
var funcType = '[object Function]';
module.exports = function bind(that) {
    var target = this;
    if (typeof target !== 'function' || toStr.call(target) !== funcType) throw new TypeError(ERROR_MESSAGE + target);
    var args = slice.call(arguments, 1);
    var bound;
    var binder = function() {
        if (this instanceof bound) {
            var result = target.apply(this, args.concat(slice.call(arguments)));
            if (Object(result) === result) return result;
            return this;
        } else return target.apply(that, args.concat(slice.call(arguments)));
    };
    var boundLength = Math.max(0, target.length - args.length);
    var boundArgs = [];
    for(var i = 0; i < boundLength; i++)boundArgs.push('$' + i);
    bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this,arguments); }')(binder);
    if (target.prototype) {
        var Empty = function Empty() {
        };
        Empty.prototype = target.prototype;
        bound.prototype = new Empty();
        Empty.prototype = null;
    }
    return bound;
};

},{}],"6Inba":[function(require,module,exports) {
'use strict';
var bind = require('function-bind');
module.exports = bind.call(Function.call, Object.prototype.hasOwnProperty);

},{"function-bind":"13Udp"}],"bPDkM":[function(require,module,exports) {
'use strict';
var bind = require('function-bind');
var GetIntrinsic = require('get-intrinsic');
var $apply = GetIntrinsic('%Function.prototype.apply%');
var $call = GetIntrinsic('%Function.prototype.call%');
var $reflectApply = GetIntrinsic('%Reflect.apply%', true) || bind.call($call, $apply);
var $gOPD = GetIntrinsic('%Object.getOwnPropertyDescriptor%', true);
var $defineProperty = GetIntrinsic('%Object.defineProperty%', true);
var $max = GetIntrinsic('%Math.max%');
if ($defineProperty) try {
    $defineProperty({
    }, 'a', {
        value: 1
    });
} catch (e) {
    // IE 8 has a broken defineProperty
    $defineProperty = null;
}
module.exports = function callBind(originalFunction) {
    var func = $reflectApply(bind, $call, arguments);
    if ($gOPD && $defineProperty) {
        var desc = $gOPD(func, 'length');
        if (desc.configurable) // original length, plus the receiver, minus any additional arguments (after the receiver)
        $defineProperty(func, 'length', {
            value: 1 + $max(0, originalFunction.length - (arguments.length - 1))
        });
    }
    return func;
};
var applyBind = function applyBind() {
    return $reflectApply(bind, $apply, arguments);
};
if ($defineProperty) $defineProperty(module.exports, 'apply', {
    value: applyBind
});
else module.exports.apply = applyBind;

},{"function-bind":"13Udp","get-intrinsic":"4hk6k"}],"kT8Ou":[function(require,module,exports) {
'use strict';
var toStr = Object.prototype.toString;
var fnToStr = Function.prototype.toString;
var isFnRegex = /^\s*(?:function)?\*/;
var hasToStringTag = require('has-tostringtag/shams')();
var getProto = Object.getPrototypeOf;
var getGeneratorFunc = function() {
    if (!hasToStringTag) return false;
    try {
        return Function('return function*() {}')();
    } catch (e) {
    }
};
var GeneratorFunction;
module.exports = function isGeneratorFunction(fn) {
    if (typeof fn !== 'function') return false;
    if (isFnRegex.test(fnToStr.call(fn))) return true;
    if (!hasToStringTag) {
        var str = toStr.call(fn);
        return str === '[object GeneratorFunction]';
    }
    if (!getProto) return false;
    if (typeof GeneratorFunction === 'undefined') {
        var generatorFunc = getGeneratorFunc();
        GeneratorFunction = generatorFunc ? getProto(generatorFunc) : false;
    }
    return getProto(fn) === GeneratorFunction;
};

},{"has-tostringtag/shams":"7aneK"}],"iDM4O":[function(require,module,exports) {
var global = arguments[3];
'use strict';
var forEach = require('foreach');
var availableTypedArrays = require('available-typed-arrays');
var callBound = require('call-bind/callBound');
var $toString = callBound('Object.prototype.toString');
var hasToStringTag = require('has-tostringtag/shams')();
var g = typeof globalThis === 'undefined' ? global : globalThis;
var typedArrays = availableTypedArrays();
var $slice = callBound('String.prototype.slice');
var toStrTags = {
};
var gOPD = require('es-abstract/helpers/getOwnPropertyDescriptor');
var getPrototypeOf = Object.getPrototypeOf; // require('getprototypeof');
if (hasToStringTag && gOPD && getPrototypeOf) forEach(typedArrays, function(typedArray) {
    if (typeof g[typedArray] === 'function') {
        var arr = new g[typedArray]();
        if (Symbol.toStringTag in arr) {
            var proto = getPrototypeOf(arr);
            var descriptor = gOPD(proto, Symbol.toStringTag);
            if (!descriptor) {
                var superProto = getPrototypeOf(proto);
                descriptor = gOPD(superProto, Symbol.toStringTag);
            }
            toStrTags[typedArray] = descriptor.get;
        }
    }
});
var tryTypedArrays = function tryAllTypedArrays(value) {
    var foundName = false;
    forEach(toStrTags, function(getter, typedArray) {
        if (!foundName) try {
            var name = getter.call(value);
            if (name === typedArray) foundName = name;
        } catch (e) {
        }
    });
    return foundName;
};
var isTypedArray = require('is-typed-array');
module.exports = function whichTypedArray(value) {
    if (!isTypedArray(value)) return false;
    if (!hasToStringTag || !(Symbol.toStringTag in value)) return $slice($toString(value), 8, -1);
    return tryTypedArrays(value);
};

},{"foreach":"h6wOr","available-typed-arrays":"9Wjza","call-bind/callBound":"f0fyo","has-tostringtag/shams":"7aneK","es-abstract/helpers/getOwnPropertyDescriptor":"gx5Wc","is-typed-array":"6c7tM"}],"h6wOr":[function(require,module,exports) {
var hasOwn = Object.prototype.hasOwnProperty;
var toString = Object.prototype.toString;
module.exports = function forEach(obj, fn, ctx) {
    if (toString.call(fn) !== '[object Function]') throw new TypeError('iterator must be a function');
    var l = obj.length;
    if (l === +l) for(var i = 0; i < l; i++)fn.call(ctx, obj[i], i, obj);
    else {
        for(var k in obj)if (hasOwn.call(obj, k)) fn.call(ctx, obj[k], k, obj);
    }
};

},{}],"9Wjza":[function(require,module,exports) {
var global = arguments[3];
'use strict';
var possibleNames = [
    'BigInt64Array',
    'BigUint64Array',
    'Float32Array',
    'Float64Array',
    'Int16Array',
    'Int32Array',
    'Int8Array',
    'Uint16Array',
    'Uint32Array',
    'Uint8Array',
    'Uint8ClampedArray'
];
var g = typeof globalThis === 'undefined' ? global : globalThis;
module.exports = function availableTypedArrays() {
    var out = [];
    for(var i = 0; i < possibleNames.length; i++)if (typeof g[possibleNames[i]] === 'function') out[out.length] = possibleNames[i];
    return out;
};

},{}],"gx5Wc":[function(require,module,exports) {
'use strict';
var GetIntrinsic = require('get-intrinsic');
var $gOPD = GetIntrinsic('%Object.getOwnPropertyDescriptor%', true);
if ($gOPD) try {
    $gOPD([], 'length');
} catch (e) {
    // IE 8 has a broken gOPD
    $gOPD = null;
}
module.exports = $gOPD;

},{"get-intrinsic":"4hk6k"}],"6c7tM":[function(require,module,exports) {
var global = arguments[3];
'use strict';
var forEach = require('foreach');
var availableTypedArrays = require('available-typed-arrays');
var callBound = require('call-bind/callBound');
var $toString = callBound('Object.prototype.toString');
var hasToStringTag = require('has-tostringtag/shams')();
var g = typeof globalThis === 'undefined' ? global : globalThis;
var typedArrays = availableTypedArrays();
var $indexOf = callBound('Array.prototype.indexOf', true) || function indexOf(array, value) {
    for(var i = 0; i < array.length; i += 1){
        if (array[i] === value) return i;
    }
    return -1;
};
var $slice = callBound('String.prototype.slice');
var toStrTags = {
};
var gOPD = require('es-abstract/helpers/getOwnPropertyDescriptor');
var getPrototypeOf = Object.getPrototypeOf; // require('getprototypeof');
if (hasToStringTag && gOPD && getPrototypeOf) forEach(typedArrays, function(typedArray) {
    var arr = new g[typedArray]();
    if (Symbol.toStringTag in arr) {
        var proto = getPrototypeOf(arr);
        var descriptor = gOPD(proto, Symbol.toStringTag);
        if (!descriptor) {
            var superProto = getPrototypeOf(proto);
            descriptor = gOPD(superProto, Symbol.toStringTag);
        }
        toStrTags[typedArray] = descriptor.get;
    }
});
var tryTypedArrays = function tryAllTypedArrays(value) {
    var anyTrue = false;
    forEach(toStrTags, function(getter, typedArray) {
        if (!anyTrue) try {
            anyTrue = getter.call(value) === typedArray;
        } catch (e) {
        }
    });
    return anyTrue;
};
module.exports = function isTypedArray(value) {
    if (!value || typeof value !== 'object') return false;
    if (!hasToStringTag || !(Symbol.toStringTag in value)) {
        var tag = $slice($toString(value), 8, -1);
        return $indexOf(typedArrays, tag) > -1;
    }
    if (!gOPD) return false;
    return tryTypedArrays(value);
};

},{"foreach":"h6wOr","available-typed-arrays":"9Wjza","call-bind/callBound":"f0fyo","has-tostringtag/shams":"7aneK","es-abstract/helpers/getOwnPropertyDescriptor":"gx5Wc"}],"k1wGR":[function(require,module,exports) {
module.exports = function isBuffer(arg) {
    return arg && typeof arg === 'object' && typeof arg.copy === 'function' && typeof arg.fill === 'function' && typeof arg.readUInt8 === 'function';
};

},{}],"emkVv":[function(require,module,exports) {
'use strict';
const { AbstractLevelDOWN  } = require('abstract-leveldown');
const inherits = require('inherits');
const DeferredIterator = require('./deferred-iterator');
const DeferredChainedBatch = require('./deferred-chained-batch');
const getCallback = require('./util').getCallback;
const deferrables = [
    'put',
    'get',
    'getMany',
    'del',
    'batch',
    'clear'
];
const optionalDeferrables = [
    'approximateSize',
    'compactRange'
];
const kInnerDb = Symbol('innerDb');
const kOperations = Symbol('operations');
const kPromise = Symbol('promise');
function DeferredLevelDOWN(db) {
    AbstractLevelDOWN.call(this, db.supports || {
    });
    // TODO (future major): remove this fallback; db must have manifest that
    // declares approximateSize and compactRange in additionalMethods.
    for (const m of optionalDeferrables)if (typeof db[m] === 'function' && !this.supports.additionalMethods[m]) this.supports.additionalMethods[m] = true;
    this[kInnerDb] = db;
    this[kOperations] = [];
    implement(this);
}
inherits(DeferredLevelDOWN, AbstractLevelDOWN);
DeferredLevelDOWN.prototype.type = 'deferred-leveldown';
// Backwards compatibility for reachdown and subleveldown
Object.defineProperty(DeferredLevelDOWN.prototype, '_db', {
    enumerable: true,
    get () {
        return this[kInnerDb];
    }
});
DeferredLevelDOWN.prototype._open = function(options, callback) {
    const onopen = (err)=>{
        if (err || this[kInnerDb].status !== 'open') // TODO: reject scheduled operations
        return callback(err || new Error('Database is not open'));
        const operations = this[kOperations];
        this[kOperations] = [];
        for (const op of operations)if (op.iterator) op.iterator.setDb(this[kInnerDb]);
        else this[kInnerDb][op.method](...op.args);
        /* istanbul ignore if: assertion */ if (this[kOperations].length > 0) throw new Error('Did not expect further operations');
        callback();
    };
    if (this[kInnerDb].status === 'new' || this[kInnerDb].status === 'closed') this[kInnerDb].open(options, onopen);
    else this._nextTick(onopen);
};
DeferredLevelDOWN.prototype._close = function(callback) {
    this[kInnerDb].close(callback);
};
DeferredLevelDOWN.prototype._isOperational = function() {
    return this.status === 'opening';
};
function implement(self) {
    const additionalMethods = Object.keys(self.supports.additionalMethods);
    for (const method of deferrables.concat(additionalMethods))// Override the public rather than private methods to cover cases where abstract-leveldown
    // has a fast-path like on db.batch([]) which bypasses _batch() because the array is empty.
    self[method] = function(...args) {
        if (method === 'batch' && args.length === 0) return new DeferredChainedBatch(this);
        else if (this.status === 'open') return this[kInnerDb][method](...args);
        const callback = getCallback(args, kPromise);
        if (this.status === 'opening') this[kOperations].push({
            method,
            args
        });
        else this._nextTick(callback, new Error('Database is not open'));
        return callback[kPromise];
    };
    self.iterator = function(options) {
        if (this.status === 'open') return this[kInnerDb].iterator(options);
        else if (this.status === 'opening') {
            const iterator = new DeferredIterator(this, options);
            this[kOperations].push({
                iterator
            });
            return iterator;
        } else throw new Error('Database is not open');
    };
    for (const method1 of deferrables.concat([
        'iterator'
    ]))self['_' + method1] = function() {
        /* istanbul ignore next: assertion */ throw new Error('Did not expect private method to be called: ' + method1);
    };
}
module.exports = DeferredLevelDOWN;
module.exports.DeferredIterator = DeferredIterator;

},{"abstract-leveldown":"jvgwU","inherits":"d3hL2","./deferred-iterator":"db8Ah","./deferred-chained-batch":"cOF40","./util":"eK7I4"}],"jvgwU":[function(require,module,exports) {
'use strict';
exports.AbstractLevelDOWN = require('./abstract-leveldown');
exports.AbstractIterator = require('./abstract-iterator');
exports.AbstractChainedBatch = require('./abstract-chained-batch');

},{"./abstract-leveldown":"lKDWd","./abstract-iterator":"ffT5c","./abstract-chained-batch":"5acH7"}],"lKDWd":[function(require,module,exports) {
'use strict';
const supports = require('level-supports');
const isBuffer = require('is-buffer');
const catering = require('catering');
const AbstractIterator = require('./abstract-iterator');
const AbstractChainedBatch = require('./abstract-chained-batch');
const getCallback = require('./lib/common').getCallback;
const getOptions = require('./lib/common').getOptions;
const hasOwnProperty = Object.prototype.hasOwnProperty;
const rangeOptions = [
    'lt',
    'lte',
    'gt',
    'gte'
];
function AbstractLevelDOWN(manifest) {
    this.status = 'new';
    // TODO (next major): make this mandatory
    this.supports = supports(manifest, {
        status: true
    });
}
AbstractLevelDOWN.prototype.open = function(options, callback) {
    const oldStatus = this.status;
    if (typeof options === 'function') callback = options;
    if (typeof callback !== 'function') throw new Error('open() requires a callback argument');
    if (typeof options !== 'object' || options === null) options = {
    };
    options.createIfMissing = options.createIfMissing !== false;
    options.errorIfExists = !!options.errorIfExists;
    this.status = 'opening';
    this._open(options, (err)=>{
        if (err) {
            this.status = oldStatus;
            return callback(err);
        }
        this.status = 'open';
        callback();
    });
};
AbstractLevelDOWN.prototype._open = function(options, callback) {
    this._nextTick(callback);
};
AbstractLevelDOWN.prototype.close = function(callback) {
    const oldStatus = this.status;
    if (typeof callback !== 'function') throw new Error('close() requires a callback argument');
    this.status = 'closing';
    this._close((err)=>{
        if (err) {
            this.status = oldStatus;
            return callback(err);
        }
        this.status = 'closed';
        callback();
    });
};
AbstractLevelDOWN.prototype._close = function(callback) {
    this._nextTick(callback);
};
AbstractLevelDOWN.prototype.get = function(key, options, callback) {
    if (typeof options === 'function') callback = options;
    if (typeof callback !== 'function') throw new Error('get() requires a callback argument');
    const err = this._checkKey(key);
    if (err) return this._nextTick(callback, err);
    key = this._serializeKey(key);
    if (typeof options !== 'object' || options === null) options = {
    };
    options.asBuffer = options.asBuffer !== false;
    this._get(key, options, callback);
};
AbstractLevelDOWN.prototype._get = function(key, options, callback) {
    this._nextTick(function() {
        callback(new Error('NotFound'));
    });
};
AbstractLevelDOWN.prototype.getMany = function(keys, options, callback) {
    callback = getCallback(options, callback);
    callback = catering.fromCallback(callback);
    options = getOptions(options);
    if (maybeError(this, callback)) return callback.promise;
    if (!Array.isArray(keys)) {
        this._nextTick(callback, new Error('getMany() requires an array argument'));
        return callback.promise;
    }
    if (keys.length === 0) {
        this._nextTick(callback, null, []);
        return callback.promise;
    }
    if (typeof options.asBuffer !== 'boolean') options = {
        ...options,
        asBuffer: true
    };
    const serialized = new Array(keys.length);
    for(let i = 0; i < keys.length; i++){
        const key = keys[i];
        const err = this._checkKey(key);
        if (err) {
            this._nextTick(callback, err);
            return callback.promise;
        }
        serialized[i] = this._serializeKey(key);
    }
    this._getMany(serialized, options, callback);
    return callback.promise;
};
AbstractLevelDOWN.prototype._getMany = function(keys, options, callback) {
    this._nextTick(callback, null, new Array(keys.length).fill(undefined));
};
AbstractLevelDOWN.prototype.put = function(key, value, options, callback) {
    if (typeof options === 'function') callback = options;
    if (typeof callback !== 'function') throw new Error('put() requires a callback argument');
    const err = this._checkKey(key) || this._checkValue(value);
    if (err) return this._nextTick(callback, err);
    key = this._serializeKey(key);
    value = this._serializeValue(value);
    if (typeof options !== 'object' || options === null) options = {
    };
    this._put(key, value, options, callback);
};
AbstractLevelDOWN.prototype._put = function(key, value, options, callback) {
    this._nextTick(callback);
};
AbstractLevelDOWN.prototype.del = function(key, options, callback) {
    if (typeof options === 'function') callback = options;
    if (typeof callback !== 'function') throw new Error('del() requires a callback argument');
    const err = this._checkKey(key);
    if (err) return this._nextTick(callback, err);
    key = this._serializeKey(key);
    if (typeof options !== 'object' || options === null) options = {
    };
    this._del(key, options, callback);
};
AbstractLevelDOWN.prototype._del = function(key, options, callback) {
    this._nextTick(callback);
};
AbstractLevelDOWN.prototype.batch = function(array, options, callback) {
    if (!arguments.length) return this._chainedBatch();
    if (typeof options === 'function') callback = options;
    if (typeof array === 'function') callback = array;
    if (typeof callback !== 'function') throw new Error('batch(array) requires a callback argument');
    if (!Array.isArray(array)) return this._nextTick(callback, new Error('batch(array) requires an array argument'));
    if (array.length === 0) return this._nextTick(callback);
    if (typeof options !== 'object' || options === null) options = {
    };
    const serialized = new Array(array.length);
    for(let i = 0; i < array.length; i++){
        if (typeof array[i] !== 'object' || array[i] === null) return this._nextTick(callback, new Error('batch(array) element must be an object and not `null`'));
        const e = Object.assign({
        }, array[i]);
        if (e.type !== 'put' && e.type !== 'del') return this._nextTick(callback, new Error("`type` must be 'put' or 'del'"));
        const err = this._checkKey(e.key);
        if (err) return this._nextTick(callback, err);
        e.key = this._serializeKey(e.key);
        if (e.type === 'put') {
            const valueErr = this._checkValue(e.value);
            if (valueErr) return this._nextTick(callback, valueErr);
            e.value = this._serializeValue(e.value);
        }
        serialized[i] = e;
    }
    this._batch(serialized, options, callback);
};
AbstractLevelDOWN.prototype._batch = function(array, options, callback) {
    this._nextTick(callback);
};
AbstractLevelDOWN.prototype.clear = function(options, callback) {
    if (typeof options === 'function') callback = options;
    else if (typeof callback !== 'function') throw new Error('clear() requires a callback argument');
    options = cleanRangeOptions(this, options);
    options.reverse = !!options.reverse;
    options.limit = 'limit' in options ? options.limit : -1;
    this._clear(options, callback);
};
AbstractLevelDOWN.prototype._clear = function(options, callback) {
    // Avoid setupIteratorOptions, would serialize range options a second time.
    options.keys = true;
    options.values = false;
    options.keyAsBuffer = true;
    options.valueAsBuffer = true;
    const iterator = this._iterator(options);
    const emptyOptions = {
    };
    const next = (err1)=>{
        if (err1) return iterator.end(function() {
            callback(err1);
        });
        iterator.next((err, key)=>{
            if (err) return next(err);
            if (key === undefined) return iterator.end(callback);
            // This could be optimized by using a batch, but the default _clear
            // is not meant to be fast. Implementations have more room to optimize
            // if they override _clear. Note: using _del bypasses key serialization.
            this._del(key, emptyOptions, next);
        });
    };
    next();
};
AbstractLevelDOWN.prototype._setupIteratorOptions = function(options) {
    options = cleanRangeOptions(this, options);
    options.reverse = !!options.reverse;
    options.keys = options.keys !== false;
    options.values = options.values !== false;
    options.limit = 'limit' in options ? options.limit : -1;
    options.keyAsBuffer = options.keyAsBuffer !== false;
    options.valueAsBuffer = options.valueAsBuffer !== false;
    return options;
};
function cleanRangeOptions(db, options) {
    const result = {
    };
    for(const k in options){
        if (!hasOwnProperty.call(options, k)) continue;
        if (k === 'start' || k === 'end') throw new Error('Legacy range options ("start" and "end") have been removed');
        let opt = options[k];
        if (isRangeOption(k)) // Note that we don't reject nullish and empty options here. While
        // those types are invalid as keys, they are valid as range options.
        opt = db._serializeKey(opt);
        result[k] = opt;
    }
    return result;
}
function isRangeOption(k) {
    return rangeOptions.indexOf(k) !== -1;
}
AbstractLevelDOWN.prototype.iterator = function(options) {
    if (typeof options !== 'object' || options === null) options = {
    };
    options = this._setupIteratorOptions(options);
    return this._iterator(options);
};
AbstractLevelDOWN.prototype._iterator = function(options) {
    return new AbstractIterator(this);
};
AbstractLevelDOWN.prototype._chainedBatch = function() {
    return new AbstractChainedBatch(this);
};
AbstractLevelDOWN.prototype._serializeKey = function(key) {
    return key;
};
AbstractLevelDOWN.prototype._serializeValue = function(value) {
    return value;
};
AbstractLevelDOWN.prototype._checkKey = function(key) {
    if (key === null || key === undefined) return new Error('key cannot be `null` or `undefined`');
    else if (isBuffer(key) && key.length === 0) return new Error('key cannot be an empty Buffer');
    else if (key === '') return new Error('key cannot be an empty String');
    else if (Array.isArray(key) && key.length === 0) return new Error('key cannot be an empty Array');
};
AbstractLevelDOWN.prototype._checkValue = function(value) {
    if (value === null || value === undefined) return new Error('value cannot be `null` or `undefined`');
};
// TODO: docs and tests
AbstractLevelDOWN.prototype.isOperational = function() {
    return this.status === 'open' || this._isOperational();
};
// Implementation may accept operations in other states too
AbstractLevelDOWN.prototype._isOperational = function() {
    return false;
};
// Expose browser-compatible nextTick for dependents
// TODO: rename _nextTick to _queueMicrotask
// TODO: after we drop node 10, also use queueMicrotask in node
AbstractLevelDOWN.prototype._nextTick = require('./next-tick');
module.exports = AbstractLevelDOWN;
function maybeError(db, callback) {
    if (!db.isOperational()) {
        db._nextTick(callback, new Error('Database is not open'));
        return true;
    }
    return false;
}

},{"level-supports":"1scZb","is-buffer":"1UQTn","catering":"hpV8E","./abstract-iterator":"ffT5c","./abstract-chained-batch":"5acH7","./lib/common":"4t6Oq","./next-tick":"6a39s"}],"1scZb":[function(require,module,exports) {
'use strict';
module.exports = function supports(...manifests) {
    const manifest = manifests.reduce((acc, m)=>Object.assign(acc, m)
    , {
    });
    return Object.assign(manifest, {
        // Features of abstract-leveldown
        bufferKeys: manifest.bufferKeys || false,
        snapshots: manifest.snapshots || false,
        permanence: manifest.permanence || false,
        seek: manifest.seek || false,
        clear: manifest.clear || false,
        getMany: manifest.getMany || false,
        keyIterator: manifest.keyIterator || false,
        valueIterator: manifest.valueIterator || false,
        iteratorNextv: manifest.iteratorNextv || false,
        iteratorAll: manifest.iteratorAll || false,
        // Features of abstract-leveldown that levelup doesn't have
        status: manifest.status || false,
        idempotentOpen: manifest.idempotentOpen || false,
        passiveOpen: manifest.passiveOpen || false,
        serialize: manifest.serialize || false,
        // Features of disk-based implementations
        createIfMissing: manifest.createIfMissing || false,
        errorIfExists: manifest.errorIfExists || false,
        // Features of level(up) that abstract-leveldown doesn't have yet
        deferredOpen: manifest.deferredOpen || false,
        openCallback: manifest.openCallback || false,
        promises: manifest.promises || false,
        streams: manifest.streams || false,
        encodings: maybeObject(manifest.encodings),
        events: maybeObject(manifest.events),
        // Methods that are not part of abstract-leveldown or levelup
        additionalMethods: Object.assign({
        }, manifest.additionalMethods)
    });
};
function maybeObject(value) {
    return !value ? false : Object.assign({
    }, value);
}

},{}],"1UQTn":[function(require,module,exports) {
/*!
 * Determine if an object is a Buffer
 *
 * @author   Feross Aboukhadijeh <https://feross.org>
 * @license  MIT
 */ module.exports = function isBuffer(obj) {
    return obj != null && obj.constructor != null && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj);
};

},{}],"hpV8E":[function(require,module,exports) {
'use strict';
var queueTick = require('queue-tick');
exports.fromCallback = function(callback, symbol) {
    if (callback === undefined) {
        var promise = new Promise(function(resolve, reject) {
            callback = function(err, res) {
                if (err) reject(err);
                else resolve(res);
            };
        });
        callback[symbol !== undefined ? symbol : 'promise'] = promise;
    } else if (typeof callback !== 'function') throw new TypeError('Callback must be a function');
    return callback;
};
exports.fromPromise = function(promise, callback) {
    if (callback === undefined) return promise;
    promise.then(function(res) {
        queueTick(()=>callback(null, res)
        );
    }).catch(function(err) {
        queueTick(()=>callback(err)
        );
    });
};

},{"queue-tick":"6ao8o"}],"6ao8o":[function(require,module,exports) {
module.exports = typeof queueMicrotask === 'function' ? queueMicrotask : (fn)=>Promise.resolve().then(fn)
;

},{}],"ffT5c":[function(require,module,exports) {
'use strict';
function AbstractIterator(db) {
    if (typeof db !== 'object' || db === null) throw new TypeError('First argument must be an abstract-leveldown compliant store');
    this.db = db;
    this._ended = false;
    this._nexting = false;
}
AbstractIterator.prototype.next = function(callback) {
    // In callback mode, we return `this`
    let ret = this;
    if (callback === undefined) ret = new Promise(function(resolve, reject) {
        callback = function(err, key, value) {
            if (err) reject(err);
            else if (key === undefined && value === undefined) resolve();
            else resolve([
                key,
                value
            ]);
        };
    });
    else if (typeof callback !== 'function') throw new Error('next() requires a callback argument');
    if (this._ended) {
        this._nextTick(callback, new Error('cannot call next() after end()'));
        return ret;
    }
    if (this._nexting) {
        this._nextTick(callback, new Error('cannot call next() before previous next() has completed'));
        return ret;
    }
    this._nexting = true;
    this._next((err, ...rest)=>{
        this._nexting = false;
        callback(err, ...rest);
    });
    return ret;
};
AbstractIterator.prototype._next = function(callback) {
    this._nextTick(callback);
};
AbstractIterator.prototype.seek = function(target) {
    if (this._ended) throw new Error('cannot call seek() after end()');
    if (this._nexting) throw new Error('cannot call seek() before next() has completed');
    target = this.db._serializeKey(target);
    this._seek(target);
};
AbstractIterator.prototype._seek = function(target) {
};
AbstractIterator.prototype.end = function(callback) {
    let promise;
    if (callback === undefined) promise = new Promise(function(resolve, reject) {
        callback = function(err) {
            if (err) reject(err);
            else resolve();
        };
    });
    else if (typeof callback !== 'function') throw new Error('end() requires a callback argument');
    if (this._ended) {
        this._nextTick(callback, new Error('end() already called on iterator'));
        return promise;
    }
    this._ended = true;
    this._end(callback);
    return promise;
};
AbstractIterator.prototype._end = function(callback) {
    this._nextTick(callback);
};
AbstractIterator.prototype[Symbol.asyncIterator] = async function*() {
    try {
        let kv;
        while((kv = await this.next()) !== undefined)yield kv;
    } finally{
        if (!this._ended) await this.end();
    }
};
// Expose browser-compatible nextTick for dependents
AbstractIterator.prototype._nextTick = require('./next-tick');
module.exports = AbstractIterator;

},{"./next-tick":"6a39s"}],"6a39s":[function(require,module,exports) {
'use strict';
const queueMicrotask = require('queue-microtask');
module.exports = function(fn, ...args) {
    if (args.length === 0) queueMicrotask(fn);
    else queueMicrotask(()=>fn(...args)
    );
};

},{"queue-microtask":"9M7Vw"}],"9M7Vw":[function(require,module,exports) {
var global = arguments[3];
/*! queue-microtask. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */ let promise;
module.exports = typeof queueMicrotask === 'function' ? queueMicrotask.bind(typeof window !== 'undefined' ? window : global) : (cb)=>(promise || (promise = Promise.resolve())).then(cb).catch((err)=>setTimeout(()=>{
            throw err;
        }, 0)
    )
;

},{}],"5acH7":[function(require,module,exports) {
'use strict';
const emptyOptions = Object.freeze({
});
function AbstractChainedBatch(db) {
    if (typeof db !== 'object' || db === null) throw new TypeError('First argument must be an abstract-leveldown compliant store');
    this.db = db;
    this._operations = [];
    this._written = false;
}
AbstractChainedBatch.prototype._checkWritten = function() {
    if (this._written) throw new Error('write() already called on this batch');
};
AbstractChainedBatch.prototype.put = function(key, value, options) {
    this._checkWritten();
    const err = this.db._checkKey(key) || this.db._checkValue(value);
    if (err) throw err;
    key = this.db._serializeKey(key);
    value = this.db._serializeValue(value);
    this._put(key, value, options != null ? options : emptyOptions);
    return this;
};
AbstractChainedBatch.prototype._put = function(key, value, options) {
    this._operations.push({
        ...options,
        type: 'put',
        key,
        value
    });
};
AbstractChainedBatch.prototype.del = function(key, options) {
    this._checkWritten();
    const err = this.db._checkKey(key);
    if (err) throw err;
    key = this.db._serializeKey(key);
    this._del(key, options != null ? options : emptyOptions);
    return this;
};
AbstractChainedBatch.prototype._del = function(key, options) {
    this._operations.push({
        ...options,
        type: 'del',
        key
    });
};
AbstractChainedBatch.prototype.clear = function() {
    this._checkWritten();
    this._clear();
    return this;
};
AbstractChainedBatch.prototype._clear = function() {
    this._operations = [];
};
AbstractChainedBatch.prototype.write = function(options, callback) {
    this._checkWritten();
    if (typeof options === 'function') callback = options;
    if (typeof callback !== 'function') throw new Error('write() requires a callback argument');
    if (typeof options !== 'object' || options === null) options = {
    };
    this._written = true;
    this._write(options, callback);
};
AbstractChainedBatch.prototype._write = function(options, callback) {
    this.db._batch(this._operations, options, callback);
};
// Expose browser-compatible nextTick for dependents
AbstractChainedBatch.prototype._nextTick = require('./next-tick');
module.exports = AbstractChainedBatch;

},{"./next-tick":"6a39s"}],"4t6Oq":[function(require,module,exports) {
'use strict';
exports.getCallback = function(options, callback) {
    return typeof options === 'function' ? options : callback;
};
exports.getOptions = function(options) {
    return typeof options === 'object' && options !== null ? options : {
    };
};

},{}],"db8Ah":[function(require,module,exports) {
'use strict';
const { AbstractIterator  } = require('abstract-leveldown');
const inherits = require('inherits');
const getCallback = require('./util').getCallback;
const kOptions = Symbol('options');
const kIterator = Symbol('iterator');
const kOperations = Symbol('operations');
const kPromise = Symbol('promise');
function DeferredIterator(db, options) {
    AbstractIterator.call(this, db);
    this[kOptions] = options;
    this[kIterator] = null;
    this[kOperations] = [];
}
inherits(DeferredIterator, AbstractIterator);
DeferredIterator.prototype.setDb = function(db) {
    this[kIterator] = db.iterator(this[kOptions]);
    for (const op of this[kOperations].splice(0, this[kOperations].length))this[kIterator][op.method](...op.args);
};
DeferredIterator.prototype.next = function(...args) {
    if (this.db.status === 'open') return this[kIterator].next(...args);
    const callback = getCallback(args, kPromise, function map(key, value) {
        if (key === undefined && value === undefined) return undefined;
        else return [
            key,
            value
        ];
    });
    if (this.db.status === 'opening') this[kOperations].push({
        method: 'next',
        args
    });
    else this._nextTick(callback, new Error('Database is not open'));
    return callback[kPromise] || this;
};
DeferredIterator.prototype.seek = function(...args) {
    if (this.db.status === 'open') this[kIterator].seek(...args);
    else if (this.db.status === 'opening') this[kOperations].push({
        method: 'seek',
        args
    });
    else throw new Error('Database is not open');
};
DeferredIterator.prototype.end = function(...args) {
    if (this.db.status === 'open') return this[kIterator].end(...args);
    const callback = getCallback(args, kPromise);
    if (this.db.status === 'opening') this[kOperations].push({
        method: 'end',
        args
    });
    else this._nextTick(callback, new Error('Database is not open'));
    return callback[kPromise] || this;
};
for (const method of [
    'next',
    'seek',
    'end'
])DeferredIterator.prototype['_' + method] = function() {
    /* istanbul ignore next: assertion */ throw new Error('Did not expect private method to be called: ' + method);
};
module.exports = DeferredIterator;

},{"abstract-leveldown":"jvgwU","inherits":"d3hL2","./util":"eK7I4"}],"eK7I4":[function(require,module,exports) {
'use strict';
exports.getCallback = function(args, symbol, map) {
    let callback = args[args.length - 1];
    if (typeof callback !== 'function') {
        const promise = new Promise((resolve, reject)=>{
            args.push(callback = function(err, ...results) {
                if (err) reject(err);
                else resolve(map ? map(...results) : results[0]);
            });
        });
        callback[symbol] = promise;
    }
    return callback;
};

},{}],"cOF40":[function(require,module,exports) {
'use strict';
const { AbstractChainedBatch  } = require('abstract-leveldown');
const kOperations = Symbol('operations');
module.exports = class DeferredChainedBatch extends AbstractChainedBatch {
    constructor(db){
        super(db);
        this[kOperations] = [];
    }
    _put(key, value, options) {
        this[kOperations].push({
            ...options,
            type: 'put',
            key,
            value
        });
    }
    _del(key1, options1) {
        this[kOperations].push({
            ...options1,
            type: 'del',
            key: key1
        });
    }
    _clear() {
        this[kOperations] = [];
    }
    _write(options2, callback) {
        // AbstractChainedBatch would call _batch(), we call batch()
        this.db.batch(this[kOperations], options2, callback);
    }
};

},{"abstract-leveldown":"jvgwU"}],"sfkOa":[function(require,module,exports) {
'use strict';
const inherits = require('inherits');
const { Readable  } = require('readable-stream');
module.exports = ReadStream;
inherits(ReadStream, Readable);
function ReadStream(iterator, options) {
    if (!(this instanceof ReadStream)) return new ReadStream(iterator, options);
    options = options || {
    };
    Readable.call(this, Object.assign({
    }, options, {
        objectMode: true
    }));
    this._iterator = iterator;
    this._options = options;
    this.on('end', this.destroy.bind(this, null, null));
}
ReadStream.prototype._read = function() {
    if (this.destroyed) return;
    this._iterator.next((err, key, value)=>{
        if (this.destroyed) return;
        if (err) return this.destroy(err);
        if (key === undefined && value === undefined) this.push(null);
        else if (this._options.keys !== false && this._options.values === false) this.push(key);
        else if (this._options.keys === false && this._options.values !== false) this.push(value);
        else this.push({
            key,
            value
        });
    });
};
ReadStream.prototype._destroy = function(err, callback) {
    this._iterator.end(function(err2) {
        callback(err || err2);
    });
};

},{"inherits":"d3hL2","readable-stream":"dDZDY"}],"dDZDY":[function(require,module,exports) {
exports = module.exports = require('./lib/_stream_readable.js');
exports.Stream = exports;
exports.Readable = exports;
exports.Writable = require('./lib/_stream_writable.js');
exports.Duplex = require('./lib/_stream_duplex.js');
exports.Transform = require('./lib/_stream_transform.js');
exports.PassThrough = require('./lib/_stream_passthrough.js');
exports.finished = require('./lib/internal/streams/end-of-stream.js');
exports.pipeline = require('./lib/internal/streams/pipeline.js');

},{"./lib/_stream_readable.js":"lUe9z","./lib/_stream_writable.js":"k8dSD","./lib/_stream_duplex.js":"8XkxS","./lib/_stream_transform.js":"lDiiK","./lib/_stream_passthrough.js":"gj76M","./lib/internal/streams/end-of-stream.js":"8Xuxj","./lib/internal/streams/pipeline.js":"iNB4a"}],"lUe9z":[function(require,module,exports) {
var global = arguments[3];
var process = require("process");
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
module.exports = Readable;
/*<replacement>*/ var Duplex;
/*</replacement>*/ Readable.ReadableState = ReadableState;
/*<replacement>*/ var EE = require('events').EventEmitter;
var EElistenerCount = function EElistenerCount(emitter, type) {
    return emitter.listeners(type).length;
};
/*</replacement>*/ /*<replacement>*/ var Stream = require('./internal/streams/stream');
/*</replacement>*/ var Buffer = require('buffer').Buffer;
var OurUint8Array = global.Uint8Array || function() {
};
function _uint8ArrayToBuffer(chunk) {
    return Buffer.from(chunk);
}
function _isUint8Array(obj) {
    return Buffer.isBuffer(obj) || obj instanceof OurUint8Array;
}
/*<replacement>*/ var debugUtil = require('util');
var debug;
if (debugUtil && debugUtil.debuglog) debug = debugUtil.debuglog('stream');
else debug = function debug() {
};
/*</replacement>*/ var BufferList = require('./internal/streams/buffer_list');
var destroyImpl = require('./internal/streams/destroy');
var _require = require('./internal/streams/state'), getHighWaterMark = _require.getHighWaterMark;
var _require$codes = require('../errors').codes, ERR_INVALID_ARG_TYPE = _require$codes.ERR_INVALID_ARG_TYPE, ERR_STREAM_PUSH_AFTER_EOF = _require$codes.ERR_STREAM_PUSH_AFTER_EOF, ERR_METHOD_NOT_IMPLEMENTED = _require$codes.ERR_METHOD_NOT_IMPLEMENTED, ERR_STREAM_UNSHIFT_AFTER_END_EVENT = _require$codes.ERR_STREAM_UNSHIFT_AFTER_END_EVENT; // Lazy loaded to improve the startup performance.
var StringDecoder;
var createReadableStreamAsyncIterator;
var from;
require('inherits')(Readable, Stream);
var errorOrDestroy = destroyImpl.errorOrDestroy;
var kProxyEvents = [
    'error',
    'close',
    'destroy',
    'pause',
    'resume'
];
function prependListener(emitter, event, fn) {
    // Sadly this is not cacheable as some libraries bundle their own
    // event emitter implementation with them.
    if (typeof emitter.prependListener === 'function') return emitter.prependListener(event, fn); // This is a hack to make sure that our error handler is attached before any
    // userland ones.  NEVER DO THIS. This is here only because this code needs
    // to continue to work with older versions of Node.js that do not include
    // the prependListener() method. The goal is to eventually remove this hack.
    if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);
    else if (Array.isArray(emitter._events[event])) emitter._events[event].unshift(fn);
    else emitter._events[event] = [
        fn,
        emitter._events[event]
    ];
}
function ReadableState(options, stream, isDuplex) {
    Duplex = Duplex || require('./_stream_duplex');
    options = options || {
    }; // Duplex streams are both readable and writable, but share
    // the same options object.
    // However, some cases require setting options to different
    // values for the readable and the writable sides of the duplex stream.
    // These options can be provided separately as readableXXX and writableXXX.
    if (typeof isDuplex !== 'boolean') isDuplex = stream instanceof Duplex; // object stream flag. Used to make read(n) ignore n and to
    // make all the buffer merging and length checks go away
    this.objectMode = !!options.objectMode;
    if (isDuplex) this.objectMode = this.objectMode || !!options.readableObjectMode; // the point at which it stops calling _read() to fill the buffer
    // Note: 0 is a valid value, means "don't call _read preemptively ever"
    this.highWaterMark = getHighWaterMark(this, options, 'readableHighWaterMark', isDuplex); // A linked list is used to store data chunks instead of an array because the
    // linked list can remove elements from the beginning faster than
    // array.shift()
    this.buffer = new BufferList();
    this.length = 0;
    this.pipes = null;
    this.pipesCount = 0;
    this.flowing = null;
    this.ended = false;
    this.endEmitted = false;
    this.reading = false; // a flag to be able to tell if the event 'readable'/'data' is emitted
    // immediately, or on a later tick.  We set this to true at first, because
    // any actions that shouldn't happen until "later" should generally also
    // not happen before the first read call.
    this.sync = true; // whenever we return null, then we set a flag to say
    // that we're awaiting a 'readable' event emission.
    this.needReadable = false;
    this.emittedReadable = false;
    this.readableListening = false;
    this.resumeScheduled = false;
    this.paused = true; // Should close be emitted on destroy. Defaults to true.
    this.emitClose = options.emitClose !== false; // Should .destroy() be called after 'end' (and potentially 'finish')
    this.autoDestroy = !!options.autoDestroy; // has it been destroyed
    this.destroyed = false; // Crypto is kind of old and crusty.  Historically, its default string
    // encoding is 'binary' so we have to make this configurable.
    // Everything else in the universe uses 'utf8', though.
    this.defaultEncoding = options.defaultEncoding || 'utf8'; // the number of writers that are awaiting a drain event in .pipe()s
    this.awaitDrain = 0; // if true, a maybeReadMore has been scheduled
    this.readingMore = false;
    this.decoder = null;
    this.encoding = null;
    if (options.encoding) {
        if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;
        this.decoder = new StringDecoder(options.encoding);
        this.encoding = options.encoding;
    }
}
function Readable(options) {
    Duplex = Duplex || require('./_stream_duplex');
    if (!(this instanceof Readable)) return new Readable(options); // Checking for a Stream.Duplex instance is faster here instead of inside
    // the ReadableState constructor, at least with V8 6.5
    var isDuplex = this instanceof Duplex;
    this._readableState = new ReadableState(options, this, isDuplex); // legacy
    this.readable = true;
    if (options) {
        if (typeof options.read === 'function') this._read = options.read;
        if (typeof options.destroy === 'function') this._destroy = options.destroy;
    }
    Stream.call(this);
}
Object.defineProperty(Readable.prototype, 'destroyed', {
    // making it explicit this property is not enumerable
    // because otherwise some prototype manipulation in
    // userland will fail
    enumerable: false,
    get: function get() {
        if (this._readableState === undefined) return false;
        return this._readableState.destroyed;
    },
    set: function set(value) {
        // we ignore the value if the stream
        // has not been initialized yet
        if (!this._readableState) return;
         // backward compatibility, the user is explicitly
        // managing destroyed
        this._readableState.destroyed = value;
    }
});
Readable.prototype.destroy = destroyImpl.destroy;
Readable.prototype._undestroy = destroyImpl.undestroy;
Readable.prototype._destroy = function(err, cb) {
    cb(err);
}; // Manually shove something into the read() buffer.
// This returns true if the highWaterMark has not been hit yet,
// similar to how Writable.write() returns true if you should
// write() some more.
Readable.prototype.push = function(chunk, encoding) {
    var state = this._readableState;
    var skipChunkCheck;
    if (!state.objectMode) {
        if (typeof chunk === 'string') {
            encoding = encoding || state.defaultEncoding;
            if (encoding !== state.encoding) {
                chunk = Buffer.from(chunk, encoding);
                encoding = '';
            }
            skipChunkCheck = true;
        }
    } else skipChunkCheck = true;
    return readableAddChunk(this, chunk, encoding, false, skipChunkCheck);
}; // Unshift should *always* be something directly out of read()
Readable.prototype.unshift = function(chunk) {
    return readableAddChunk(this, chunk, null, true, false);
};
function readableAddChunk(stream, chunk, encoding, addToFront, skipChunkCheck) {
    debug('readableAddChunk', chunk);
    var state = stream._readableState;
    if (chunk === null) {
        state.reading = false;
        onEofChunk(stream, state);
    } else {
        var er;
        if (!skipChunkCheck) er = chunkInvalid(state, chunk);
        if (er) errorOrDestroy(stream, er);
        else if (state.objectMode || chunk && chunk.length > 0) {
            if (typeof chunk !== 'string' && !state.objectMode && Object.getPrototypeOf(chunk) !== Buffer.prototype) chunk = _uint8ArrayToBuffer(chunk);
            if (addToFront) {
                if (state.endEmitted) errorOrDestroy(stream, new ERR_STREAM_UNSHIFT_AFTER_END_EVENT());
                else addChunk(stream, state, chunk, true);
            } else if (state.ended) errorOrDestroy(stream, new ERR_STREAM_PUSH_AFTER_EOF());
            else if (state.destroyed) return false;
            else {
                state.reading = false;
                if (state.decoder && !encoding) {
                    chunk = state.decoder.write(chunk);
                    if (state.objectMode || chunk.length !== 0) addChunk(stream, state, chunk, false);
                    else maybeReadMore(stream, state);
                } else addChunk(stream, state, chunk, false);
            }
        } else if (!addToFront) {
            state.reading = false;
            maybeReadMore(stream, state);
        }
    } // We can push more data if we are below the highWaterMark.
    // Also, if we have no data yet, we can stand some more bytes.
    // This is to work around cases where hwm=0, such as the repl.
    return !state.ended && (state.length < state.highWaterMark || state.length === 0);
}
function addChunk(stream, state, chunk, addToFront) {
    if (state.flowing && state.length === 0 && !state.sync) {
        state.awaitDrain = 0;
        stream.emit('data', chunk);
    } else {
        // update the buffer info.
        state.length += state.objectMode ? 1 : chunk.length;
        if (addToFront) state.buffer.unshift(chunk);
        else state.buffer.push(chunk);
        if (state.needReadable) emitReadable(stream);
    }
    maybeReadMore(stream, state);
}
function chunkInvalid(state, chunk) {
    var er;
    if (!_isUint8Array(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) er = new ERR_INVALID_ARG_TYPE('chunk', [
        'string',
        'Buffer',
        'Uint8Array'
    ], chunk);
    return er;
}
Readable.prototype.isPaused = function() {
    return this._readableState.flowing === false;
}; // backwards compatibility.
Readable.prototype.setEncoding = function(enc) {
    if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;
    var decoder = new StringDecoder(enc);
    this._readableState.decoder = decoder; // If setEncoding(null), decoder.encoding equals utf8
    this._readableState.encoding = this._readableState.decoder.encoding; // Iterate over current buffer to convert already stored Buffers:
    var p = this._readableState.buffer.head;
    var content = '';
    while(p !== null){
        content += decoder.write(p.data);
        p = p.next;
    }
    this._readableState.buffer.clear();
    if (content !== '') this._readableState.buffer.push(content);
    this._readableState.length = content.length;
    return this;
}; // Don't raise the hwm > 1GB
var MAX_HWM = 1073741824;
function computeNewHighWaterMark(n) {
    if (n >= MAX_HWM) // TODO(ronag): Throw ERR_VALUE_OUT_OF_RANGE.
    n = MAX_HWM;
    else {
        // Get the next highest power of 2 to prevent increasing hwm excessively in
        // tiny amounts
        n--;
        n |= n >>> 1;
        n |= n >>> 2;
        n |= n >>> 4;
        n |= n >>> 8;
        n |= n >>> 16;
        n++;
    }
    return n;
} // This function is designed to be inlinable, so please take care when making
// changes to the function body.
function howMuchToRead(n, state) {
    if (n <= 0 || state.length === 0 && state.ended) return 0;
    if (state.objectMode) return 1;
    if (n !== n) {
        // Only flow one buffer at a time
        if (state.flowing && state.length) return state.buffer.head.data.length;
        else return state.length;
    } // If we're asking for more than the current hwm, then raise the hwm.
    if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n);
    if (n <= state.length) return n; // Don't have enough
    if (!state.ended) {
        state.needReadable = true;
        return 0;
    }
    return state.length;
} // you can override either this method, or the async _read(n) below.
Readable.prototype.read = function(n) {
    debug('read', n);
    n = parseInt(n, 10);
    var state = this._readableState;
    var nOrig = n;
    if (n !== 0) state.emittedReadable = false; // if we're doing read(0) to trigger a readable event, but we
    // already have a bunch of data in the buffer, then just trigger
    // the 'readable' event and move on.
    if (n === 0 && state.needReadable && ((state.highWaterMark !== 0 ? state.length >= state.highWaterMark : state.length > 0) || state.ended)) {
        debug('read: emitReadable', state.length, state.ended);
        if (state.length === 0 && state.ended) endReadable(this);
        else emitReadable(this);
        return null;
    }
    n = howMuchToRead(n, state); // if we've ended, and we're now clear, then finish it up.
    if (n === 0 && state.ended) {
        if (state.length === 0) endReadable(this);
        return null;
    } // All the actual chunk generation logic needs to be
    // *below* the call to _read.  The reason is that in certain
    // synthetic stream cases, such as passthrough streams, _read
    // may be a completely synchronous operation which may change
    // the state of the read buffer, providing enough data when
    // before there was *not* enough.
    //
    // So, the steps are:
    // 1. Figure out what the state of things will be after we do
    // a read from the buffer.
    //
    // 2. If that resulting state will trigger a _read, then call _read.
    // Note that this may be asynchronous, or synchronous.  Yes, it is
    // deeply ugly to write APIs this way, but that still doesn't mean
    // that the Readable class should behave improperly, as streams are
    // designed to be sync/async agnostic.
    // Take note if the _read call is sync or async (ie, if the read call
    // has returned yet), so that we know whether or not it's safe to emit
    // 'readable' etc.
    //
    // 3. Actually pull the requested chunks out of the buffer and return.
    // if we need a readable event, then we need to do some reading.
    var doRead = state.needReadable;
    debug('need readable', doRead); // if we currently have less than the highWaterMark, then also read some
    if (state.length === 0 || state.length - n < state.highWaterMark) {
        doRead = true;
        debug('length less than watermark', doRead);
    } // however, if we've ended, then there's no point, and if we're already
    // reading, then it's unnecessary.
    if (state.ended || state.reading) {
        doRead = false;
        debug('reading or ended', doRead);
    } else if (doRead) {
        debug('do read');
        state.reading = true;
        state.sync = true; // if the length is currently zero, then we *need* a readable event.
        if (state.length === 0) state.needReadable = true; // call internal read method
        this._read(state.highWaterMark);
        state.sync = false; // If _read pushed data synchronously, then `reading` will be false,
        // and we need to re-evaluate how much data we can return to the user.
        if (!state.reading) n = howMuchToRead(nOrig, state);
    }
    var ret;
    if (n > 0) ret = fromList(n, state);
    else ret = null;
    if (ret === null) {
        state.needReadable = state.length <= state.highWaterMark;
        n = 0;
    } else {
        state.length -= n;
        state.awaitDrain = 0;
    }
    if (state.length === 0) {
        // If we have nothing in the buffer, then we want to know
        // as soon as we *do* get something into the buffer.
        if (!state.ended) state.needReadable = true; // If we tried to read() past the EOF, then emit end on the next tick.
        if (nOrig !== n && state.ended) endReadable(this);
    }
    if (ret !== null) this.emit('data', ret);
    return ret;
};
function onEofChunk(stream, state) {
    debug('onEofChunk');
    if (state.ended) return;
    if (state.decoder) {
        var chunk = state.decoder.end();
        if (chunk && chunk.length) {
            state.buffer.push(chunk);
            state.length += state.objectMode ? 1 : chunk.length;
        }
    }
    state.ended = true;
    if (state.sync) // if we are sync, wait until next tick to emit the data.
    // Otherwise we risk emitting data in the flow()
    // the readable code triggers during a read() call
    emitReadable(stream);
    else {
        // emit 'readable' now to make sure it gets picked up.
        state.needReadable = false;
        if (!state.emittedReadable) {
            state.emittedReadable = true;
            emitReadable_(stream);
        }
    }
} // Don't emit readable right away in sync mode, because this can trigger
// another read() call => stack overflow.  This way, it might trigger
// a nextTick recursion warning, but that's not so bad.
function emitReadable(stream) {
    var state = stream._readableState;
    debug('emitReadable', state.needReadable, state.emittedReadable);
    state.needReadable = false;
    if (!state.emittedReadable) {
        debug('emitReadable', state.flowing);
        state.emittedReadable = true;
        process.nextTick(emitReadable_, stream);
    }
}
function emitReadable_(stream) {
    var state = stream._readableState;
    debug('emitReadable_', state.destroyed, state.length, state.ended);
    if (!state.destroyed && (state.length || state.ended)) {
        stream.emit('readable');
        state.emittedReadable = false;
    } // The stream needs another readable event if
    // 1. It is not flowing, as the flow mechanism will take
    //    care of it.
    // 2. It is not ended.
    // 3. It is below the highWaterMark, so we can schedule
    //    another readable later.
    state.needReadable = !state.flowing && !state.ended && state.length <= state.highWaterMark;
    flow(stream);
} // at this point, the user has presumably seen the 'readable' event,
// and called read() to consume some data.  that may have triggered
// in turn another _read(n) call, in which case reading = true if
// it's in progress.
// However, if we're not ended, or reading, and the length < hwm,
// then go ahead and try to read some more preemptively.
function maybeReadMore(stream, state) {
    if (!state.readingMore) {
        state.readingMore = true;
        process.nextTick(maybeReadMore_, stream, state);
    }
}
function maybeReadMore_(stream, state) {
    // Attempt to read more data if we should.
    //
    // The conditions for reading more data are (one of):
    // - Not enough data buffered (state.length < state.highWaterMark). The loop
    //   is responsible for filling the buffer with enough data if such data
    //   is available. If highWaterMark is 0 and we are not in the flowing mode
    //   we should _not_ attempt to buffer any extra data. We'll get more data
    //   when the stream consumer calls read() instead.
    // - No data in the buffer, and the stream is in flowing mode. In this mode
    //   the loop below is responsible for ensuring read() is called. Failing to
    //   call read here would abort the flow and there's no other mechanism for
    //   continuing the flow if the stream consumer has just subscribed to the
    //   'data' event.
    //
    // In addition to the above conditions to keep reading data, the following
    // conditions prevent the data from being read:
    // - The stream has ended (state.ended).
    // - There is already a pending 'read' operation (state.reading). This is a
    //   case where the the stream has called the implementation defined _read()
    //   method, but they are processing the call asynchronously and have _not_
    //   called push() with new data. In this case we skip performing more
    //   read()s. The execution ends in this method again after the _read() ends
    //   up calling push() with more data.
    while(!state.reading && !state.ended && (state.length < state.highWaterMark || state.flowing && state.length === 0)){
        var len = state.length;
        debug('maybeReadMore read 0');
        stream.read(0);
        if (len === state.length) break;
    }
    state.readingMore = false;
} // abstract method.  to be overridden in specific implementation classes.
// call cb(er, data) where data is <= n in length.
// for virtual (non-string, non-buffer) streams, "length" is somewhat
// arbitrary, and perhaps not very meaningful.
Readable.prototype._read = function(n) {
    errorOrDestroy(this, new ERR_METHOD_NOT_IMPLEMENTED('_read()'));
};
Readable.prototype.pipe = function(dest, pipeOpts) {
    var src = this;
    var state = this._readableState;
    switch(state.pipesCount){
        case 0:
            state.pipes = dest;
            break;
        case 1:
            state.pipes = [
                state.pipes,
                dest
            ];
            break;
        default:
            state.pipes.push(dest);
            break;
    }
    state.pipesCount += 1;
    debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);
    var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr;
    var endFn = doEnd ? onend : unpipe;
    if (state.endEmitted) process.nextTick(endFn);
    else src.once('end', endFn);
    dest.on('unpipe', onunpipe);
    function onunpipe(readable, unpipeInfo) {
        debug('onunpipe');
        if (readable === src) {
            if (unpipeInfo && unpipeInfo.hasUnpiped === false) {
                unpipeInfo.hasUnpiped = true;
                cleanup();
            }
        }
    }
    function onend() {
        debug('onend');
        dest.end();
    } // when the dest drains, it reduces the awaitDrain counter
    // on the source.  This would be more elegant with a .once()
    // handler in flow(), but adding and removing repeatedly is
    // too slow.
    var ondrain = pipeOnDrain(src);
    dest.on('drain', ondrain);
    var cleanedUp = false;
    function cleanup() {
        debug('cleanup'); // cleanup event handlers once the pipe is broken
        dest.removeListener('close', onclose);
        dest.removeListener('finish', onfinish);
        dest.removeListener('drain', ondrain);
        dest.removeListener('error', onerror);
        dest.removeListener('unpipe', onunpipe);
        src.removeListener('end', onend);
        src.removeListener('end', unpipe);
        src.removeListener('data', ondata);
        cleanedUp = true; // if the reader is waiting for a drain event from this
        // specific writer, then it would cause it to never start
        // flowing again.
        // So, if this is awaiting a drain, then we just call it now.
        // If we don't know, then assume that we are waiting for one.
        if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain();
    }
    src.on('data', ondata);
    function ondata(chunk) {
        debug('ondata');
        var ret = dest.write(chunk);
        debug('dest.write', ret);
        if (ret === false) {
            // If the user unpiped during `dest.write()`, it is possible
            // to get stuck in a permanently paused state if that write
            // also returned false.
            // => Check whether `dest` is still a piping destination.
            if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) {
                debug('false write response, pause', state.awaitDrain);
                state.awaitDrain++;
            }
            src.pause();
        }
    } // if the dest has an error, then stop piping into it.
    // however, don't suppress the throwing behavior for this.
    function onerror(er) {
        debug('onerror', er);
        unpipe();
        dest.removeListener('error', onerror);
        if (EElistenerCount(dest, 'error') === 0) errorOrDestroy(dest, er);
    } // Make sure our error handler is attached before userland ones.
    prependListener(dest, 'error', onerror); // Both close and finish should trigger unpipe, but only once.
    function onclose() {
        dest.removeListener('finish', onfinish);
        unpipe();
    }
    dest.once('close', onclose);
    function onfinish() {
        debug('onfinish');
        dest.removeListener('close', onclose);
        unpipe();
    }
    dest.once('finish', onfinish);
    function unpipe() {
        debug('unpipe');
        src.unpipe(dest);
    } // tell the dest that it's being piped to
    dest.emit('pipe', src); // start the flow if it hasn't been started already.
    if (!state.flowing) {
        debug('pipe resume');
        src.resume();
    }
    return dest;
};
function pipeOnDrain(src) {
    return function pipeOnDrainFunctionResult() {
        var state = src._readableState;
        debug('pipeOnDrain', state.awaitDrain);
        if (state.awaitDrain) state.awaitDrain--;
        if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) {
            state.flowing = true;
            flow(src);
        }
    };
}
Readable.prototype.unpipe = function(dest) {
    var state = this._readableState;
    var unpipeInfo = {
        hasUnpiped: false
    }; // if we're not piping anywhere, then do nothing.
    if (state.pipesCount === 0) return this; // just one destination.  most common case.
    if (state.pipesCount === 1) {
        // passed in one, but it's not the right one.
        if (dest && dest !== state.pipes) return this;
        if (!dest) dest = state.pipes; // got a match.
        state.pipes = null;
        state.pipesCount = 0;
        state.flowing = false;
        if (dest) dest.emit('unpipe', this, unpipeInfo);
        return this;
    } // slow case. multiple pipe destinations.
    if (!dest) {
        // remove all.
        var dests = state.pipes;
        var len = state.pipesCount;
        state.pipes = null;
        state.pipesCount = 0;
        state.flowing = false;
        for(var i = 0; i < len; i++)dests[i].emit('unpipe', this, {
            hasUnpiped: false
        });
        return this;
    } // try to find the right one.
    var index = indexOf(state.pipes, dest);
    if (index === -1) return this;
    state.pipes.splice(index, 1);
    state.pipesCount -= 1;
    if (state.pipesCount === 1) state.pipes = state.pipes[0];
    dest.emit('unpipe', this, unpipeInfo);
    return this;
}; // set up data events if they are asked for
// Ensure readable listeners eventually get something
Readable.prototype.on = function(ev, fn) {
    var res = Stream.prototype.on.call(this, ev, fn);
    var state = this._readableState;
    if (ev === 'data') {
        // update readableListening so that resume() may be a no-op
        // a few lines down. This is needed to support once('readable').
        state.readableListening = this.listenerCount('readable') > 0; // Try start flowing on next tick if stream isn't explicitly paused
        if (state.flowing !== false) this.resume();
    } else if (ev === 'readable') {
        if (!state.endEmitted && !state.readableListening) {
            state.readableListening = state.needReadable = true;
            state.flowing = false;
            state.emittedReadable = false;
            debug('on readable', state.length, state.reading);
            if (state.length) emitReadable(this);
            else if (!state.reading) process.nextTick(nReadingNextTick, this);
        }
    }
    return res;
};
Readable.prototype.addListener = Readable.prototype.on;
Readable.prototype.removeListener = function(ev, fn) {
    var res = Stream.prototype.removeListener.call(this, ev, fn);
    if (ev === 'readable') // We need to check if there is someone still listening to
    // readable and reset the state. However this needs to happen
    // after readable has been emitted but before I/O (nextTick) to
    // support once('readable', fn) cycles. This means that calling
    // resume within the same tick will have no
    // effect.
    process.nextTick(updateReadableListening, this);
    return res;
};
Readable.prototype.removeAllListeners = function(ev) {
    var res = Stream.prototype.removeAllListeners.apply(this, arguments);
    if (ev === 'readable' || ev === undefined) // We need to check if there is someone still listening to
    // readable and reset the state. However this needs to happen
    // after readable has been emitted but before I/O (nextTick) to
    // support once('readable', fn) cycles. This means that calling
    // resume within the same tick will have no
    // effect.
    process.nextTick(updateReadableListening, this);
    return res;
};
function updateReadableListening(self) {
    var state = self._readableState;
    state.readableListening = self.listenerCount('readable') > 0;
    if (state.resumeScheduled && !state.paused) // flowing needs to be set to true now, otherwise
    // the upcoming resume will not flow.
    state.flowing = true; // crude way to check if we should resume
    else if (self.listenerCount('data') > 0) self.resume();
}
function nReadingNextTick(self) {
    debug('readable nexttick read 0');
    self.read(0);
} // pause() and resume() are remnants of the legacy readable stream API
// If the user uses them, then switch into old mode.
Readable.prototype.resume = function() {
    var state = this._readableState;
    if (!state.flowing) {
        debug('resume'); // we flow only if there is no one listening
        // for readable, but we still have to call
        // resume()
        state.flowing = !state.readableListening;
        resume(this, state);
    }
    state.paused = false;
    return this;
};
function resume(stream, state) {
    if (!state.resumeScheduled) {
        state.resumeScheduled = true;
        process.nextTick(resume_, stream, state);
    }
}
function resume_(stream, state) {
    debug('resume', state.reading);
    if (!state.reading) stream.read(0);
    state.resumeScheduled = false;
    stream.emit('resume');
    flow(stream);
    if (state.flowing && !state.reading) stream.read(0);
}
Readable.prototype.pause = function() {
    debug('call pause flowing=%j', this._readableState.flowing);
    if (this._readableState.flowing !== false) {
        debug('pause');
        this._readableState.flowing = false;
        this.emit('pause');
    }
    this._readableState.paused = true;
    return this;
};
function flow(stream) {
    var state = stream._readableState;
    debug('flow', state.flowing);
    while(state.flowing && stream.read() !== null);
} // wrap an old-style stream as the async data source.
// This is *not* part of the readable stream interface.
// It is an ugly unfortunate mess of history.
Readable.prototype.wrap = function(stream) {
    var _this = this;
    var state = this._readableState;
    var paused = false;
    stream.on('end', function() {
        debug('wrapped end');
        if (state.decoder && !state.ended) {
            var chunk = state.decoder.end();
            if (chunk && chunk.length) _this.push(chunk);
        }
        _this.push(null);
    });
    stream.on('data', function(chunk) {
        debug('wrapped data');
        if (state.decoder) chunk = state.decoder.write(chunk); // don't skip over falsy values in objectMode
        if (state.objectMode && (chunk === null || chunk === undefined)) return;
        else if (!state.objectMode && (!chunk || !chunk.length)) return;
        var ret = _this.push(chunk);
        if (!ret) {
            paused = true;
            stream.pause();
        }
    }); // proxy all the other methods.
    // important when wrapping filters and duplexes.
    for(var i in stream)if (this[i] === undefined && typeof stream[i] === 'function') this[i] = (function methodWrap(method) {
        return function methodWrapReturnFunction() {
            return stream[method].apply(stream, arguments);
        };
    })(i);
     // proxy certain important events.
    for(var n1 = 0; n1 < kProxyEvents.length; n1++)stream.on(kProxyEvents[n1], this.emit.bind(this, kProxyEvents[n1]));
     // when we try to consume some more bytes, simply unpause the
    // underlying stream.
    this._read = function(n) {
        debug('wrapped _read', n);
        if (paused) {
            paused = false;
            stream.resume();
        }
    };
    return this;
};
if (typeof Symbol === 'function') Readable.prototype[Symbol.asyncIterator] = function() {
    if (createReadableStreamAsyncIterator === undefined) createReadableStreamAsyncIterator = require('./internal/streams/async_iterator');
    return createReadableStreamAsyncIterator(this);
};
Object.defineProperty(Readable.prototype, 'readableHighWaterMark', {
    // making it explicit this property is not enumerable
    // because otherwise some prototype manipulation in
    // userland will fail
    enumerable: false,
    get: function get() {
        return this._readableState.highWaterMark;
    }
});
Object.defineProperty(Readable.prototype, 'readableBuffer', {
    // making it explicit this property is not enumerable
    // because otherwise some prototype manipulation in
    // userland will fail
    enumerable: false,
    get: function get() {
        return this._readableState && this._readableState.buffer;
    }
});
Object.defineProperty(Readable.prototype, 'readableFlowing', {
    // making it explicit this property is not enumerable
    // because otherwise some prototype manipulation in
    // userland will fail
    enumerable: false,
    get: function get() {
        return this._readableState.flowing;
    },
    set: function set(state) {
        if (this._readableState) this._readableState.flowing = state;
    }
}); // exposed for testing purposes only.
Readable._fromList = fromList;
Object.defineProperty(Readable.prototype, 'readableLength', {
    // making it explicit this property is not enumerable
    // because otherwise some prototype manipulation in
    // userland will fail
    enumerable: false,
    get: function get() {
        return this._readableState.length;
    }
}); // Pluck off n bytes from an array of buffers.
// Length is the combined lengths of all the buffers in the list.
// This function is designed to be inlinable, so please take care when making
// changes to the function body.
function fromList(n, state) {
    // nothing buffered
    if (state.length === 0) return null;
    var ret;
    if (state.objectMode) ret = state.buffer.shift();
    else if (!n || n >= state.length) {
        // read it all, truncate the list
        if (state.decoder) ret = state.buffer.join('');
        else if (state.buffer.length === 1) ret = state.buffer.first();
        else ret = state.buffer.concat(state.length);
        state.buffer.clear();
    } else // read part of list
    ret = state.buffer.consume(n, state.decoder);
    return ret;
}
function endReadable(stream) {
    var state = stream._readableState;
    debug('endReadable', state.endEmitted);
    if (!state.endEmitted) {
        state.ended = true;
        process.nextTick(endReadableNT, state, stream);
    }
}
function endReadableNT(state, stream) {
    debug('endReadableNT', state.endEmitted, state.length); // Check that we didn't get one last unshift.
    if (!state.endEmitted && state.length === 0) {
        state.endEmitted = true;
        stream.readable = false;
        stream.emit('end');
        if (state.autoDestroy) {
            // In case of duplex streams we need a way to detect
            // if the writable side is ready for autoDestroy as well
            var wState = stream._writableState;
            if (!wState || wState.autoDestroy && wState.finished) stream.destroy();
        }
    }
}
if (typeof Symbol === 'function') Readable.from = function(iterable, opts) {
    if (from === undefined) from = require('./internal/streams/from');
    return from(Readable, iterable, opts);
};
function indexOf(xs, x) {
    for(var i = 0, l = xs.length; i < l; i++){
        if (xs[i] === x) return i;
    }
    return -1;
}

},{"process":"lDnB8","events":"bHM3D","./internal/streams/stream":"6CSYT","buffer":"eKea5","util":"joWnX","./internal/streams/buffer_list":"IH4pu","./internal/streams/destroy":"hcEiF","./internal/streams/state":"02KOM","../errors":"fjg3U","inherits":"d3hL2","./_stream_duplex":"8XkxS","string_decoder/":"vLxWd","./internal/streams/async_iterator":"a5MdZ","./internal/streams/from":"hFNof"}],"6CSYT":[function(require,module,exports) {
module.exports = require('events').EventEmitter;

},{"events":"bHM3D"}],"IH4pu":[function(require,module,exports) {
'use strict';
function ownKeys(object, enumerableOnly) {
    var keys = Object.keys(object);
    if (Object.getOwnPropertySymbols) {
        var symbols = Object.getOwnPropertySymbols(object);
        if (enumerableOnly) symbols = symbols.filter(function(sym) {
            return Object.getOwnPropertyDescriptor(object, sym).enumerable;
        });
        keys.push.apply(keys, symbols);
    }
    return keys;
}
function _objectSpread(target) {
    for(var i = 1; i < arguments.length; i++){
        var source = arguments[i] != null ? arguments[i] : {
        };
        if (i % 2) ownKeys(Object(source), true).forEach(function(key) {
            _defineProperty(target, key, source[key]);
        });
        else if (Object.getOwnPropertyDescriptors) Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
        else ownKeys(Object(source)).forEach(function(key) {
            Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
        });
    }
    return target;
}
function _defineProperty(obj, key, value) {
    if (key in obj) Object.defineProperty(obj, key, {
        value: value,
        enumerable: true,
        configurable: true,
        writable: true
    });
    else obj[key] = value;
    return obj;
}
function _classCallCheck(instance, Constructor) {
    if (!(instance instanceof Constructor)) throw new TypeError("Cannot call a class as a function");
}
function _defineProperties(target, props) {
    for(var i = 0; i < props.length; i++){
        var descriptor = props[i];
        descriptor.enumerable = descriptor.enumerable || false;
        descriptor.configurable = true;
        if ("value" in descriptor) descriptor.writable = true;
        Object.defineProperty(target, descriptor.key, descriptor);
    }
}
function _createClass(Constructor, protoProps, staticProps) {
    if (protoProps) _defineProperties(Constructor.prototype, protoProps);
    if (staticProps) _defineProperties(Constructor, staticProps);
    return Constructor;
}
var _require = require('buffer'), Buffer = _require.Buffer;
var _require2 = require('util'), inspect = _require2.inspect;
var custom = inspect && inspect.custom || 'inspect';
function copyBuffer(src, target, offset) {
    Buffer.prototype.copy.call(src, target, offset);
}
module.exports = /*#__PURE__*/ (function() {
    function BufferList() {
        _classCallCheck(this, BufferList);
        this.head = null;
        this.tail = null;
        this.length = 0;
    }
    _createClass(BufferList, [
        {
            key: "push",
            value: function push(v) {
                var entry = {
                    data: v,
                    next: null
                };
                if (this.length > 0) this.tail.next = entry;
                else this.head = entry;
                this.tail = entry;
                ++this.length;
            }
        },
        {
            key: "unshift",
            value: function unshift(v) {
                var entry = {
                    data: v,
                    next: this.head
                };
                if (this.length === 0) this.tail = entry;
                this.head = entry;
                ++this.length;
            }
        },
        {
            key: "shift",
            value: function shift() {
                if (this.length === 0) return;
                var ret = this.head.data;
                if (this.length === 1) this.head = this.tail = null;
                else this.head = this.head.next;
                --this.length;
                return ret;
            }
        },
        {
            key: "clear",
            value: function clear() {
                this.head = this.tail = null;
                this.length = 0;
            }
        },
        {
            key: "join",
            value: function join(s) {
                if (this.length === 0) return '';
                var p = this.head;
                var ret = '' + p.data;
                while(p = p.next)ret += s + p.data;
                return ret;
            }
        },
        {
            key: "concat",
            value: function concat(n) {
                if (this.length === 0) return Buffer.alloc(0);
                var ret = Buffer.allocUnsafe(n >>> 0);
                var p = this.head;
                var i = 0;
                while(p){
                    copyBuffer(p.data, ret, i);
                    i += p.data.length;
                    p = p.next;
                }
                return ret;
            } // Consumes a specified amount of bytes or characters from the buffered data.
        },
        {
            key: "consume",
            value: function consume(n, hasStrings) {
                var ret;
                if (n < this.head.data.length) {
                    // `slice` is the same for buffers and strings.
                    ret = this.head.data.slice(0, n);
                    this.head.data = this.head.data.slice(n);
                } else if (n === this.head.data.length) // First chunk is a perfect match.
                ret = this.shift();
                else // Result spans more than one buffer.
                ret = hasStrings ? this._getString(n) : this._getBuffer(n);
                return ret;
            }
        },
        {
            key: "first",
            value: function first() {
                return this.head.data;
            } // Consumes a specified amount of characters from the buffered data.
        },
        {
            key: "_getString",
            value: function _getString(n) {
                var p = this.head;
                var c = 1;
                var ret = p.data;
                n -= ret.length;
                while(p = p.next){
                    var str = p.data;
                    var nb = n > str.length ? str.length : n;
                    if (nb === str.length) ret += str;
                    else ret += str.slice(0, n);
                    n -= nb;
                    if (n === 0) {
                        if (nb === str.length) {
                            ++c;
                            if (p.next) this.head = p.next;
                            else this.head = this.tail = null;
                        } else {
                            this.head = p;
                            p.data = str.slice(nb);
                        }
                        break;
                    }
                    ++c;
                }
                this.length -= c;
                return ret;
            } // Consumes a specified amount of bytes from the buffered data.
        },
        {
            key: "_getBuffer",
            value: function _getBuffer(n) {
                var ret = Buffer.allocUnsafe(n);
                var p = this.head;
                var c = 1;
                p.data.copy(ret);
                n -= p.data.length;
                while(p = p.next){
                    var buf = p.data;
                    var nb = n > buf.length ? buf.length : n;
                    buf.copy(ret, ret.length - n, 0, nb);
                    n -= nb;
                    if (n === 0) {
                        if (nb === buf.length) {
                            ++c;
                            if (p.next) this.head = p.next;
                            else this.head = this.tail = null;
                        } else {
                            this.head = p;
                            p.data = buf.slice(nb);
                        }
                        break;
                    }
                    ++c;
                }
                this.length -= c;
                return ret;
            } // Make sure the linked list only shows the minimal necessary information.
        },
        {
            key: custom,
            value: function value(_, options) {
                return inspect(this, _objectSpread({
                }, options, {
                    // Only inspect one level.
                    depth: 0,
                    // It should not recurse.
                    customInspect: false
                }));
            }
        }
    ]);
    return BufferList;
})();

},{"buffer":"eKea5","util":"joWnX"}],"hcEiF":[function(require,module,exports) {
var process = require("process");
'use strict'; // undocumented cb() API, needed for core, not for public API
function destroy(err1, cb) {
    var _this = this;
    var readableDestroyed = this._readableState && this._readableState.destroyed;
    var writableDestroyed = this._writableState && this._writableState.destroyed;
    if (readableDestroyed || writableDestroyed) {
        if (cb) cb(err1);
        else if (err1) {
            if (!this._writableState) process.nextTick(emitErrorNT, this, err1);
            else if (!this._writableState.errorEmitted) {
                this._writableState.errorEmitted = true;
                process.nextTick(emitErrorNT, this, err1);
            }
        }
        return this;
    } // we set destroyed to true before firing error callbacks in order
    // to make it re-entrance safe in case destroy() is called within callbacks
    if (this._readableState) this._readableState.destroyed = true;
     // if this is a duplex stream mark the writable part as destroyed as well
    if (this._writableState) this._writableState.destroyed = true;
    this._destroy(err1 || null, function(err) {
        if (!cb && err) {
            if (!_this._writableState) process.nextTick(emitErrorAndCloseNT, _this, err);
            else if (!_this._writableState.errorEmitted) {
                _this._writableState.errorEmitted = true;
                process.nextTick(emitErrorAndCloseNT, _this, err);
            } else process.nextTick(emitCloseNT, _this);
        } else if (cb) {
            process.nextTick(emitCloseNT, _this);
            cb(err);
        } else process.nextTick(emitCloseNT, _this);
    });
    return this;
}
function emitErrorAndCloseNT(self, err) {
    emitErrorNT(self, err);
    emitCloseNT(self);
}
function emitCloseNT(self) {
    if (self._writableState && !self._writableState.emitClose) return;
    if (self._readableState && !self._readableState.emitClose) return;
    self.emit('close');
}
function undestroy() {
    if (this._readableState) {
        this._readableState.destroyed = false;
        this._readableState.reading = false;
        this._readableState.ended = false;
        this._readableState.endEmitted = false;
    }
    if (this._writableState) {
        this._writableState.destroyed = false;
        this._writableState.ended = false;
        this._writableState.ending = false;
        this._writableState.finalCalled = false;
        this._writableState.prefinished = false;
        this._writableState.finished = false;
        this._writableState.errorEmitted = false;
    }
}
function emitErrorNT(self, err) {
    self.emit('error', err);
}
function errorOrDestroy(stream, err) {
    // We have tests that rely on errors being emitted
    // in the same tick, so changing this is semver major.
    // For now when you opt-in to autoDestroy we allow
    // the error to be emitted nextTick. In a future
    // semver major update we should change the default to this.
    var rState = stream._readableState;
    var wState = stream._writableState;
    if (rState && rState.autoDestroy || wState && wState.autoDestroy) stream.destroy(err);
    else stream.emit('error', err);
}
module.exports = {
    destroy: destroy,
    undestroy: undestroy,
    errorOrDestroy: errorOrDestroy
};

},{"process":"lDnB8"}],"02KOM":[function(require,module,exports) {
'use strict';
var ERR_INVALID_OPT_VALUE = require('../../../errors').codes.ERR_INVALID_OPT_VALUE;
function highWaterMarkFrom(options, isDuplex, duplexKey) {
    return options.highWaterMark != null ? options.highWaterMark : isDuplex ? options[duplexKey] : null;
}
function getHighWaterMark(state, options, duplexKey, isDuplex) {
    var hwm = highWaterMarkFrom(options, isDuplex, duplexKey);
    if (hwm != null) {
        if (!(isFinite(hwm) && Math.floor(hwm) === hwm) || hwm < 0) {
            var name = isDuplex ? duplexKey : 'highWaterMark';
            throw new ERR_INVALID_OPT_VALUE(name, hwm);
        }
        return Math.floor(hwm);
    } // Default value
    return state.objectMode ? 16 : 16384;
}
module.exports = {
    getHighWaterMark: getHighWaterMark
};

},{"../../../errors":"fjg3U"}],"fjg3U":[function(require,module,exports) {
'use strict';
function _inheritsLoose(subClass, superClass) {
    subClass.prototype = Object.create(superClass.prototype);
    subClass.prototype.constructor = subClass;
    subClass.__proto__ = superClass;
}
var codes = {
};
function createErrorType(code, message, Base) {
    if (!Base) Base = Error;
    function getMessage(arg1, arg2, arg3) {
        if (typeof message === 'string') return message;
        else return message(arg1, arg2, arg3);
    }
    var NodeError1 = /*#__PURE__*/ function(_Base) {
        _inheritsLoose(NodeError, _Base);
        function NodeError(arg1, arg2, arg3) {
            return _Base.call(this, getMessage(arg1, arg2, arg3)) || this;
        }
        return NodeError;
    }(Base);
    NodeError1.prototype.name = Base.name;
    NodeError1.prototype.code = code;
    codes[code] = NodeError1;
} // https://github.com/nodejs/node/blob/v10.8.0/lib/internal/errors.js
function oneOf(expected, thing) {
    if (Array.isArray(expected)) {
        var len = expected.length;
        expected = expected.map(function(i) {
            return String(i);
        });
        if (len > 2) return "one of ".concat(thing, " ").concat(expected.slice(0, len - 1).join(', '), ", or ") + expected[len - 1];
        else if (len === 2) return "one of ".concat(thing, " ").concat(expected[0], " or ").concat(expected[1]);
        else return "of ".concat(thing, " ").concat(expected[0]);
    } else return "of ".concat(thing, " ").concat(String(expected));
} // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith
function startsWith(str, search, pos) {
    return str.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search;
} // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith
function endsWith(str, search, this_len) {
    if (this_len === undefined || this_len > str.length) this_len = str.length;
    return str.substring(this_len - search.length, this_len) === search;
} // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes
function includes(str, search, start) {
    if (typeof start !== 'number') start = 0;
    if (start + search.length > str.length) return false;
    else return str.indexOf(search, start) !== -1;
}
createErrorType('ERR_INVALID_OPT_VALUE', function(name, value) {
    return 'The value "' + value + '" is invalid for option "' + name + '"';
}, TypeError);
createErrorType('ERR_INVALID_ARG_TYPE', function(name, expected, actual) {
    // determiner: 'must be' or 'must not be'
    var determiner;
    if (typeof expected === 'string' && startsWith(expected, 'not ')) {
        determiner = 'must not be';
        expected = expected.replace(/^not /, '');
    } else determiner = 'must be';
    var msg;
    if (endsWith(name, ' argument')) // For cases like 'first argument'
    msg = "The ".concat(name, " ").concat(determiner, " ").concat(oneOf(expected, 'type'));
    else {
        var type = includes(name, '.') ? 'property' : 'argument';
        msg = "The \"".concat(name, "\" ").concat(type, " ").concat(determiner, " ").concat(oneOf(expected, 'type'));
    }
    msg += ". Received type ".concat(typeof actual);
    return msg;
}, TypeError);
createErrorType('ERR_STREAM_PUSH_AFTER_EOF', 'stream.push() after EOF');
createErrorType('ERR_METHOD_NOT_IMPLEMENTED', function(name) {
    return 'The ' + name + ' method is not implemented';
});
createErrorType('ERR_STREAM_PREMATURE_CLOSE', 'Premature close');
createErrorType('ERR_STREAM_DESTROYED', function(name) {
    return 'Cannot call ' + name + ' after a stream was destroyed';
});
createErrorType('ERR_MULTIPLE_CALLBACK', 'Callback called multiple times');
createErrorType('ERR_STREAM_CANNOT_PIPE', 'Cannot pipe, not readable');
createErrorType('ERR_STREAM_WRITE_AFTER_END', 'write after end');
createErrorType('ERR_STREAM_NULL_VALUES', 'May not write null values to stream', TypeError);
createErrorType('ERR_UNKNOWN_ENCODING', function(arg) {
    return 'Unknown encoding: ' + arg;
}, TypeError);
createErrorType('ERR_STREAM_UNSHIFT_AFTER_END_EVENT', 'stream.unshift() after end event');
module.exports.codes = codes;

},{}],"8XkxS":[function(require,module,exports) {
var process = require("process");
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
// a duplex stream is just a stream that is both readable and writable.
// Since JS doesn't have multiple prototypal inheritance, this class
// prototypally inherits from Readable, and then parasitically from
// Writable.
'use strict';
/*<replacement>*/ var objectKeys = Object.keys || function(obj) {
    var keys = [];
    for(var key in obj)keys.push(key);
    return keys;
};
/*</replacement>*/ module.exports = Duplex;
var Readable = require('./_stream_readable');
var Writable = require('./_stream_writable');
require('inherits')(Duplex, Readable);
// Allow the keys array to be GC'ed.
var keys1 = objectKeys(Writable.prototype);
for(var v = 0; v < keys1.length; v++){
    var method = keys1[v];
    if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
}
function Duplex(options) {
    if (!(this instanceof Duplex)) return new Duplex(options);
    Readable.call(this, options);
    Writable.call(this, options);
    this.allowHalfOpen = true;
    if (options) {
        if (options.readable === false) this.readable = false;
        if (options.writable === false) this.writable = false;
        if (options.allowHalfOpen === false) {
            this.allowHalfOpen = false;
            this.once('end', onend);
        }
    }
}
Object.defineProperty(Duplex.prototype, 'writableHighWaterMark', {
    // making it explicit this property is not enumerable
    // because otherwise some prototype manipulation in
    // userland will fail
    enumerable: false,
    get: function get() {
        return this._writableState.highWaterMark;
    }
});
Object.defineProperty(Duplex.prototype, 'writableBuffer', {
    // making it explicit this property is not enumerable
    // because otherwise some prototype manipulation in
    // userland will fail
    enumerable: false,
    get: function get() {
        return this._writableState && this._writableState.getBuffer();
    }
});
Object.defineProperty(Duplex.prototype, 'writableLength', {
    // making it explicit this property is not enumerable
    // because otherwise some prototype manipulation in
    // userland will fail
    enumerable: false,
    get: function get() {
        return this._writableState.length;
    }
}); // the no-half-open enforcer
function onend() {
    // If the writable side ended, then we're ok.
    if (this._writableState.ended) return; // no more data can be written.
    // But allow more writes to happen in this tick.
    process.nextTick(onEndNT, this);
}
function onEndNT(self) {
    self.end();
}
Object.defineProperty(Duplex.prototype, 'destroyed', {
    // making it explicit this property is not enumerable
    // because otherwise some prototype manipulation in
    // userland will fail
    enumerable: false,
    get: function get() {
        if (this._readableState === undefined || this._writableState === undefined) return false;
        return this._readableState.destroyed && this._writableState.destroyed;
    },
    set: function set(value) {
        // we ignore the value if the stream
        // has not been initialized yet
        if (this._readableState === undefined || this._writableState === undefined) return;
         // backward compatibility, the user is explicitly
        // managing destroyed
        this._readableState.destroyed = value;
        this._writableState.destroyed = value;
    }
});

},{"process":"lDnB8","./_stream_readable":"lUe9z","./_stream_writable":"k8dSD","inherits":"d3hL2"}],"k8dSD":[function(require,module,exports) {
var global = arguments[3];
var process = require("process");
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
// A bit simpler than readable streams.
// Implement an async ._write(chunk, encoding, cb), and it'll handle all
// the drain event emission and buffering.
'use strict';
module.exports = Writable;
/* <replacement> */ function WriteReq(chunk, encoding, cb) {
    this.chunk = chunk;
    this.encoding = encoding;
    this.callback = cb;
    this.next = null;
} // It seems a linked list but it is not
// there will be only 2 of these for each stream
function CorkedRequest(state) {
    var _this = this;
    this.next = null;
    this.entry = null;
    this.finish = function() {
        onCorkedFinish(_this, state);
    };
}
/* </replacement> */ /*<replacement>*/ var Duplex;
/*</replacement>*/ Writable.WritableState = WritableState;
/*<replacement>*/ var internalUtil = {
    deprecate: require('util-deprecate')
};
/*</replacement>*/ /*<replacement>*/ var Stream = require('./internal/streams/stream');
/*</replacement>*/ var Buffer = require('buffer').Buffer;
var OurUint8Array = global.Uint8Array || function() {
};
function _uint8ArrayToBuffer(chunk) {
    return Buffer.from(chunk);
}
function _isUint8Array(obj) {
    return Buffer.isBuffer(obj) || obj instanceof OurUint8Array;
}
var destroyImpl = require('./internal/streams/destroy');
var _require = require('./internal/streams/state'), getHighWaterMark = _require.getHighWaterMark;
var _require$codes = require('../errors').codes, ERR_INVALID_ARG_TYPE = _require$codes.ERR_INVALID_ARG_TYPE, ERR_METHOD_NOT_IMPLEMENTED = _require$codes.ERR_METHOD_NOT_IMPLEMENTED, ERR_MULTIPLE_CALLBACK = _require$codes.ERR_MULTIPLE_CALLBACK, ERR_STREAM_CANNOT_PIPE = _require$codes.ERR_STREAM_CANNOT_PIPE, ERR_STREAM_DESTROYED = _require$codes.ERR_STREAM_DESTROYED, ERR_STREAM_NULL_VALUES = _require$codes.ERR_STREAM_NULL_VALUES, ERR_STREAM_WRITE_AFTER_END = _require$codes.ERR_STREAM_WRITE_AFTER_END, ERR_UNKNOWN_ENCODING = _require$codes.ERR_UNKNOWN_ENCODING;
var errorOrDestroy = destroyImpl.errorOrDestroy;
require('inherits')(Writable, Stream);
function nop() {
}
function WritableState(options, stream, isDuplex) {
    Duplex = Duplex || require('./_stream_duplex');
    options = options || {
    }; // Duplex streams are both readable and writable, but share
    // the same options object.
    // However, some cases require setting options to different
    // values for the readable and the writable sides of the duplex stream,
    // e.g. options.readableObjectMode vs. options.writableObjectMode, etc.
    if (typeof isDuplex !== 'boolean') isDuplex = stream instanceof Duplex; // object stream flag to indicate whether or not this stream
    // contains buffers or objects.
    this.objectMode = !!options.objectMode;
    if (isDuplex) this.objectMode = this.objectMode || !!options.writableObjectMode; // the point at which write() starts returning false
    // Note: 0 is a valid value, means that we always return false if
    // the entire buffer is not flushed immediately on write()
    this.highWaterMark = getHighWaterMark(this, options, 'writableHighWaterMark', isDuplex); // if _final has been called
    this.finalCalled = false; // drain event flag.
    this.needDrain = false; // at the start of calling end()
    this.ending = false; // when end() has been called, and returned
    this.ended = false; // when 'finish' is emitted
    this.finished = false; // has it been destroyed
    this.destroyed = false; // should we decode strings into buffers before passing to _write?
    // this is here so that some node-core streams can optimize string
    // handling at a lower level.
    var noDecode = options.decodeStrings === false;
    this.decodeStrings = !noDecode; // Crypto is kind of old and crusty.  Historically, its default string
    // encoding is 'binary' so we have to make this configurable.
    // Everything else in the universe uses 'utf8', though.
    this.defaultEncoding = options.defaultEncoding || 'utf8'; // not an actual buffer we keep track of, but a measurement
    // of how much we're waiting to get pushed to some underlying
    // socket or file.
    this.length = 0; // a flag to see when we're in the middle of a write.
    this.writing = false; // when true all writes will be buffered until .uncork() call
    this.corked = 0; // a flag to be able to tell if the onwrite cb is called immediately,
    // or on a later tick.  We set this to true at first, because any
    // actions that shouldn't happen until "later" should generally also
    // not happen before the first write call.
    this.sync = true; // a flag to know if we're processing previously buffered items, which
    // may call the _write() callback in the same tick, so that we don't
    // end up in an overlapped onwrite situation.
    this.bufferProcessing = false; // the callback that's passed to _write(chunk,cb)
    this.onwrite = function(er) {
        onwrite(stream, er);
    }; // the callback that the user supplies to write(chunk,encoding,cb)
    this.writecb = null; // the amount that is being written when _write is called.
    this.writelen = 0;
    this.bufferedRequest = null;
    this.lastBufferedRequest = null; // number of pending user-supplied write callbacks
    // this must be 0 before 'finish' can be emitted
    this.pendingcb = 0; // emit prefinish if the only thing we're waiting for is _write cbs
    // This is relevant for synchronous Transform streams
    this.prefinished = false; // True if the error was already emitted and should not be thrown again
    this.errorEmitted = false; // Should close be emitted on destroy. Defaults to true.
    this.emitClose = options.emitClose !== false; // Should .destroy() be called after 'finish' (and potentially 'end')
    this.autoDestroy = !!options.autoDestroy; // count buffered requests
    this.bufferedRequestCount = 0; // allocate the first CorkedRequest, there is always
    // one allocated and free to use, and we maintain at most two
    this.corkedRequestsFree = new CorkedRequest(this);
}
WritableState.prototype.getBuffer = function getBuffer() {
    var current = this.bufferedRequest;
    var out = [];
    while(current){
        out.push(current);
        current = current.next;
    }
    return out;
};
(function() {
    try {
        Object.defineProperty(WritableState.prototype, 'buffer', {
            get: internalUtil.deprecate(function writableStateBufferGetter() {
                return this.getBuffer();
            }, "_writableState.buffer is deprecated. Use _writableState.getBuffer instead.", 'DEP0003')
        });
    } catch (_) {
    }
})(); // Test _writableState for inheritance to account for Duplex streams,
// whose prototype chain only points to Readable.
var realHasInstance;
if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') {
    realHasInstance = Function.prototype[Symbol.hasInstance];
    Object.defineProperty(Writable, Symbol.hasInstance, {
        value: function value(object) {
            if (realHasInstance.call(this, object)) return true;
            if (this !== Writable) return false;
            return object && object._writableState instanceof WritableState;
        }
    });
} else realHasInstance = function realHasInstance(object) {
    return object instanceof this;
};
function Writable(options) {
    Duplex = Duplex || require('./_stream_duplex'); // Writable ctor is applied to Duplexes, too.
    // `realHasInstance` is necessary because using plain `instanceof`
    // would return false, as no `_writableState` property is attached.
    // Trying to use the custom `instanceof` for Writable here will also break the
    // Node.js LazyTransform implementation, which has a non-trivial getter for
    // `_writableState` that would lead to infinite recursion.
    // Checking for a Stream.Duplex instance is faster here instead of inside
    // the WritableState constructor, at least with V8 6.5
    var isDuplex = this instanceof Duplex;
    if (!isDuplex && !realHasInstance.call(Writable, this)) return new Writable(options);
    this._writableState = new WritableState(options, this, isDuplex); // legacy.
    this.writable = true;
    if (options) {
        if (typeof options.write === 'function') this._write = options.write;
        if (typeof options.writev === 'function') this._writev = options.writev;
        if (typeof options.destroy === 'function') this._destroy = options.destroy;
        if (typeof options.final === 'function') this._final = options.final;
    }
    Stream.call(this);
} // Otherwise people can pipe Writable streams, which is just wrong.
Writable.prototype.pipe = function() {
    errorOrDestroy(this, new ERR_STREAM_CANNOT_PIPE());
};
function writeAfterEnd(stream, cb) {
    var er = new ERR_STREAM_WRITE_AFTER_END(); // TODO: defer error events consistently everywhere, not just the cb
    errorOrDestroy(stream, er);
    process.nextTick(cb, er);
} // Checks that a user-supplied chunk is valid, especially for the particular
// mode the stream is in. Currently this means that `null` is never accepted
// and undefined/non-string values are only allowed in object mode.
function validChunk(stream, state, chunk, cb) {
    var er;
    if (chunk === null) er = new ERR_STREAM_NULL_VALUES();
    else if (typeof chunk !== 'string' && !state.objectMode) er = new ERR_INVALID_ARG_TYPE('chunk', [
        'string',
        'Buffer'
    ], chunk);
    if (er) {
        errorOrDestroy(stream, er);
        process.nextTick(cb, er);
        return false;
    }
    return true;
}
Writable.prototype.write = function(chunk, encoding, cb) {
    var state = this._writableState;
    var ret = false;
    var isBuf = !state.objectMode && _isUint8Array(chunk);
    if (isBuf && !Buffer.isBuffer(chunk)) chunk = _uint8ArrayToBuffer(chunk);
    if (typeof encoding === 'function') {
        cb = encoding;
        encoding = null;
    }
    if (isBuf) encoding = 'buffer';
    else if (!encoding) encoding = state.defaultEncoding;
    if (typeof cb !== 'function') cb = nop;
    if (state.ending) writeAfterEnd(this, cb);
    else if (isBuf || validChunk(this, state, chunk, cb)) {
        state.pendingcb++;
        ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb);
    }
    return ret;
};
Writable.prototype.cork = function() {
    this._writableState.corked++;
};
Writable.prototype.uncork = function() {
    var state = this._writableState;
    if (state.corked) {
        state.corked--;
        if (!state.writing && !state.corked && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);
    }
};
Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {
    // node::ParseEncoding() requires lower case.
    if (typeof encoding === 'string') encoding = encoding.toLowerCase();
    if (!([
        'hex',
        'utf8',
        'utf-8',
        'ascii',
        'binary',
        'base64',
        'ucs2',
        'ucs-2',
        'utf16le',
        'utf-16le',
        'raw'
    ].indexOf((encoding + '').toLowerCase()) > -1)) throw new ERR_UNKNOWN_ENCODING(encoding);
    this._writableState.defaultEncoding = encoding;
    return this;
};
Object.defineProperty(Writable.prototype, 'writableBuffer', {
    // making it explicit this property is not enumerable
    // because otherwise some prototype manipulation in
    // userland will fail
    enumerable: false,
    get: function get() {
        return this._writableState && this._writableState.getBuffer();
    }
});
function decodeChunk(state, chunk, encoding) {
    if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') chunk = Buffer.from(chunk, encoding);
    return chunk;
}
Object.defineProperty(Writable.prototype, 'writableHighWaterMark', {
    // making it explicit this property is not enumerable
    // because otherwise some prototype manipulation in
    // userland will fail
    enumerable: false,
    get: function get() {
        return this._writableState.highWaterMark;
    }
}); // if we're already writing something, then just put this
// in the queue, and wait our turn.  Otherwise, call _write
// If we return false, then we need a drain event, so set that flag.
function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) {
    if (!isBuf) {
        var newChunk = decodeChunk(state, chunk, encoding);
        if (chunk !== newChunk) {
            isBuf = true;
            encoding = 'buffer';
            chunk = newChunk;
        }
    }
    var len = state.objectMode ? 1 : chunk.length;
    state.length += len;
    var ret = state.length < state.highWaterMark; // we must ensure that previous needDrain will not be reset to false.
    if (!ret) state.needDrain = true;
    if (state.writing || state.corked) {
        var last = state.lastBufferedRequest;
        state.lastBufferedRequest = {
            chunk: chunk,
            encoding: encoding,
            isBuf: isBuf,
            callback: cb,
            next: null
        };
        if (last) last.next = state.lastBufferedRequest;
        else state.bufferedRequest = state.lastBufferedRequest;
        state.bufferedRequestCount += 1;
    } else doWrite(stream, state, false, len, chunk, encoding, cb);
    return ret;
}
function doWrite(stream, state, writev, len, chunk, encoding, cb) {
    state.writelen = len;
    state.writecb = cb;
    state.writing = true;
    state.sync = true;
    if (state.destroyed) state.onwrite(new ERR_STREAM_DESTROYED('write'));
    else if (writev) stream._writev(chunk, state.onwrite);
    else stream._write(chunk, encoding, state.onwrite);
    state.sync = false;
}
function onwriteError(stream, state, sync, er, cb) {
    --state.pendingcb;
    if (sync) {
        // defer the callback if we are being called synchronously
        // to avoid piling up things on the stack
        process.nextTick(cb, er); // this can emit finish, and it will always happen
        // after error
        process.nextTick(finishMaybe, stream, state);
        stream._writableState.errorEmitted = true;
        errorOrDestroy(stream, er);
    } else {
        // the caller expect this to happen before if
        // it is async
        cb(er);
        stream._writableState.errorEmitted = true;
        errorOrDestroy(stream, er); // this can emit finish, but finish must
        // always follow error
        finishMaybe(stream, state);
    }
}
function onwriteStateUpdate(state) {
    state.writing = false;
    state.writecb = null;
    state.length -= state.writelen;
    state.writelen = 0;
}
function onwrite(stream, er) {
    var state = stream._writableState;
    var sync = state.sync;
    var cb = state.writecb;
    if (typeof cb !== 'function') throw new ERR_MULTIPLE_CALLBACK();
    onwriteStateUpdate(state);
    if (er) onwriteError(stream, state, sync, er, cb);
    else {
        // Check if we're actually ready to finish, but don't emit yet
        var finished = needFinish(state) || stream.destroyed;
        if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) clearBuffer(stream, state);
        if (sync) process.nextTick(afterWrite, stream, state, finished, cb);
        else afterWrite(stream, state, finished, cb);
    }
}
function afterWrite(stream, state, finished, cb) {
    if (!finished) onwriteDrain(stream, state);
    state.pendingcb--;
    cb();
    finishMaybe(stream, state);
} // Must force callback to be called on nextTick, so that we don't
// emit 'drain' before the write() consumer gets the 'false' return
// value, and has a chance to attach a 'drain' listener.
function onwriteDrain(stream, state) {
    if (state.length === 0 && state.needDrain) {
        state.needDrain = false;
        stream.emit('drain');
    }
} // if there's something in the buffer waiting, then process it
function clearBuffer(stream, state) {
    state.bufferProcessing = true;
    var entry = state.bufferedRequest;
    if (stream._writev && entry && entry.next) {
        // Fast case, write everything using _writev()
        var l = state.bufferedRequestCount;
        var buffer = new Array(l);
        var holder = state.corkedRequestsFree;
        holder.entry = entry;
        var count = 0;
        var allBuffers = true;
        while(entry){
            buffer[count] = entry;
            if (!entry.isBuf) allBuffers = false;
            entry = entry.next;
            count += 1;
        }
        buffer.allBuffers = allBuffers;
        doWrite(stream, state, true, state.length, buffer, '', holder.finish); // doWrite is almost always async, defer these to save a bit of time
        // as the hot path ends with doWrite
        state.pendingcb++;
        state.lastBufferedRequest = null;
        if (holder.next) {
            state.corkedRequestsFree = holder.next;
            holder.next = null;
        } else state.corkedRequestsFree = new CorkedRequest(state);
        state.bufferedRequestCount = 0;
    } else {
        // Slow case, write chunks one-by-one
        while(entry){
            var chunk = entry.chunk;
            var encoding = entry.encoding;
            var cb = entry.callback;
            var len = state.objectMode ? 1 : chunk.length;
            doWrite(stream, state, false, len, chunk, encoding, cb);
            entry = entry.next;
            state.bufferedRequestCount--; // if we didn't call the onwrite immediately, then
            // it means that we need to wait until it does.
            // also, that means that the chunk and cb are currently
            // being processed, so move the buffer counter past them.
            if (state.writing) break;
        }
        if (entry === null) state.lastBufferedRequest = null;
    }
    state.bufferedRequest = entry;
    state.bufferProcessing = false;
}
Writable.prototype._write = function(chunk, encoding, cb) {
    cb(new ERR_METHOD_NOT_IMPLEMENTED('_write()'));
};
Writable.prototype._writev = null;
Writable.prototype.end = function(chunk, encoding, cb) {
    var state = this._writableState;
    if (typeof chunk === 'function') {
        cb = chunk;
        chunk = null;
        encoding = null;
    } else if (typeof encoding === 'function') {
        cb = encoding;
        encoding = null;
    }
    if (chunk !== null && chunk !== undefined) this.write(chunk, encoding); // .end() fully uncorks
    if (state.corked) {
        state.corked = 1;
        this.uncork();
    } // ignore unnecessary end() calls.
    if (!state.ending) endWritable(this, state, cb);
    return this;
};
Object.defineProperty(Writable.prototype, 'writableLength', {
    // making it explicit this property is not enumerable
    // because otherwise some prototype manipulation in
    // userland will fail
    enumerable: false,
    get: function get() {
        return this._writableState.length;
    }
});
function needFinish(state) {
    return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing;
}
function callFinal(stream, state) {
    stream._final(function(err) {
        state.pendingcb--;
        if (err) errorOrDestroy(stream, err);
        state.prefinished = true;
        stream.emit('prefinish');
        finishMaybe(stream, state);
    });
}
function prefinish(stream, state) {
    if (!state.prefinished && !state.finalCalled) {
        if (typeof stream._final === 'function' && !state.destroyed) {
            state.pendingcb++;
            state.finalCalled = true;
            process.nextTick(callFinal, stream, state);
        } else {
            state.prefinished = true;
            stream.emit('prefinish');
        }
    }
}
function finishMaybe(stream, state) {
    var need = needFinish(state);
    if (need) {
        prefinish(stream, state);
        if (state.pendingcb === 0) {
            state.finished = true;
            stream.emit('finish');
            if (state.autoDestroy) {
                // In case of duplex streams we need a way to detect
                // if the readable side is ready for autoDestroy as well
                var rState = stream._readableState;
                if (!rState || rState.autoDestroy && rState.endEmitted) stream.destroy();
            }
        }
    }
    return need;
}
function endWritable(stream, state, cb) {
    state.ending = true;
    finishMaybe(stream, state);
    if (cb) {
        if (state.finished) process.nextTick(cb);
        else stream.once('finish', cb);
    }
    state.ended = true;
    stream.writable = false;
}
function onCorkedFinish(corkReq, state, err) {
    var entry = corkReq.entry;
    corkReq.entry = null;
    while(entry){
        var cb = entry.callback;
        state.pendingcb--;
        cb(err);
        entry = entry.next;
    } // reuse the free corkReq.
    state.corkedRequestsFree.next = corkReq;
}
Object.defineProperty(Writable.prototype, 'destroyed', {
    // making it explicit this property is not enumerable
    // because otherwise some prototype manipulation in
    // userland will fail
    enumerable: false,
    get: function get() {
        if (this._writableState === undefined) return false;
        return this._writableState.destroyed;
    },
    set: function set(value) {
        // we ignore the value if the stream
        // has not been initialized yet
        if (!this._writableState) return;
         // backward compatibility, the user is explicitly
        // managing destroyed
        this._writableState.destroyed = value;
    }
});
Writable.prototype.destroy = destroyImpl.destroy;
Writable.prototype._undestroy = destroyImpl.undestroy;
Writable.prototype._destroy = function(err, cb) {
    cb(err);
};

},{"process":"lDnB8","util-deprecate":"bfjXI","./internal/streams/stream":"6CSYT","buffer":"eKea5","./internal/streams/destroy":"hcEiF","./internal/streams/state":"02KOM","../errors":"fjg3U","inherits":"d3hL2","./_stream_duplex":"8XkxS"}],"bfjXI":[function(require,module,exports) {
var global = arguments[3];
/**
 * Module exports.
 */ module.exports = deprecate;
/**
 * Mark that a method should not be used.
 * Returns a modified function which warns once by default.
 *
 * If `localStorage.noDeprecation = true` is set, then it is a no-op.
 *
 * If `localStorage.throwDeprecation = true` is set, then deprecated functions
 * will throw an Error when invoked.
 *
 * If `localStorage.traceDeprecation = true` is set, then deprecated functions
 * will invoke `console.trace()` instead of `console.error()`.
 *
 * @param {Function} fn - the function to deprecate
 * @param {String} msg - the string to print to the console when `fn` is invoked
 * @returns {Function} a new "deprecated" version of `fn`
 * @api public
 */ function deprecate(fn, msg) {
    if (config('noDeprecation')) return fn;
    var warned = false;
    function deprecated() {
        if (!warned) {
            if (config('throwDeprecation')) throw new Error(msg);
            else if (config('traceDeprecation')) console.trace(msg);
            else console.warn(msg);
            warned = true;
        }
        return fn.apply(this, arguments);
    }
    return deprecated;
}
/**
 * Checks `localStorage` for boolean values for the given `name`.
 *
 * @param {String} name
 * @returns {Boolean}
 * @api private
 */ function config(name) {
    // accessing global.localStorage can trigger a DOMException in sandboxed iframes
    try {
        if (!global.localStorage) return false;
    } catch (_) {
        return false;
    }
    var val = global.localStorage[name];
    if (null == val) return false;
    return String(val).toLowerCase() === 'true';
}

},{}],"vLxWd":[function(require,module,exports) {
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
/*<replacement>*/ var Buffer = require('safe-buffer').Buffer;
/*</replacement>*/ var isEncoding = Buffer.isEncoding || function(encoding) {
    encoding = '' + encoding;
    switch(encoding && encoding.toLowerCase()){
        case 'hex':
        case 'utf8':
        case 'utf-8':
        case 'ascii':
        case 'binary':
        case 'base64':
        case 'ucs2':
        case 'ucs-2':
        case 'utf16le':
        case 'utf-16le':
        case 'raw':
            return true;
        default:
            return false;
    }
};
function _normalizeEncoding(enc) {
    if (!enc) return 'utf8';
    var retried;
    while(true)switch(enc){
        case 'utf8':
        case 'utf-8':
            return 'utf8';
        case 'ucs2':
        case 'ucs-2':
        case 'utf16le':
        case 'utf-16le':
            return 'utf16le';
        case 'latin1':
        case 'binary':
            return 'latin1';
        case 'base64':
        case 'ascii':
        case 'hex':
            return enc;
        default:
            if (retried) return; // undefined
            enc = ('' + enc).toLowerCase();
            retried = true;
    }
}
// Do not cache `Buffer.isEncoding` when checking encoding names as some
// modules monkey-patch it to support additional encodings
function normalizeEncoding(enc) {
    var nenc = _normalizeEncoding(enc);
    if (typeof nenc !== 'string' && (Buffer.isEncoding === isEncoding || !isEncoding(enc))) throw new Error('Unknown encoding: ' + enc);
    return nenc || enc;
}
// StringDecoder provides an interface for efficiently splitting a series of
// buffers into a series of JS strings without breaking apart multi-byte
// characters.
exports.StringDecoder = StringDecoder;
function StringDecoder(encoding) {
    this.encoding = normalizeEncoding(encoding);
    var nb;
    switch(this.encoding){
        case 'utf16le':
            this.text = utf16Text;
            this.end = utf16End;
            nb = 4;
            break;
        case 'utf8':
            this.fillLast = utf8FillLast;
            nb = 4;
            break;
        case 'base64':
            this.text = base64Text;
            this.end = base64End;
            nb = 3;
            break;
        default:
            this.write = simpleWrite;
            this.end = simpleEnd;
            return;
    }
    this.lastNeed = 0;
    this.lastTotal = 0;
    this.lastChar = Buffer.allocUnsafe(nb);
}
StringDecoder.prototype.write = function(buf) {
    if (buf.length === 0) return '';
    var r;
    var i;
    if (this.lastNeed) {
        r = this.fillLast(buf);
        if (r === undefined) return '';
        i = this.lastNeed;
        this.lastNeed = 0;
    } else i = 0;
    if (i < buf.length) return r ? r + this.text(buf, i) : this.text(buf, i);
    return r || '';
};
StringDecoder.prototype.end = utf8End;
// Returns only complete characters in a Buffer
StringDecoder.prototype.text = utf8Text;
// Attempts to complete a partial non-UTF-8 character using bytes from a Buffer
StringDecoder.prototype.fillLast = function(buf) {
    if (this.lastNeed <= buf.length) {
        buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, this.lastNeed);
        return this.lastChar.toString(this.encoding, 0, this.lastTotal);
    }
    buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, buf.length);
    this.lastNeed -= buf.length;
};
// Checks the type of a UTF-8 byte, whether it's ASCII, a leading byte, or a
// continuation byte. If an invalid byte is detected, -2 is returned.
function utf8CheckByte(byte) {
    if (byte <= 127) return 0;
    else if (byte >> 5 === 6) return 2;
    else if (byte >> 4 === 14) return 3;
    else if (byte >> 3 === 30) return 4;
    return byte >> 6 === 2 ? -1 : -2;
}
// Checks at most 3 bytes at the end of a Buffer in order to detect an
// incomplete multi-byte UTF-8 character. The total number of bytes (2, 3, or 4)
// needed to complete the UTF-8 character (if applicable) are returned.
function utf8CheckIncomplete(self, buf, i) {
    var j = buf.length - 1;
    if (j < i) return 0;
    var nb = utf8CheckByte(buf[j]);
    if (nb >= 0) {
        if (nb > 0) self.lastNeed = nb - 1;
        return nb;
    }
    if (--j < i || nb === -2) return 0;
    nb = utf8CheckByte(buf[j]);
    if (nb >= 0) {
        if (nb > 0) self.lastNeed = nb - 2;
        return nb;
    }
    if (--j < i || nb === -2) return 0;
    nb = utf8CheckByte(buf[j]);
    if (nb >= 0) {
        if (nb > 0) {
            if (nb === 2) nb = 0;
            else self.lastNeed = nb - 3;
        }
        return nb;
    }
    return 0;
}
// Validates as many continuation bytes for a multi-byte UTF-8 character as
// needed or are available. If we see a non-continuation byte where we expect
// one, we "replace" the validated continuation bytes we've seen so far with
// a single UTF-8 replacement character ('\ufffd'), to match v8's UTF-8 decoding
// behavior. The continuation byte check is included three times in the case
// where all of the continuation bytes for a character exist in the same buffer.
// It is also done this way as a slight performance increase instead of using a
// loop.
function utf8CheckExtraBytes(self, buf, p) {
    if ((buf[0] & 192) !== 128) {
        self.lastNeed = 0;
        return '\ufffd';
    }
    if (self.lastNeed > 1 && buf.length > 1) {
        if ((buf[1] & 192) !== 128) {
            self.lastNeed = 1;
            return '\ufffd';
        }
        if (self.lastNeed > 2 && buf.length > 2) {
            if ((buf[2] & 192) !== 128) {
                self.lastNeed = 2;
                return '\ufffd';
            }
        }
    }
}
// Attempts to complete a multi-byte UTF-8 character using bytes from a Buffer.
function utf8FillLast(buf) {
    var p = this.lastTotal - this.lastNeed;
    var r = utf8CheckExtraBytes(this, buf, p);
    if (r !== undefined) return r;
    if (this.lastNeed <= buf.length) {
        buf.copy(this.lastChar, p, 0, this.lastNeed);
        return this.lastChar.toString(this.encoding, 0, this.lastTotal);
    }
    buf.copy(this.lastChar, p, 0, buf.length);
    this.lastNeed -= buf.length;
}
// Returns all complete UTF-8 characters in a Buffer. If the Buffer ended on a
// partial character, the character's bytes are buffered until the required
// number of bytes are available.
function utf8Text(buf, i) {
    var total = utf8CheckIncomplete(this, buf, i);
    if (!this.lastNeed) return buf.toString('utf8', i);
    this.lastTotal = total;
    var end = buf.length - (total - this.lastNeed);
    buf.copy(this.lastChar, 0, end);
    return buf.toString('utf8', i, end);
}
// For UTF-8, a replacement character is added when ending on a partial
// character.
function utf8End(buf) {
    var r = buf && buf.length ? this.write(buf) : '';
    if (this.lastNeed) return r + '\ufffd';
    return r;
}
// UTF-16LE typically needs two bytes per character, but even if we have an even
// number of bytes available, we need to check if we end on a leading/high
// surrogate. In that case, we need to wait for the next two bytes in order to
// decode the last character properly.
function utf16Text(buf, i) {
    if ((buf.length - i) % 2 === 0) {
        var r = buf.toString('utf16le', i);
        if (r) {
            var c = r.charCodeAt(r.length - 1);
            if (c >= 55296 && c <= 56319) {
                this.lastNeed = 2;
                this.lastTotal = 4;
                this.lastChar[0] = buf[buf.length - 2];
                this.lastChar[1] = buf[buf.length - 1];
                return r.slice(0, -1);
            }
        }
        return r;
    }
    this.lastNeed = 1;
    this.lastTotal = 2;
    this.lastChar[0] = buf[buf.length - 1];
    return buf.toString('utf16le', i, buf.length - 1);
}
// For UTF-16LE we do not explicitly append special replacement characters if we
// end on a partial character, we simply let v8 handle that.
function utf16End(buf) {
    var r = buf && buf.length ? this.write(buf) : '';
    if (this.lastNeed) {
        var end = this.lastTotal - this.lastNeed;
        return r + this.lastChar.toString('utf16le', 0, end);
    }
    return r;
}
function base64Text(buf, i) {
    var n = (buf.length - i) % 3;
    if (n === 0) return buf.toString('base64', i);
    this.lastNeed = 3 - n;
    this.lastTotal = 3;
    if (n === 1) this.lastChar[0] = buf[buf.length - 1];
    else {
        this.lastChar[0] = buf[buf.length - 2];
        this.lastChar[1] = buf[buf.length - 1];
    }
    return buf.toString('base64', i, buf.length - n);
}
function base64End(buf) {
    var r = buf && buf.length ? this.write(buf) : '';
    if (this.lastNeed) return r + this.lastChar.toString('base64', 0, 3 - this.lastNeed);
    return r;
}
// Pass bytes on through for single-byte encodings (e.g. ascii, latin1, hex)
function simpleWrite(buf) {
    return buf.toString(this.encoding);
}
function simpleEnd(buf) {
    return buf && buf.length ? this.write(buf) : '';
}

},{"safe-buffer":"5vn3A"}],"5vn3A":[function(require,module,exports) {
/*! safe-buffer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */ /* eslint-disable node/no-deprecated-api */ var buffer = require('buffer');
var Buffer = buffer.Buffer;
// alternative to using Object.keys for old browsers
function copyProps(src, dst) {
    for(var key in src)dst[key] = src[key];
}
if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) module.exports = buffer;
else {
    // Copy properties from require('buffer')
    copyProps(buffer, exports);
    exports.Buffer = SafeBuffer;
}
function SafeBuffer(arg, encodingOrOffset, length) {
    return Buffer(arg, encodingOrOffset, length);
}
SafeBuffer.prototype = Object.create(Buffer.prototype);
// Copy static methods from Buffer
copyProps(Buffer, SafeBuffer);
SafeBuffer.from = function(arg, encodingOrOffset, length) {
    if (typeof arg === 'number') throw new TypeError('Argument must not be a number');
    return Buffer(arg, encodingOrOffset, length);
};
SafeBuffer.alloc = function(size, fill, encoding) {
    if (typeof size !== 'number') throw new TypeError('Argument must be a number');
    var buf = Buffer(size);
    if (fill !== undefined) {
        if (typeof encoding === 'string') buf.fill(fill, encoding);
        else buf.fill(fill);
    } else buf.fill(0);
    return buf;
};
SafeBuffer.allocUnsafe = function(size) {
    if (typeof size !== 'number') throw new TypeError('Argument must be a number');
    return Buffer(size);
};
SafeBuffer.allocUnsafeSlow = function(size) {
    if (typeof size !== 'number') throw new TypeError('Argument must be a number');
    return buffer.SlowBuffer(size);
};

},{"buffer":"eKea5"}],"a5MdZ":[function(require,module,exports) {
var process = require("process");
'use strict';
var _Object$setPrototypeO;
function _defineProperty(obj, key, value) {
    if (key in obj) Object.defineProperty(obj, key, {
        value: value,
        enumerable: true,
        configurable: true,
        writable: true
    });
    else obj[key] = value;
    return obj;
}
var finished = require('./end-of-stream');
var kLastResolve = Symbol('lastResolve');
var kLastReject = Symbol('lastReject');
var kError = Symbol('error');
var kEnded = Symbol('ended');
var kLastPromise = Symbol('lastPromise');
var kHandlePromise = Symbol('handlePromise');
var kStream = Symbol('stream');
function createIterResult(value, done) {
    return {
        value: value,
        done: done
    };
}
function readAndResolve(iter) {
    var resolve = iter[kLastResolve];
    if (resolve !== null) {
        var data = iter[kStream].read(); // we defer if data is null
        // we can be expecting either 'end' or
        // 'error'
        if (data !== null) {
            iter[kLastPromise] = null;
            iter[kLastResolve] = null;
            iter[kLastReject] = null;
            resolve(createIterResult(data, false));
        }
    }
}
function onReadable(iter) {
    // we wait for the next tick, because it might
    // emit an error with process.nextTick
    process.nextTick(readAndResolve, iter);
}
function wrapForNext(lastPromise, iter) {
    return function(resolve, reject) {
        lastPromise.then(function() {
            if (iter[kEnded]) {
                resolve(createIterResult(undefined, true));
                return;
            }
            iter[kHandlePromise](resolve, reject);
        }, reject);
    };
}
var AsyncIteratorPrototype = Object.getPrototypeOf(function() {
});
var ReadableStreamAsyncIteratorPrototype = Object.setPrototypeOf((_Object$setPrototypeO = {
    get stream () {
        return this[kStream];
    },
    next: function next() {
        var _this = this;
        // if we have detected an error in the meanwhile
        // reject straight away
        var error = this[kError];
        if (error !== null) return Promise.reject(error);
        if (this[kEnded]) return Promise.resolve(createIterResult(undefined, true));
        if (this[kStream].destroyed) // We need to defer via nextTick because if .destroy(err) is
        // called, the error will be emitted via nextTick, and
        // we cannot guarantee that there is no error lingering around
        // waiting to be emitted.
        return new Promise(function(resolve, reject) {
            process.nextTick(function() {
                if (_this[kError]) reject(_this[kError]);
                else resolve(createIterResult(undefined, true));
            });
        });
         // if we have multiple next() calls
        // we will wait for the previous Promise to finish
        // this logic is optimized to support for await loops,
        // where next() is only called once at a time
        var lastPromise = this[kLastPromise];
        var promise;
        if (lastPromise) promise = new Promise(wrapForNext(lastPromise, this));
        else {
            // fast path needed to support multiple this.push()
            // without triggering the next() queue
            var data = this[kStream].read();
            if (data !== null) return Promise.resolve(createIterResult(data, false));
            promise = new Promise(this[kHandlePromise]);
        }
        this[kLastPromise] = promise;
        return promise;
    }
}, _defineProperty(_Object$setPrototypeO, Symbol.asyncIterator, function() {
    return this;
}), _defineProperty(_Object$setPrototypeO, "return", function _return() {
    var _this2 = this;
    // destroy(err, cb) is a private API
    // we can guarantee we have that here, because we control the
    // Readable class this is attached to
    return new Promise(function(resolve, reject) {
        _this2[kStream].destroy(null, function(err) {
            if (err) {
                reject(err);
                return;
            }
            resolve(createIterResult(undefined, true));
        });
    });
}), _Object$setPrototypeO), AsyncIteratorPrototype);
var createReadableStreamAsyncIterator = function createReadableStreamAsyncIterator(stream) {
    var _Object$create;
    var iterator = Object.create(ReadableStreamAsyncIteratorPrototype, (_Object$create = {
    }, _defineProperty(_Object$create, kStream, {
        value: stream,
        writable: true
    }), _defineProperty(_Object$create, kLastResolve, {
        value: null,
        writable: true
    }), _defineProperty(_Object$create, kLastReject, {
        value: null,
        writable: true
    }), _defineProperty(_Object$create, kError, {
        value: null,
        writable: true
    }), _defineProperty(_Object$create, kEnded, {
        value: stream._readableState.endEmitted,
        writable: true
    }), _defineProperty(_Object$create, kHandlePromise, {
        value: function value(resolve, reject) {
            var data = iterator[kStream].read();
            if (data) {
                iterator[kLastPromise] = null;
                iterator[kLastResolve] = null;
                iterator[kLastReject] = null;
                resolve(createIterResult(data, false));
            } else {
                iterator[kLastResolve] = resolve;
                iterator[kLastReject] = reject;
            }
        },
        writable: true
    }), _Object$create));
    iterator[kLastPromise] = null;
    finished(stream, function(err) {
        if (err && err.code !== 'ERR_STREAM_PREMATURE_CLOSE') {
            var reject = iterator[kLastReject]; // reject if we are waiting for data in the Promise
            // returned by next() and store the error
            if (reject !== null) {
                iterator[kLastPromise] = null;
                iterator[kLastResolve] = null;
                iterator[kLastReject] = null;
                reject(err);
            }
            iterator[kError] = err;
            return;
        }
        var resolve = iterator[kLastResolve];
        if (resolve !== null) {
            iterator[kLastPromise] = null;
            iterator[kLastResolve] = null;
            iterator[kLastReject] = null;
            resolve(createIterResult(undefined, true));
        }
        iterator[kEnded] = true;
    });
    stream.on('readable', onReadable.bind(null, iterator));
    return iterator;
};
module.exports = createReadableStreamAsyncIterator;

},{"process":"lDnB8","./end-of-stream":"8Xuxj"}],"8Xuxj":[function(require,module,exports) {
// Ported from https://github.com/mafintosh/end-of-stream with
// permission from the author, Mathias Buus (@mafintosh).
'use strict';
var ERR_STREAM_PREMATURE_CLOSE = require('../../../errors').codes.ERR_STREAM_PREMATURE_CLOSE;
function once(callback) {
    var called = false;
    return function() {
        if (called) return;
        called = true;
        for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++)args[_key] = arguments[_key];
        callback.apply(this, args);
    };
}
function noop() {
}
function isRequest(stream) {
    return stream.setHeader && typeof stream.abort === 'function';
}
function eos(stream, opts, callback) {
    if (typeof opts === 'function') return eos(stream, null, opts);
    if (!opts) opts = {
    };
    callback = once(callback || noop);
    var readable = opts.readable || opts.readable !== false && stream.readable;
    var writable = opts.writable || opts.writable !== false && stream.writable;
    var onlegacyfinish = function onlegacyfinish() {
        if (!stream.writable) onfinish();
    };
    var writableEnded = stream._writableState && stream._writableState.finished;
    var onfinish = function onfinish() {
        writable = false;
        writableEnded = true;
        if (!readable) callback.call(stream);
    };
    var readableEnded = stream._readableState && stream._readableState.endEmitted;
    var onend = function onend() {
        readable = false;
        readableEnded = true;
        if (!writable) callback.call(stream);
    };
    var onerror = function onerror(err) {
        callback.call(stream, err);
    };
    var onclose = function onclose() {
        var err;
        if (readable && !readableEnded) {
            if (!stream._readableState || !stream._readableState.ended) err = new ERR_STREAM_PREMATURE_CLOSE();
            return callback.call(stream, err);
        }
        if (writable && !writableEnded) {
            if (!stream._writableState || !stream._writableState.ended) err = new ERR_STREAM_PREMATURE_CLOSE();
            return callback.call(stream, err);
        }
    };
    var onrequest = function onrequest() {
        stream.req.on('finish', onfinish);
    };
    if (isRequest(stream)) {
        stream.on('complete', onfinish);
        stream.on('abort', onclose);
        if (stream.req) onrequest();
        else stream.on('request', onrequest);
    } else if (writable && !stream._writableState) {
        // legacy streams
        stream.on('end', onlegacyfinish);
        stream.on('close', onlegacyfinish);
    }
    stream.on('end', onend);
    stream.on('finish', onfinish);
    if (opts.error !== false) stream.on('error', onerror);
    stream.on('close', onclose);
    return function() {
        stream.removeListener('complete', onfinish);
        stream.removeListener('abort', onclose);
        stream.removeListener('request', onrequest);
        if (stream.req) stream.req.removeListener('finish', onfinish);
        stream.removeListener('end', onlegacyfinish);
        stream.removeListener('close', onlegacyfinish);
        stream.removeListener('finish', onfinish);
        stream.removeListener('end', onend);
        stream.removeListener('error', onerror);
        stream.removeListener('close', onclose);
    };
}
module.exports = eos;

},{"../../../errors":"fjg3U"}],"hFNof":[function(require,module,exports) {
module.exports = function() {
    throw new Error('Readable.from is not available in the browser');
};

},{}],"lDiiK":[function(require,module,exports) {
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
// a transform stream is a readable/writable stream where you do
// something with the data.  Sometimes it's called a "filter",
// but that's not a great name for it, since that implies a thing where
// some bits pass through, and others are simply ignored.  (That would
// be a valid example of a transform, of course.)
//
// While the output is causally related to the input, it's not a
// necessarily symmetric or synchronous transformation.  For example,
// a zlib stream might take multiple plain-text writes(), and then
// emit a single compressed chunk some time in the future.
//
// Here's how this works:
//
// The Transform stream has all the aspects of the readable and writable
// stream classes.  When you write(chunk), that calls _write(chunk,cb)
// internally, and returns false if there's a lot of pending writes
// buffered up.  When you call read(), that calls _read(n) until
// there's enough pending readable data buffered up.
//
// In a transform stream, the written data is placed in a buffer.  When
// _read(n) is called, it transforms the queued up data, calling the
// buffered _write cb's as it consumes chunks.  If consuming a single
// written chunk would result in multiple output chunks, then the first
// outputted bit calls the readcb, and subsequent chunks just go into
// the read buffer, and will cause it to emit 'readable' if necessary.
//
// This way, back-pressure is actually determined by the reading side,
// since _read has to be called to start processing a new chunk.  However,
// a pathological inflate type of transform can cause excessive buffering
// here.  For example, imagine a stream where every byte of input is
// interpreted as an integer from 0-255, and then results in that many
// bytes of output.  Writing the 4 bytes {ff,ff,ff,ff} would result in
// 1kb of data being output.  In this case, you could write a very small
// amount of input, and end up with a very large amount of output.  In
// such a pathological inflating mechanism, there'd be no way to tell
// the system to stop doing the transform.  A single 4MB write could
// cause the system to run out of memory.
//
// However, even in such a pathological case, only a single written chunk
// would be consumed, and then the rest would wait (un-transformed) until
// the results of the previous transformed chunk were consumed.
'use strict';
module.exports = Transform;
var _require$codes = require('../errors').codes, ERR_METHOD_NOT_IMPLEMENTED = _require$codes.ERR_METHOD_NOT_IMPLEMENTED, ERR_MULTIPLE_CALLBACK = _require$codes.ERR_MULTIPLE_CALLBACK, ERR_TRANSFORM_ALREADY_TRANSFORMING = _require$codes.ERR_TRANSFORM_ALREADY_TRANSFORMING, ERR_TRANSFORM_WITH_LENGTH_0 = _require$codes.ERR_TRANSFORM_WITH_LENGTH_0;
var Duplex = require('./_stream_duplex');
require('inherits')(Transform, Duplex);
function afterTransform(er, data) {
    var ts = this._transformState;
    ts.transforming = false;
    var cb = ts.writecb;
    if (cb === null) return this.emit('error', new ERR_MULTIPLE_CALLBACK());
    ts.writechunk = null;
    ts.writecb = null;
    if (data != null) this.push(data);
    cb(er);
    var rs = this._readableState;
    rs.reading = false;
    if (rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark);
}
function Transform(options) {
    if (!(this instanceof Transform)) return new Transform(options);
    Duplex.call(this, options);
    this._transformState = {
        afterTransform: afterTransform.bind(this),
        needTransform: false,
        transforming: false,
        writecb: null,
        writechunk: null,
        writeencoding: null
    }; // start out asking for a readable event once data is transformed.
    this._readableState.needReadable = true; // we have implemented the _read method, and done the other things
    // that Readable wants before the first _read call, so unset the
    // sync guard flag.
    this._readableState.sync = false;
    if (options) {
        if (typeof options.transform === 'function') this._transform = options.transform;
        if (typeof options.flush === 'function') this._flush = options.flush;
    } // When the writable side finishes, then flush out anything remaining.
    this.on('prefinish', prefinish);
}
function prefinish() {
    var _this = this;
    if (typeof this._flush === 'function' && !this._readableState.destroyed) this._flush(function(er, data) {
        done(_this, er, data);
    });
    else done(this, null, null);
}
Transform.prototype.push = function(chunk, encoding) {
    this._transformState.needTransform = false;
    return Duplex.prototype.push.call(this, chunk, encoding);
}; // This is the part where you do stuff!
// override this function in implementation classes.
// 'chunk' is an input chunk.
//
// Call `push(newChunk)` to pass along transformed output
// to the readable side.  You may call 'push' zero or more times.
//
// Call `cb(err)` when you are done with this chunk.  If you pass
// an error, then that'll put the hurt on the whole operation.  If you
// never call cb(), then you'll never get another chunk.
Transform.prototype._transform = function(chunk, encoding, cb) {
    cb(new ERR_METHOD_NOT_IMPLEMENTED('_transform()'));
};
Transform.prototype._write = function(chunk, encoding, cb) {
    var ts = this._transformState;
    ts.writecb = cb;
    ts.writechunk = chunk;
    ts.writeencoding = encoding;
    if (!ts.transforming) {
        var rs = this._readableState;
        if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark);
    }
}; // Doesn't matter what the args are here.
// _transform does all the work.
// That we got here means that the readable side wants more data.
Transform.prototype._read = function(n) {
    var ts = this._transformState;
    if (ts.writechunk !== null && !ts.transforming) {
        ts.transforming = true;
        this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);
    } else // mark that we need a transform, so that any data that comes in
    // will get processed, now that we've asked for it.
    ts.needTransform = true;
};
Transform.prototype._destroy = function(err, cb) {
    Duplex.prototype._destroy.call(this, err, function(err2) {
        cb(err2);
    });
};
function done(stream, er, data) {
    if (er) return stream.emit('error', er);
    if (data != null) stream.push(data); // TODO(BridgeAR): Write a test for these two error cases
    // if there's nothing in the write buffer, then that means
    // that nothing more will ever be provided
    if (stream._writableState.length) throw new ERR_TRANSFORM_WITH_LENGTH_0();
    if (stream._transformState.transforming) throw new ERR_TRANSFORM_ALREADY_TRANSFORMING();
    return stream.push(null);
}

},{"../errors":"fjg3U","./_stream_duplex":"8XkxS","inherits":"d3hL2"}],"gj76M":[function(require,module,exports) {
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
// a passthrough stream.
// basically just the most minimal sort of Transform stream.
// Every written chunk gets output as-is.
'use strict';
module.exports = PassThrough;
var Transform = require('./_stream_transform');
require('inherits')(PassThrough, Transform);
function PassThrough(options) {
    if (!(this instanceof PassThrough)) return new PassThrough(options);
    Transform.call(this, options);
}
PassThrough.prototype._transform = function(chunk, encoding, cb) {
    cb(null, chunk);
};

},{"./_stream_transform":"lDiiK","inherits":"d3hL2"}],"iNB4a":[function(require,module,exports) {
// Ported from https://github.com/mafintosh/pump with
// permission from the author, Mathias Buus (@mafintosh).
'use strict';
var eos;
function once(callback) {
    var called = false;
    return function() {
        if (called) return;
        called = true;
        callback.apply(void 0, arguments);
    };
}
var _require$codes = require('../../../errors').codes, ERR_MISSING_ARGS = _require$codes.ERR_MISSING_ARGS, ERR_STREAM_DESTROYED = _require$codes.ERR_STREAM_DESTROYED;
function noop(err) {
    // Rethrow the error if it exists to avoid swallowing it
    if (err) throw err;
}
function isRequest(stream) {
    return stream.setHeader && typeof stream.abort === 'function';
}
function destroyer(stream, reading, writing, callback) {
    callback = once(callback);
    var closed = false;
    stream.on('close', function() {
        closed = true;
    });
    if (eos === undefined) eos = require('./end-of-stream');
    eos(stream, {
        readable: reading,
        writable: writing
    }, function(err) {
        if (err) return callback(err);
        closed = true;
        callback();
    });
    var destroyed = false;
    return function(err) {
        if (closed) return;
        if (destroyed) return;
        destroyed = true; // request.destroy just do .end - .abort is what we want
        if (isRequest(stream)) return stream.abort();
        if (typeof stream.destroy === 'function') return stream.destroy();
        callback(err || new ERR_STREAM_DESTROYED('pipe'));
    };
}
function call(fn) {
    fn();
}
function pipe(from, to) {
    return from.pipe(to);
}
function popCallback(streams) {
    if (!streams.length) return noop;
    if (typeof streams[streams.length - 1] !== 'function') return noop;
    return streams.pop();
}
function pipeline() {
    for(var _len = arguments.length, streams = new Array(_len), _key = 0; _key < _len; _key++)streams[_key] = arguments[_key];
    var callback = popCallback(streams);
    if (Array.isArray(streams[0])) streams = streams[0];
    if (streams.length < 2) throw new ERR_MISSING_ARGS('streams');
    var error;
    var destroys = streams.map(function(stream, i) {
        var reading = i < streams.length - 1;
        var writing = i > 0;
        return destroyer(stream, reading, writing, function(err) {
            if (!error) error = err;
            if (err) destroys.forEach(call);
            if (reading) return;
            destroys.forEach(call);
            callback(error);
        });
    });
    return streams.reduce(pipe);
}
module.exports = pipeline;

},{"../../../errors":"fjg3U","./end-of-stream":"8Xuxj"}],"8xgxr":[function(require,module,exports) {
'use strict';
const WriteError = require('level-errors').WriteError;
const catering = require('catering');
const getCallback = require('./common').getCallback;
const getOptions = require('./common').getOptions;
function Batch(levelup) {
    this.db = levelup;
    this.batch = levelup.db.batch();
    this.ops = [];
    this.length = 0;
}
Batch.prototype.put = function(key, value, options) {
    try {
        this.batch.put(key, value, options);
    } catch (e) {
        throw new WriteError(e);
    }
    this.ops.push({
        ...options,
        type: 'put',
        key,
        value
    });
    this.length++;
    return this;
};
Batch.prototype.del = function(key, options) {
    try {
        this.batch.del(key, options);
    } catch (err) {
        throw new WriteError(err);
    }
    this.ops.push({
        ...options,
        type: 'del',
        key
    });
    this.length++;
    return this;
};
Batch.prototype.clear = function() {
    try {
        this.batch.clear();
    } catch (err) {
        throw new WriteError(err);
    }
    this.ops = [];
    this.length = 0;
    return this;
};
Batch.prototype.write = function(options, callback) {
    const levelup = this.db;
    const ops = this.ops;
    callback = getCallback(options, callback);
    callback = catering.fromCallback(callback);
    options = getOptions(options);
    try {
        this.batch.write(options, function(err) {
            if (err) return callback(new WriteError(err));
            levelup.emit('batch', ops);
            callback();
        });
    } catch (err) {
        throw new WriteError(err);
    }
    return callback.promise;
};
module.exports = Batch;

},{"level-errors":"jUsAO","catering":"hpV8E","./common":"3vVgQ"}],"jUsAO":[function(require,module,exports) {
'use strict';
function createError(type, Proto) {
    const Err = function(message, cause) {
        if (typeof message === 'object' && message !== null) {
            // Can be passed just a cause
            cause = cause || message;
            message = message.message || message.name;
        }
        message = message || '';
        cause = cause || undefined;
        // If input is already of type, return as-is to keep its stack trace.
        // Avoid instanceof, for when node_modules has multiple copies of level-errors.
        if (typeof cause === 'object' && cause.type === type && cause.message === message) return cause;
        Object.defineProperty(this, 'type', {
            value: type,
            enumerable: false,
            writable: true,
            configurable: true
        });
        Object.defineProperty(this, 'name', {
            value: type,
            enumerable: false,
            writable: true,
            configurable: true
        });
        Object.defineProperty(this, 'cause', {
            value: cause,
            enumerable: false,
            writable: true,
            configurable: true
        });
        Object.defineProperty(this, 'message', {
            value: message,
            enumerable: false,
            writable: true,
            configurable: true
        });
        Error.call(this);
        if (typeof Error.captureStackTrace === 'function') Error.captureStackTrace(this, Err);
    };
    Err.prototype = new Proto();
    return Err;
}
const LevelUPError = createError('LevelUPError', Error);
module.exports = {
    LevelUPError: LevelUPError,
    InitializationError: createError('InitializationError', LevelUPError),
    OpenError: createError('OpenError', LevelUPError),
    ReadError: createError('ReadError', LevelUPError),
    WriteError: createError('WriteError', LevelUPError),
    NotFoundError: createError('NotFoundError', LevelUPError),
    EncodingError: createError('EncodingError', LevelUPError)
};
module.exports.NotFoundError.prototype.notFound = true;
module.exports.NotFoundError.prototype.status = 404;

},{}],"3vVgQ":[function(require,module,exports) {
'use strict';
exports.getCallback = function(options, callback) {
    return typeof options === 'function' ? options : callback;
};
exports.getOptions = function(options) {
    return typeof options === 'object' && options !== null ? options : {
    };
};

},{}],"63Tpw":[function(require,module,exports) {
'use strict';
const queueMicrotask = require('queue-microtask');
module.exports = function(fn, ...args) {
    if (args.length === 0) queueMicrotask(fn);
    else queueMicrotask(()=>fn(...args)
    );
};

},{"queue-microtask":"9M7Vw"}],"6MJSj":[function(require,module,exports) {
'use strict';
const AbstractLevelDOWN = require('abstract-leveldown').AbstractLevelDOWN;
const AbstractChainedBatch = require('abstract-leveldown').AbstractChainedBatch;
const AbstractIterator = require('abstract-leveldown').AbstractIterator;
const inherits = require('inherits');
const Codec = require('level-codec');
const EncodingError = require('level-errors').EncodingError;
const rangeMethods = [
    'approximateSize',
    'compactRange'
];
module.exports = DB;
function DB(db, opts1) {
    if (!(this instanceof DB)) return new DB(db, opts1);
    const manifest = db.supports || {
    };
    const additionalMethods = manifest.additionalMethods || {
    };
    AbstractLevelDOWN.call(this, manifest);
    this.supports.encodings = true;
    this.supports.additionalMethods = {
    };
    rangeMethods.forEach(function(m) {
        // TODO (future major): remove this fallback
        const fallback = typeof db[m] === 'function';
        if (additionalMethods[m] || fallback) {
            this.supports.additionalMethods[m] = true;
            this[m] = function(start, end, opts, cb) {
                start = this.codec.encodeKey(start, opts);
                end = this.codec.encodeKey(end, opts);
                return this.db[m](start, end, opts, cb);
            };
        }
    }, this);
    opts1 = opts1 || {
    };
    if (typeof opts1.keyEncoding === 'undefined') opts1.keyEncoding = 'utf8';
    if (typeof opts1.valueEncoding === 'undefined') opts1.valueEncoding = 'utf8';
    this.db = db;
    this.codec = new Codec(opts1);
}
inherits(DB, AbstractLevelDOWN);
DB.prototype.type = 'encoding-down';
DB.prototype._serializeKey = DB.prototype._serializeValue = function(datum) {
    return datum;
};
DB.prototype._open = function(opts, cb) {
    this.db.open(opts, cb);
};
DB.prototype._close = function(cb) {
    this.db.close(cb);
};
DB.prototype._put = function(key, value, opts, cb) {
    key = this.codec.encodeKey(key, opts);
    value = this.codec.encodeValue(value, opts);
    this.db.put(key, value, opts, cb);
};
DB.prototype._get = function(key, opts, cb) {
    key = this.codec.encodeKey(key, opts);
    opts.asBuffer = this.codec.valueAsBuffer(opts);
    this.db.get(key, opts, (err, value)=>{
        if (err) return cb(err);
        try {
            value = this.codec.decodeValue(value, opts);
        } catch (err1) {
            return cb(new EncodingError(err1));
        }
        cb(null, value);
    });
};
DB.prototype._getMany = function(keys, opts, cb) {
    keys = keys.map((key)=>this.codec.encodeKey(key, opts)
    );
    opts.asBuffer = this.codec.valueAsBuffer(opts);
    this.db.getMany(keys, opts, (err, values)=>{
        if (err) return cb(err);
        const decoded = new Array(values.length);
        for(let i = 0; i < values.length; i++){
            if (values[i] === undefined) {
                decoded[i] = undefined;
                continue;
            }
            try {
                decoded[i] = this.codec.decodeValue(values[i], opts);
            } catch (err) {
                return cb(new EncodingError(err));
            }
        }
        cb(null, decoded);
    });
};
DB.prototype._del = function(key, opts, cb) {
    key = this.codec.encodeKey(key, opts);
    this.db.del(key, opts, cb);
};
DB.prototype._chainedBatch = function() {
    return new Batch(this);
};
DB.prototype._batch = function(ops, opts, cb) {
    ops = this.codec.encodeBatch(ops, opts);
    this.db.batch(ops, opts, cb);
};
DB.prototype._iterator = function(opts) {
    opts.keyAsBuffer = this.codec.keyAsBuffer(opts);
    opts.valueAsBuffer = this.codec.valueAsBuffer(opts);
    return new Iterator(this, opts);
};
DB.prototype._clear = function(opts, callback) {
    opts = this.codec.encodeLtgt(opts);
    this.db.clear(opts, callback);
};
function Iterator(db, opts) {
    AbstractIterator.call(this, db);
    this.codec = db.codec;
    this.keys = opts.keys;
    this.values = opts.values;
    this.opts = this.codec.encodeLtgt(opts);
    this.it = db.db.iterator(this.opts);
}
inherits(Iterator, AbstractIterator);
Iterator.prototype._next = function(cb) {
    this.it.next((err, key, value)=>{
        if (err) return cb(err);
        try {
            if (this.keys && typeof key !== 'undefined') key = this.codec.decodeKey(key, this.opts);
            else key = undefined;
            if (this.values && typeof value !== 'undefined') value = this.codec.decodeValue(value, this.opts);
            else value = undefined;
        } catch (err2) {
            return cb(new EncodingError(err2));
        }
        cb(null, key, value);
    });
};
Iterator.prototype._seek = function(key) {
    key = this.codec.encodeKey(key, this.opts);
    this.it.seek(key);
};
Iterator.prototype._end = function(cb) {
    this.it.end(cb);
};
function Batch(db, codec) {
    AbstractChainedBatch.call(this, db);
    this.codec = db.codec;
    this.batch = db.db.batch();
}
inherits(Batch, AbstractChainedBatch);
Batch.prototype._put = function(key, value, options) {
    key = this.codec.encodeKey(key, options);
    value = this.codec.encodeValue(value, options);
    this.batch.put(key, value);
};
Batch.prototype._del = function(key, options) {
    key = this.codec.encodeKey(key, options);
    this.batch.del(key);
};
Batch.prototype._clear = function() {
    this.batch.clear();
};
Batch.prototype._write = function(opts, cb) {
    this.batch.write(opts, cb);
};

},{"abstract-leveldown":"jvgwU","inherits":"d3hL2","level-codec":"7rUf0","level-errors":"jUsAO"}],"7rUf0":[function(require,module,exports) {
'use strict';
const encodings = require('./lib/encodings');
const rangeOptions = new Set([
    'lt',
    'gt',
    'lte',
    'gte'
]);
module.exports = Codec;
function Codec(opts) {
    if (!(this instanceof Codec)) return new Codec(opts);
    this.opts = opts || {
    };
    this.encodings = encodings;
}
Codec.prototype._encoding = function(encoding) {
    if (typeof encoding === 'string') encoding = encodings[encoding];
    if (!encoding) encoding = encodings.id;
    return encoding;
};
Codec.prototype._keyEncoding = function(opts, batchOpts) {
    return this._encoding(batchOpts && batchOpts.keyEncoding || opts && opts.keyEncoding || this.opts.keyEncoding);
};
Codec.prototype._valueEncoding = function(opts, batchOpts) {
    return this._encoding(batchOpts && (batchOpts.valueEncoding || batchOpts.encoding) || opts && (opts.valueEncoding || opts.encoding) || this.opts.valueEncoding || this.opts.encoding);
};
Codec.prototype.encodeKey = function(key, opts, batchOpts) {
    return this._keyEncoding(opts, batchOpts).encode(key);
};
Codec.prototype.encodeValue = function(value, opts, batchOpts) {
    return this._valueEncoding(opts, batchOpts).encode(value);
};
Codec.prototype.decodeKey = function(key, opts) {
    return this._keyEncoding(opts).decode(key);
};
Codec.prototype.decodeValue = function(value, opts) {
    return this._valueEncoding(opts).decode(value);
};
Codec.prototype.encodeBatch = function(ops, opts) {
    return ops.map((_op)=>{
        const op = {
            type: _op.type,
            key: this.encodeKey(_op.key, opts, _op)
        };
        if (this.keyAsBuffer(opts, _op)) op.keyEncoding = 'binary';
        if (_op.prefix) op.prefix = _op.prefix;
        if ('value' in _op) {
            op.value = this.encodeValue(_op.value, opts, _op);
            if (this.valueAsBuffer(opts, _op)) op.valueEncoding = 'binary';
        }
        return op;
    });
};
Codec.prototype.encodeLtgt = function(ltgt) {
    const ret = {
    };
    for (const key of Object.keys(ltgt)){
        if (key === 'start' || key === 'end') throw new Error('Legacy range options ("start" and "end") have been removed');
        ret[key] = rangeOptions.has(key) ? this.encodeKey(ltgt[key], ltgt) : ltgt[key];
    }
    return ret;
};
Codec.prototype.createStreamDecoder = function(opts) {
    if (opts.keys && opts.values) return (key, value)=>{
        return {
            key: this.decodeKey(key, opts),
            value: this.decodeValue(value, opts)
        };
    };
    else if (opts.keys) return (key)=>{
        return this.decodeKey(key, opts);
    };
    else if (opts.values) return (_, value)=>{
        return this.decodeValue(value, opts);
    };
    else return function() {
    };
};
Codec.prototype.keyAsBuffer = function(opts) {
    return this._keyEncoding(opts).buffer;
};
Codec.prototype.valueAsBuffer = function(opts) {
    return this._valueEncoding(opts).buffer;
};

},{"./lib/encodings":"2Orcq"}],"2Orcq":[function(require,module,exports) {
'use strict';
const { Buffer  } = require('buffer');
exports.utf8 = exports['utf-8'] = {
    encode: function(data) {
        return isBinary(data) ? data : String(data);
    },
    decode: identity,
    buffer: false,
    type: 'utf8'
};
exports.json = {
    encode: JSON.stringify,
    decode: JSON.parse,
    buffer: false,
    type: 'json'
};
exports.binary = {
    encode: function(data) {
        return isBinary(data) ? data : Buffer.from(data);
    },
    decode: identity,
    buffer: true,
    type: 'binary'
};
exports.none = {
    encode: identity,
    decode: identity,
    buffer: false,
    type: 'id'
};
exports.id = exports.none;
const bufferEncodings = [
    'hex',
    'ascii',
    'base64',
    'ucs2',
    'ucs-2',
    'utf16le',
    'utf-16le'
];
for (const type of bufferEncodings)exports[type] = {
    encode: function(data) {
        return isBinary(data) ? data : Buffer.from(data, type);
    },
    decode: function(buffer) {
        return buffer.toString(type);
    },
    buffer: true,
    type: type
};
function identity(value) {
    return value;
}
function isBinary(data) {
    return data === undefined || data === null || Buffer.isBuffer(data);
}

},{"buffer":"eKea5"}],"klBIM":[function(require,module,exports) {
/* global indexedDB */ 'use strict';
module.exports = Level;
const AbstractLevelDOWN = require('abstract-leveldown').AbstractLevelDOWN;
const inherits = require('inherits');
const parallel = require('run-parallel-limit');
const Iterator = require('./iterator');
const serialize = require('./util/serialize');
const deserialize = require('./util/deserialize');
const support = require('./util/support');
const clear = require('./util/clear');
const createKeyRange = require('./util/key-range');
const DEFAULT_PREFIX = 'level-js-';
function Level(location, opts) {
    if (!(this instanceof Level)) return new Level(location, opts);
    AbstractLevelDOWN.call(this, {
        bufferKeys: support.bufferKeys(indexedDB),
        snapshots: true,
        permanence: true,
        clear: true,
        getMany: true
    });
    opts = opts || {
    };
    if (typeof location !== 'string') throw new Error('constructor requires a location string argument');
    this.location = location;
    this.prefix = opts.prefix == null ? DEFAULT_PREFIX : opts.prefix;
    this.version = parseInt(opts.version || 1, 10);
}
inherits(Level, AbstractLevelDOWN);
Level.prototype.type = 'level-js';
Level.prototype._open = function(options, callback) {
    const req = indexedDB.open(this.prefix + this.location, this.version);
    req.onerror = function() {
        callback(req.error || new Error('unknown error'));
    };
    req.onsuccess = ()=>{
        this.db = req.result;
        callback();
    };
    req.onupgradeneeded = (ev)=>{
        const db = ev.target.result;
        if (!db.objectStoreNames.contains(this.location)) db.createObjectStore(this.location);
    };
};
Level.prototype.store = function(mode) {
    const transaction = this.db.transaction([
        this.location
    ], mode);
    return transaction.objectStore(this.location);
};
Level.prototype.await = function(request, callback) {
    const transaction = request.transaction;
    // Take advantage of the fact that a non-canceled request error aborts
    // the transaction. I.e. no need to listen for "request.onerror".
    transaction.onabort = function() {
        callback(transaction.error || new Error('aborted by user'));
    };
    transaction.oncomplete = function() {
        callback(null, request.result);
    };
};
Level.prototype._get = function(key, options, callback) {
    const store = this.store('readonly');
    let req;
    try {
        req = store.get(key);
    } catch (err1) {
        return this._nextTick(callback, err1);
    }
    this.await(req, function(err, value) {
        if (err) return callback(err);
        if (value === undefined) // 'NotFound' error, consistent with LevelDOWN API
        return callback(new Error('NotFound'));
        callback(null, deserialize(value, options.asBuffer));
    });
};
Level.prototype._getMany = function(keys, options, callback) {
    const asBuffer = options.asBuffer;
    const store = this.store('readonly');
    const tasks = keys.map((key)=>(next)=>{
            let request;
            try {
                request = store.get(key);
            } catch (err) {
                return next(err);
            }
            request.onsuccess = ()=>{
                const value = request.result;
                next(null, value === undefined ? value : deserialize(value, asBuffer));
            };
            request.onerror = (ev)=>{
                ev.stopPropagation();
                next(request.error);
            };
        }
    );
    parallel(tasks, 16, callback);
};
Level.prototype._del = function(key, options, callback) {
    const store = this.store('readwrite');
    let req;
    try {
        req = store.delete(key);
    } catch (err) {
        return this._nextTick(callback, err);
    }
    this.await(req, callback);
};
Level.prototype._put = function(key, value, options, callback) {
    const store = this.store('readwrite');
    let req;
    try {
        // Will throw a DataError or DataCloneError if the environment
        // does not support serializing the key or value respectively.
        req = store.put(value, key);
    } catch (err) {
        return this._nextTick(callback, err);
    }
    this.await(req, callback);
};
Level.prototype._serializeKey = function(key) {
    return serialize(key, this.supports.bufferKeys);
};
Level.prototype._serializeValue = function(value) {
    return serialize(value, true);
};
Level.prototype._iterator = function(options) {
    return new Iterator(this, this.location, options);
};
Level.prototype._batch = function(operations, options, callback) {
    if (operations.length === 0) return this._nextTick(callback);
    const store = this.store('readwrite');
    const transaction = store.transaction;
    let index = 0;
    let error;
    transaction.onabort = function() {
        callback(error || transaction.error || new Error('aborted by user'));
    };
    transaction.oncomplete = function() {
        callback();
    };
    // Wait for a request to complete before making the next, saving CPU.
    function loop() {
        const op = operations[index++];
        const key = op.key;
        let req;
        try {
            req = op.type === 'del' ? store.delete(key) : store.put(op.value, key);
        } catch (err) {
            error = err;
            transaction.abort();
            return;
        }
        if (index < operations.length) req.onsuccess = loop;
    }
    loop();
};
Level.prototype._clear = function(options, callback) {
    let keyRange;
    let req;
    try {
        keyRange = createKeyRange(options);
    } catch (e) {
        // The lower key is greater than the upper key.
        // IndexedDB throws an error, but we'll just do nothing.
        return this._nextTick(callback);
    }
    if (options.limit >= 0) // IDBObjectStore#delete(range) doesn't have such an option.
    // Fall back to cursor-based implementation.
    return clear(this, this.location, keyRange, options, callback);
    try {
        const store = this.store('readwrite');
        req = keyRange ? store.delete(keyRange) : store.clear();
    } catch (err) {
        return this._nextTick(callback, err);
    }
    this.await(req, callback);
};
Level.prototype._close = function(callback) {
    this.db.close();
    this._nextTick(callback);
};
// NOTE: remove in a next major release
Level.prototype.upgrade = function(callback) {
    if (this.status !== 'open') return this._nextTick(callback, new Error('cannot upgrade() before open()'));
    const it = this.iterator();
    const batchOptions = {
    };
    const self = this;
    it._deserializeKey = it._deserializeValue = identity;
    next();
    function next(err) {
        if (err) return finish(err);
        it.next(each);
    }
    function each(err, key, value) {
        if (err || key === undefined) return finish(err);
        const newKey = self._serializeKey(deserialize(key, true));
        const newValue = self._serializeValue(deserialize(value, true));
        // To bypass serialization on the old key, use _batch() instead of batch().
        // NOTE: if we disable snapshotting (#86) this could lead to a loop of
        // inserting and then iterating those same entries, because the new keys
        // possibly sort after the old keys.
        self._batch([
            {
                type: 'del',
                key: key
            },
            {
                type: 'put',
                key: newKey,
                value: newValue
            }
        ], batchOptions, next);
    }
    function finish(err) {
        it.end(function(err2) {
            callback(err || err2);
        });
    }
    function identity(data) {
        return data;
    }
};
Level.destroy = function(location, prefix, callback) {
    if (typeof prefix === 'function') {
        callback = prefix;
        prefix = DEFAULT_PREFIX;
    }
    const request = indexedDB.deleteDatabase(prefix + location);
    request.onsuccess = function() {
        callback();
    };
    request.onerror = function(err) {
        callback(err);
    };
};

},{"abstract-leveldown":"jvgwU","inherits":"d3hL2","run-parallel-limit":"kOqjZ","./iterator":"hPV5s","./util/serialize":"wUGIK","./util/deserialize":"gQaFd","./util/support":"h4ANv","./util/clear":"csz77","./util/key-range":"afsod"}],"kOqjZ":[function(require,module,exports) {
/*! run-parallel-limit. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */ module.exports = runParallelLimit;
const queueMicrotask = require('queue-microtask');
function runParallelLimit(tasks, limit, cb) {
    if (typeof limit !== 'number') throw new Error('second argument must be a Number');
    let results, len, pending, keys, isErrored;
    let isSync = true;
    let next;
    if (Array.isArray(tasks)) {
        results = [];
        pending = len = tasks.length;
    } else {
        keys = Object.keys(tasks);
        results = {
        };
        pending = len = keys.length;
    }
    function done(err) {
        function end() {
            if (cb) cb(err, results);
            cb = null;
        }
        if (isSync) queueMicrotask(end);
        else end();
    }
    function each(i, err1, result1) {
        results[i] = result1;
        if (err1) isErrored = true;
        if (--pending === 0 || err1) done(err1);
        else if (!isErrored && next < len) {
            let key;
            if (keys) {
                key = keys[next];
                next += 1;
                tasks[key](function(err, result) {
                    each(key, err, result);
                });
            } else {
                key = next;
                next += 1;
                tasks[key](function(err, result) {
                    each(key, err, result);
                });
            }
        }
    }
    next = limit;
    if (!pending) // empty
    done(null);
    else if (keys) // object
    keys.some(function(key, i) {
        tasks[key](function(err, result) {
            each(key, err, result);
        });
        if (i === limit - 1) return true // early return
        ;
        return false;
    });
    else // array
    tasks.some(function(task, i) {
        task(function(err, result) {
            each(i, err, result);
        });
        if (i === limit - 1) return true // early return
        ;
        return false;
    });
    isSync = false;
}

},{"queue-microtask":"9M7Vw"}],"hPV5s":[function(require,module,exports) {
'use strict';
const inherits = require('inherits');
const AbstractIterator = require('abstract-leveldown').AbstractIterator;
const createKeyRange = require('./util/key-range');
const deserialize = require('./util/deserialize');
const noop = function() {
};
module.exports = Iterator;
function Iterator(db, location, options) {
    AbstractIterator.call(this, db);
    this._limit = options.limit;
    this._count = 0;
    this._callback = null;
    this._cache = [];
    this._completed = false;
    this._aborted = false;
    this._error = null;
    this._transaction = null;
    this._keys = options.keys;
    this._values = options.values;
    this._keyAsBuffer = options.keyAsBuffer;
    this._valueAsBuffer = options.valueAsBuffer;
    if (this._limit === 0) {
        this._completed = true;
        return;
    }
    let keyRange;
    try {
        keyRange = createKeyRange(options);
    } catch (e) {
        // The lower key is greater than the upper key.
        // IndexedDB throws an error, but we'll just return 0 results.
        this._completed = true;
        return;
    }
    this.createIterator(location, keyRange, options.reverse);
}
inherits(Iterator, AbstractIterator);
Iterator.prototype.createIterator = function(location, keyRange, reverse) {
    const transaction = this.db.db.transaction([
        location
    ], 'readonly');
    const store = transaction.objectStore(location);
    const req = store.openCursor(keyRange, reverse ? 'prev' : 'next');
    req.onsuccess = (ev)=>{
        const cursor = ev.target.result;
        if (cursor) this.onItem(cursor);
    };
    this._transaction = transaction;
    // If an error occurs (on the request), the transaction will abort.
    transaction.onabort = ()=>{
        this.onAbort(this._transaction.error || new Error('aborted by user'));
    };
    transaction.oncomplete = ()=>{
        this.onComplete();
    };
};
Iterator.prototype.onItem = function(cursor) {
    this._cache.push(cursor.key, cursor.value);
    if (this._limit <= 0 || ++this._count < this._limit) cursor.continue();
    this.maybeNext();
};
Iterator.prototype.onAbort = function(err) {
    this._aborted = true;
    this._error = err;
    this.maybeNext();
};
Iterator.prototype.onComplete = function() {
    this._completed = true;
    this.maybeNext();
};
Iterator.prototype.maybeNext = function() {
    if (this._callback) {
        this._next(this._callback);
        this._callback = null;
    }
};
Iterator.prototype._next = function(callback) {
    if (this._aborted) {
        // The error should be picked up by either next() or end().
        const err = this._error;
        this._error = null;
        this._nextTick(callback, err);
    } else if (this._cache.length > 0) {
        let key = this._cache.shift();
        let value = this._cache.shift();
        if (this._keys && key !== undefined) key = this._deserializeKey(key, this._keyAsBuffer);
        else key = undefined;
        if (this._values && value !== undefined) value = this._deserializeValue(value, this._valueAsBuffer);
        else value = undefined;
        this._nextTick(callback, null, key, value);
    } else if (this._completed) this._nextTick(callback);
    else this._callback = callback;
};
// Exposed for the v4 to v5 upgrade utility
Iterator.prototype._deserializeKey = deserialize;
Iterator.prototype._deserializeValue = deserialize;
Iterator.prototype._end = function(callback) {
    if (this._aborted || this._completed) return this._nextTick(callback, this._error);
    // Don't advance the cursor anymore, and the transaction will complete
    // on its own in the next tick. This approach is much cleaner than calling
    // transaction.abort() with its unpredictable event order.
    this.onItem = noop;
    this.onAbort = callback;
    this.onComplete = callback;
};

},{"inherits":"d3hL2","abstract-leveldown":"jvgwU","./util/key-range":"afsod","./util/deserialize":"gQaFd"}],"afsod":[function(require,module,exports) {
/* global IDBKeyRange */ 'use strict';
const ltgt = require('ltgt');
const NONE = Symbol('none');
module.exports = function createKeyRange(options) {
    const lower = ltgt.lowerBound(options, NONE);
    const upper = ltgt.upperBound(options, NONE);
    const lowerOpen = ltgt.lowerBoundExclusive(options, NONE);
    const upperOpen = ltgt.upperBoundExclusive(options, NONE);
    if (lower !== NONE && upper !== NONE) return IDBKeyRange.bound(lower, upper, lowerOpen, upperOpen);
    else if (lower !== NONE) return IDBKeyRange.lowerBound(lower, lowerOpen);
    else if (upper !== NONE) return IDBKeyRange.upperBound(upper, upperOpen);
    else return null;
};

},{"ltgt":"8XLmg"}],"8XLmg":[function(require,module,exports) {
var Buffer = require("buffer").Buffer;
exports.compare = function(a, b) {
    if (Buffer.isBuffer(a)) {
        var l = Math.min(a.length, b.length);
        for(var i = 0; i < l; i++){
            var cmp = a[i] - b[i];
            if (cmp) return cmp;
        }
        return a.length - b.length;
    }
    return a < b ? -1 : a > b ? 1 : 0;
};
// to be compatible with the current abstract-leveldown tests
// nullish or empty strings.
// I could use !!val but I want to permit numbers and booleans,
// if possible.
function isDef(val) {
    return val !== undefined && val !== '';
}
function has(range, name) {
    return Object.hasOwnProperty.call(range, name);
}
function hasKey(range, name) {
    return Object.hasOwnProperty.call(range, name) && name;
}
var lowerBoundKey = exports.lowerBoundKey = function(range) {
    return hasKey(range, 'gt') || hasKey(range, 'gte') || hasKey(range, 'min') || (range.reverse ? hasKey(range, 'end') : hasKey(range, 'start')) || undefined;
};
var lowerBound = exports.lowerBound = function(range, def) {
    var k = lowerBoundKey(range);
    return k ? range[k] : def;
};
var lowerBoundInclusive = exports.lowerBoundInclusive = function(range) {
    return has(range, 'gt') ? false : true;
};
var upperBoundInclusive = exports.upperBoundInclusive = function(range) {
    return has(range, 'lt') ? false : true;
};
var lowerBoundExclusive = exports.lowerBoundExclusive = function(range) {
    return !lowerBoundInclusive(range);
};
var upperBoundExclusive = exports.upperBoundExclusive = function(range) {
    return !upperBoundInclusive(range);
};
var upperBoundKey = exports.upperBoundKey = function(range) {
    return hasKey(range, 'lt') || hasKey(range, 'lte') || hasKey(range, 'max') || (range.reverse ? hasKey(range, 'start') : hasKey(range, 'end')) || undefined;
};
var upperBound = exports.upperBound = function(range, def) {
    var k = upperBoundKey(range);
    return k ? range[k] : def;
};
exports.start = function(range, def) {
    return range.reverse ? upperBound(range, def) : lowerBound(range, def);
};
exports.end = function(range, def) {
    return range.reverse ? lowerBound(range, def) : upperBound(range, def);
};
exports.startInclusive = function(range) {
    return range.reverse ? upperBoundInclusive(range) : lowerBoundInclusive(range);
};
exports.endInclusive = function(range) {
    return range.reverse ? lowerBoundInclusive(range) : upperBoundInclusive(range);
};
function id(e) {
    return e;
}
exports.toLtgt = function(range, _range, map, lower, upper) {
    _range = _range || {
    };
    map = map || id;
    var defaults = arguments.length > 3;
    var lb = exports.lowerBoundKey(range);
    var ub = exports.upperBoundKey(range);
    if (lb) {
        if (lb === 'gt') _range.gt = map(range.gt, false);
        else _range.gte = map(range[lb], false);
    } else if (defaults) _range.gte = map(lower, false);
    if (ub) {
        if (ub === 'lt') _range.lt = map(range.lt, true);
        else _range.lte = map(range[ub], true);
    } else if (defaults) _range.lte = map(upper, true);
    if (range.reverse != null) _range.reverse = !!range.reverse;
    //if range was used mutably
    //(in level-sublevel it's part of an options object
    //that has more properties on it.)
    if (has(_range, 'max')) delete _range.max;
    if (has(_range, 'min')) delete _range.min;
    if (has(_range, 'start')) delete _range.start;
    if (has(_range, 'end')) delete _range.end;
    return _range;
};
exports.contains = function(range, key, compare) {
    compare = compare || exports.compare;
    var lb = lowerBound(range);
    if (isDef(lb)) {
        var cmp = compare(key, lb);
        if (cmp < 0 || cmp === 0 && lowerBoundExclusive(range)) return false;
    }
    var ub = upperBound(range);
    if (isDef(ub)) {
        var cmp = compare(key, ub);
        if (cmp > 0 || cmp === 0 && upperBoundExclusive(range)) return false;
    }
    return true;
};
exports.filter = function(range, compare) {
    return function(key) {
        return exports.contains(range, key, compare);
    };
};

},{"buffer":"eKea5"}],"gQaFd":[function(require,module,exports) {
var global = arguments[3];
'use strict';
const Buffer = require('buffer').Buffer;
const ta2str = function() {
    if (global.TextDecoder) {
        const decoder = new TextDecoder('utf-8');
        return decoder.decode.bind(decoder);
    } else return function ta2str(ta) {
        return ta2buf(ta).toString();
    };
}();
const ab2str = function() {
    if (global.TextDecoder) {
        const decoder = new TextDecoder('utf-8');
        return decoder.decode.bind(decoder);
    } else return function ab2str(ab) {
        return Buffer.from(ab).toString();
    };
}();
function ta2buf(ta) {
    const buf = Buffer.from(ta.buffer);
    if (ta.byteLength === ta.buffer.byteLength) return buf;
    else return buf.slice(ta.byteOffset, ta.byteOffset + ta.byteLength);
}
module.exports = function(data, asBuffer) {
    if (data instanceof Uint8Array) return asBuffer ? ta2buf(data) : ta2str(data);
    else if (data instanceof ArrayBuffer) return asBuffer ? Buffer.from(data) : ab2str(data);
    else return asBuffer ? Buffer.from(String(data)) : String(data);
};

},{"buffer":"eKea5"}],"wUGIK":[function(require,module,exports) {
var global = arguments[3];
'use strict';
const Buffer = require('buffer').Buffer;
// Returns either a Uint8Array or Buffer (doesn't matter to
// IndexedDB, because Buffer is a subclass of Uint8Array)
const str2bin = function() {
    if (global.TextEncoder) {
        const encoder = new TextEncoder('utf-8');
        return encoder.encode.bind(encoder);
    } else return Buffer.from;
}();
module.exports = function(data, asBuffer) {
    if (asBuffer) return Buffer.isBuffer(data) ? data : str2bin(String(data));
    else return String(data);
};

},{"buffer":"eKea5"}],"h4ANv":[function(require,module,exports) {
'use strict';
const Buffer = require('buffer').Buffer;
exports.test = function(key) {
    return function test(impl) {
        try {
            impl.cmp(key, 0);
            return true;
        } catch (err) {
            return false;
        }
    };
};
// Detect binary key support (IndexedDB Second Edition)
exports.bufferKeys = exports.test(Buffer.alloc(0));

},{"buffer":"eKea5"}],"csz77":[function(require,module,exports) {
'use strict';
module.exports = function clear(db, location, keyRange, options, callback) {
    if (options.limit === 0) return db._nextTick(callback);
    const transaction = db.db.transaction([
        location
    ], 'readwrite');
    const store = transaction.objectStore(location);
    let count = 0;
    transaction.oncomplete = function() {
        callback();
    };
    transaction.onabort = function() {
        callback(transaction.error || new Error('aborted by user'));
    };
    // A key cursor is faster (skips reading values) but not supported by IE
    const method = store.openKeyCursor ? 'openKeyCursor' : 'openCursor';
    const direction = options.reverse ? 'prev' : 'next';
    store[method](keyRange, direction).onsuccess = function(ev) {
        const cursor = ev.target.result;
        if (cursor) // Wait for a request to complete before continuing, saving CPU.
        store.delete(cursor.key).onsuccess = function() {
            if (options.limit <= 0 || ++count < options.limit) cursor.continue();
        };
    };
};

},{}],"k8J0L":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var drain = require('it-drain');
var pushable = require('it-pushable');
var key1 = require('interface-datastore/key');
var cid5 = require('multiformats/cid');
var raw = require('multiformats/codecs/raw');
var Digest = require('multiformats/hashes/digest');
var base32 = require('multiformats/bases/base32');
var base58 = require('multiformats/bases/base58');
var errcode = require('err-code');
var base = require('blockstore-core/base');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n['default'] = e;
    return Object.freeze(n);
}
var drain__default = /*#__PURE__*/ _interopDefaultLegacy(drain);
var pushable__default = /*#__PURE__*/ _interopDefaultLegacy(pushable);
var raw__namespace = /*#__PURE__*/ _interopNamespace(raw);
var Digest__namespace = /*#__PURE__*/ _interopNamespace(Digest);
var errcode__default = /*#__PURE__*/ _interopDefaultLegacy(errcode);
function cidToKey(cid$1) {
    const c = cid5.CID.asCID(cid$1);
    if (!c) throw errcode__default['default'](new Error('Not a valid cid'), 'ERR_INVALID_CID');
    return new key1.Key('/' + base32.base32.encode(c.multihash.bytes).slice(1).toUpperCase(), false);
}
function keyToCid(key) {
    return cid5.CID.createV1(raw__namespace.code, Digest__namespace.decode(base32.base32.decode('b' + key.toString().slice(1).toLowerCase())));
}
function convertPrefix(prefix) {
    const firstChar = prefix.substring(0, 1);
    if (firstChar === '/') return convertPrefix(prefix.substring(1));
    let decoder;
    if (firstChar.toLowerCase() === 'b') decoder = (input)=>base32.base32.decode(input.toLowerCase()).subarray(2)
    ;
    else if (firstChar.toLowerCase() === 'c') decoder = (input)=>base32.base32pad.decode(input.toLowerCase()).subarray(2)
    ;
    else if (firstChar === 'z') decoder = (input)=>base58.base58btc.decode(input).subarray(2)
    ;
    else if (firstChar === 'Q') decoder = (input)=>base58.base58btc.decode('z' + input)
    ;
    else decoder = (input)=>base32.base32.decode('b' + input.toLowerCase()).subarray(2)
    ;
    let bytes;
    for(let i = 1; i < prefix.length; i++)try {
        bytes = decoder(prefix.substring(0, i));
    } catch (err) {
        if (err.message !== 'Unexpected end of data') throw err;
    }
    let str = '/C';
    if (bytes) str = `/${base32.base32.encode(bytes).slice(1, -1).toUpperCase() || 'C'}`;
    return str;
}
function convertQuery(query) {
    return {
        ...query,
        prefix: query.prefix ? convertPrefix(query.prefix) : undefined,
        filters: query.filters ? query.filters.map((filter)=>(pair)=>{
                return filter({
                    key: keyToCid(pair.key),
                    value: pair.value
                });
            }
        ) : undefined,
        orders: query.orders ? query.orders.map((order)=>(a, b)=>{
                return order({
                    key: keyToCid(a.key),
                    value: a.value
                }, {
                    key: keyToCid(b.key),
                    value: b.value
                });
            }
        ) : undefined
    };
}
function convertKeyQuery(query) {
    return {
        ...query,
        prefix: query.prefix ? convertPrefix(query.prefix) : undefined,
        filters: query.filters ? query.filters.map((filter)=>(key)=>{
                return filter(keyToCid(key));
            }
        ) : undefined,
        orders: query.orders ? query.orders.map((order)=>(a, b)=>{
                return order(keyToCid(a), keyToCid(b));
            }
        ) : undefined
    };
}
class BlockstoreDatastoreAdapter extends base.BaseBlockstore {
    constructor(datastore){
        super();
        this.child = datastore;
    }
    open() {
        return this.child.open();
    }
    close() {
        return this.child.close();
    }
    async *query(query, options) {
        for await (const { key , value  } of this.child.query(convertQuery(query), options))yield {
            key: keyToCid(key),
            value
        };
    }
    async *queryKeys(query1, options1) {
        for await (const key of this.child.queryKeys(convertKeyQuery(query1), options1))yield keyToCid(key);
    }
    async get(cid1, options2) {
        return this.child.get(cidToKey(cid1), options2);
    }
    async *getMany(cids, options3) {
        for await (const cid of cids)yield this.get(cid, options3);
    }
    async put(cid2, value, options4) {
        await this.child.put(cidToKey(cid2), value, options4);
    }
    async *putMany(blocks, options5) {
        const output = pushable__default['default']();
        const runner = globalThis.process && globalThis.process.nextTick ? globalThis.process.nextTick : globalThis.setImmediate || globalThis.setTimeout;
        runner(async ()=>{
            try {
                const store = this.child;
                await drain__default['default'](this.child.putMany(async function*() {
                    for await (const block of blocks){
                        const key = cidToKey(block.key);
                        const exists = await store.has(key, options5);
                        if (!exists) yield {
                            key,
                            value: block.value
                        };
                        output.push(block);
                    }
                }()));
                output.end();
            } catch (err) {
                output.end(err);
            }
        });
        yield* output;
    }
    has(cid3, options6) {
        return this.child.has(cidToKey(cid3), options6);
    }
    delete(cid4, options7) {
        return this.child.delete(cidToKey(cid4), options7);
    }
    deleteMany(cids1, options8) {
        const out = pushable__default['default']();
        drain__default['default'](this.child.deleteMany(async function*() {
            for await (const cid of cids1){
                yield cidToKey(cid);
                out.push(cid);
            }
            out.end();
        }(), options8)).catch((err)=>{
            out.end(err);
        });
        return out;
    }
}
exports.BlockstoreDatastoreAdapter = BlockstoreDatastoreAdapter;

},{"it-drain":"h63K2","it-pushable":"hRi4l","interface-datastore/key":"ccQWS","multiformats/cid":"fJJnW","multiformats/codecs/raw":"dkcyY","multiformats/hashes/digest":"fkA58","multiformats/bases/base32":"63xDB","multiformats/bases/base58":"6Rnqi","err-code":"eQvyh","blockstore-core/base":"ajjJw"}],"ajjJw":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var drain = require('it-drain');
var filter = require('it-filter');
var take = require('it-take');
var all = require('it-all');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var drain__default = /*#__PURE__*/ _interopDefaultLegacy(drain);
var filter__default = /*#__PURE__*/ _interopDefaultLegacy(filter);
var take__default = /*#__PURE__*/ _interopDefaultLegacy(take);
var all__default = /*#__PURE__*/ _interopDefaultLegacy(all);
const sortAll = (iterable, sorter)=>{
    return (async function*() {
        const values = await all__default['default'](iterable);
        yield* values.sort(sorter);
    })();
};
class BaseBlockstore {
    open() {
        return Promise.reject(new Error('.open is not implemented'));
    }
    close() {
        return Promise.reject(new Error('.close is not implemented'));
    }
    put(key4, val, options7) {
        return Promise.reject(new Error('.put is not implemented'));
    }
    get(key1, options1) {
        return Promise.reject(new Error('.get is not implemented'));
    }
    has(key2, options2) {
        return Promise.reject(new Error('.has is not implemented'));
    }
    delete(key3, options3) {
        return Promise.reject(new Error('.delete is not implemented'));
    }
    async *putMany(source, options4 = {
    }) {
        for await (const { key , value  } of source){
            await this.put(key, value, options4);
            yield {
                key,
                value
            };
        }
    }
    async *getMany(source1, options5 = {
    }) {
        for await (const key of source1)yield this.get(key, options5);
    }
    async *deleteMany(source2, options6 = {
    }) {
        for await (const key of source2){
            await this.delete(key, options6);
            yield key;
        }
    }
    batch() {
        let puts = [];
        let dels = [];
        return {
            put (key, value) {
                puts.push({
                    key,
                    value
                });
            },
            delete (key) {
                dels.push(key);
            },
            commit: async (options)=>{
                await drain__default['default'](this.putMany(puts, options));
                puts = [];
                await drain__default['default'](this.deleteMany(dels, options));
                dels = [];
            }
        };
    }
    async *_all(q, options) {
        throw new Error('._all is not implemented');
    }
    async *_allKeys(q1, options8) {
        throw new Error('._allKeys is not implemented');
    }
    query(q2, options9) {
        let it1 = this._all(q2, options9);
        if (q2.prefix != null) it1 = filter__default['default'](it1, (e)=>e.key.toString().startsWith(q2.prefix || '')
        );
        if (Array.isArray(q2.filters)) it1 = q2.filters.reduce((it, f)=>filter__default['default'](it, f)
        , it1);
        if (Array.isArray(q2.orders)) it1 = q2.orders.reduce((it, f)=>sortAll(it, f)
        , it1);
        if (q2.offset != null) {
            let i = 0;
            it1 = filter__default['default'](it1, ()=>(i++) >= (q2.offset || 0)
            );
        }
        if (q2.limit != null) it1 = take__default['default'](it1, q2.limit);
        return it1;
    }
    queryKeys(q3, options10) {
        let it2 = this._allKeys(q3, options10);
        if (q3.prefix != null) it2 = filter__default['default'](it2, (cid)=>cid.toString().startsWith(q3.prefix || '')
        );
        if (Array.isArray(q3.filters)) it2 = q3.filters.reduce((it, f)=>filter__default['default'](it, f)
        , it2);
        if (Array.isArray(q3.orders)) it2 = q3.orders.reduce((it, f)=>sortAll(it, f)
        , it2);
        if (q3.offset != null) {
            let i = 0;
            it2 = filter__default['default'](it2, ()=>(i++) >= q3.offset
            );
        }
        if (q3.limit != null) it2 = take__default['default'](it2, q3.limit);
        return it2;
    }
}
exports.BaseBlockstore = BaseBlockstore;

},{"it-drain":"h63K2","it-filter":"7NtwB","it-take":"8hPk7","it-all":"hynpN"}],"78HPV":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var get = require('dlv');
var mergeOpts = require('merge-options');
var errCode = require('err-code');
var libp2pPubsubRouters = require('ipfs-core-config/libp2p-pubsub-routers');
var DelegatedPeerRouter = require('libp2p-delegated-peer-routing');
var DelegatedContentRouter = require('libp2p-delegated-content-routing');
var ipfsHttpClient = require('ipfs-http-client');
var multiaddr = require('multiaddr');
var version = require('../version.js');
var libp2p = require('ipfs-core-config/libp2p');
var bootstrap = require('libp2p-bootstrap');
var Libp2p = require('libp2p');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var get__default = /*#__PURE__*/ _interopDefaultLegacy(get);
var mergeOpts__default = /*#__PURE__*/ _interopDefaultLegacy(mergeOpts);
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
var DelegatedPeerRouter__default = /*#__PURE__*/ _interopDefaultLegacy(DelegatedPeerRouter);
var DelegatedContentRouter__default = /*#__PURE__*/ _interopDefaultLegacy(DelegatedContentRouter);
var bootstrap__default = /*#__PURE__*/ _interopDefaultLegacy(bootstrap);
var Libp2p__default = /*#__PURE__*/ _interopDefaultLegacy(Libp2p);
const mergeOptions = mergeOpts__default['default'].bind({
    ignoreUndefined: true
});
function createLibp2p({ options ={
} , peerId , multiaddrs =[] , repo , keychainConfig ={
} , config ={
}  }) {
    const { datastore , keys  } = repo;
    const libp2pOptions = getLibp2pOptions({
        options,
        config,
        datastore,
        keys,
        keychainConfig,
        peerId,
        multiaddrs
    });
    if (typeof options.libp2p === 'function') return options.libp2p({
        libp2pOptions,
        options,
        config,
        datastore,
        peerId
    });
    return Libp2p__default['default'].create(libp2pOptions);
}
function getLibp2pOptions({ options , config , datastore , keys , keychainConfig , peerId , multiaddrs  }) {
    const getPubsubRouter = ()=>{
        const router = get__default['default'](config, 'Pubsub.Router') || 'gossipsub';
        if (!libp2pPubsubRouters.routers[router]) throw errCode__default['default'](new Error(`Router unavailable. Configure libp2p.modules.pubsub to use the ${router} router.`), 'ERR_NOT_SUPPORTED');
        return libp2pPubsubRouters.routers[router];
    };
    const libp2pDefaults = {
        datastore,
        peerId: peerId,
        modules: {
        }
    };
    const libp2pOptions = {
        modules: {
            pubsub: getPubsubRouter(),
            contentRouting: [],
            peerRouting: []
        },
        config: {
            peerDiscovery: {
                mdns: {
                    enabled: get__default['default'](options, 'config.Discovery.MDNS.Enabled', get__default['default'](config, 'Discovery.MDNS.Enabled', true))
                },
                webRTCStar: {
                    enabled: get__default['default'](options, 'config.Discovery.webRTCStar.Enabled', get__default['default'](config, 'Discovery.webRTCStar.Enabled', true))
                },
                bootstrap: {
                    list: get__default['default'](options, 'config.Bootstrap', get__default['default'](config, 'Bootstrap', []))
                }
            },
            relay: {
                enabled: get__default['default'](options, 'relay.enabled', get__default['default'](config, 'relay.enabled', true)),
                hop: {
                    enabled: get__default['default'](options, 'relay.hop.enabled', get__default['default'](config, 'relay.hop.enabled', false)),
                    active: get__default['default'](options, 'relay.hop.active', get__default['default'](config, 'relay.hop.active', false))
                }
            },
            dht: {
                enabled: get__default['default'](config, 'Routing.Type', 'none') !== 'none',
                clientMode: get__default['default'](config, 'Routing.Type', 'dht') !== 'dhtserver',
                kBucketSize: get__default['default'](options, 'dht.kBucketSize', 20)
            },
            pubsub: {
                enabled: get__default['default'](options, 'config.Pubsub.Enabled', get__default['default'](config, 'Pubsub.Enabled', true))
            },
            nat: {
                enabled: !get__default['default'](config, 'Swarm.DisableNatPortMap', false)
            }
        },
        addresses: {
            listen: multiaddrs.map((ma)=>ma.toString()
            ),
            announce: get__default['default'](options, 'addresses.announce', get__default['default'](config, 'Addresses.Announce', [])),
            noAnnounce: get__default['default'](options, 'addresses.noAnnounce', get__default['default'](config, 'Addresses.NoAnnounce', []))
        },
        connectionManager: get__default['default'](options, 'connectionManager', {
            maxConnections: get__default['default'](options, 'config.Swarm.ConnMgr.HighWater', get__default['default'](config, 'Swarm.ConnMgr.HighWater')),
            minConnections: get__default['default'](options, 'config.Swarm.ConnMgr.LowWater', get__default['default'](config, 'Swarm.ConnMgr.LowWater'))
        }),
        keychain: {
            datastore: keys,
            ...keychainConfig
        },
        host: {
            agentVersion: `js-ipfs/${version.ipfsCore}`
        }
    };
    let constructorOptions = get__default['default'](options, 'libp2p', undefined);
    if (typeof constructorOptions === 'function') constructorOptions = undefined;
    const libp2pConfig = mergeOptions(libp2pDefaults, libp2p.libp2pConfig(), libp2pOptions, constructorOptions);
    const bootstrapList = get__default['default'](libp2pConfig, 'config.peerDiscovery.bootstrap.list', []);
    if (bootstrapList.length > 0) libp2pConfig.modules.peerDiscovery.push(bootstrap__default['default']);
    const delegateHosts = get__default['default'](options, 'config.Addresses.Delegates', get__default['default'](config, 'Addresses.Delegates', []));
    if (delegateHosts.length > 0) {
        const delegateString = delegateHosts[Math.floor(Math.random() * delegateHosts.length)];
        const delegateAddr = new multiaddr.Multiaddr(delegateString).toOptions();
        const delegateApiOptions = {
            host: delegateAddr.host,
            protocol: parseInt(delegateAddr.port) === 443 ? 'https' : 'http',
            port: delegateAddr.port
        };
        const delegateHttpClient = ipfsHttpClient.create(delegateApiOptions);
        libp2pOptions.modules.contentRouting = libp2pOptions.modules.contentRouting || [];
        libp2pOptions.modules.contentRouting.push(new DelegatedContentRouter__default['default'](peerId, delegateHttpClient));
        libp2pOptions.modules.peerRouting = libp2pOptions.modules.peerRouting || [];
        libp2pOptions.modules.peerRouting.push(new DelegatedPeerRouter__default['default'](delegateHttpClient));
    }
    return libp2pConfig;
}
exports.createLibp2p = createLibp2p;

},{"dlv":"3eBmB","merge-options":"8VjFj","err-code":"eQvyh","ipfs-core-config/libp2p-pubsub-routers":"5GwdK","libp2p-delegated-peer-routing":"3cVss","libp2p-delegated-content-routing":"4OlJb","ipfs-http-client":"7FTpC","multiaddr":"kOPrF","../version.js":"7iiYH","ipfs-core-config/libp2p":"bANS0","libp2p-bootstrap":"lAx0u","libp2p":"1VuOh"}],"5GwdK":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var GossipSub = require('libp2p-gossipsub');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var GossipSub__default = /*#__PURE__*/ _interopDefaultLegacy(GossipSub);
const routers = {
    gossipsub: GossipSub__default["default"]
};
exports.routers = routers;

},{"libp2p-gossipsub":"4HG11"}],"4HG11":[function(require,module,exports) {
"use strict";
var __createBinding = this && this.__createBinding || (Object.create ? function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    Object.defineProperty(o, k2, {
        enumerable: true,
        get: function() {
            return m[k];
        }
    });
} : function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
});
var __setModuleDefault = this && this.__setModuleDefault || (Object.create ? function(o, v) {
    Object.defineProperty(o, "default", {
        enumerable: true,
        value: v
    });
} : function(o, v) {
    o["default"] = v;
});
var __importStar = this && this.__importStar || function(mod) {
    if (mod && mod.__esModule) return mod;
    var result = {
    };
    if (mod != null) {
        for(var k in mod)if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    }
    __setModuleDefault(result, mod);
    return result;
};
var __awaiter = this && this.__awaiter || function(thisArg, _arguments, P, generator) {
    function adopt(value) {
        return value instanceof P ? value : new P(function(resolve) {
            resolve(value);
        });
    }
    return new (P || (P = Promise))(function(resolve, reject) {
        function fulfilled(value) {
            try {
                step(generator.next(value));
            } catch (e) {
                reject(e);
            }
        }
        function rejected(value) {
            try {
                step(generator["throw"](value));
            } catch (e) {
                reject(e);
            }
        }
        function step(result) {
            result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
        }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
const pubsub_1 = __importStar(require("libp2p-interfaces/src/pubsub"));
const message_cache_1 = require("./message-cache");
const rpc_1 = require("./message/rpc");
const constants = __importStar(require("./constants"));
const heartbeat_1 = require("./heartbeat");
const get_gossip_peers_1 = require("./get-gossip-peers");
const utils_1 = require("./utils");
const score_1 = require("./score");
const tracer_1 = require("./tracer");
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const TimeCache = require("time-cache");
const PeerId = require("peer-id");
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const Envelope = require("libp2p/src/record/envelope");
class Gossipsub extends pubsub_1.default {
    // TODO: add remaining props
    /**
     * @param {Libp2p} libp2p
     * @param {Object} [options]
     * @param {boolean} [options.emitSelf = false] if publish should emit to self, if subscribed
     * @param {boolean} [options.canRelayMessage = false] - if can relay messages not subscribed
     * @param {boolean} [options.gossipIncoming = true] if incoming messages on a subscribed topic should be automatically gossiped
     * @param {boolean} [options.fallbackToFloodsub = true] if dial should fallback to floodsub
     * @param {boolean} [options.floodPublish = true] if self-published messages should be sent to all peers
     * @param {boolean} [options.doPX = false] whether PX is enabled; this should be enabled in bootstrappers and other well connected/trusted nodes.
     * @param {Object} [options.messageCache] override the default MessageCache
     * @param {string} [options.globalSignaturePolicy = "StrictSign"] signing policy to apply across all messages
     * @param {Object} [options.scoreParams] peer score parameters
     * @param {Object} [options.scoreThresholds] peer score thresholds
     * @param {AddrInfo[]} [options.directPeers] peers with which we will maintain direct connections
     * @constructor
     */ constructor(libp2p, options = {
    }){
        const multicodecs = [
            constants.GossipsubIDv11,
            constants.GossipsubIDv10
        ];
        const opts = Object.assign(Object.assign({
            gossipIncoming: true,
            fallbackToFloodsub: true,
            floodPublish: true,
            doPX: false,
            directPeers: [],
            D: constants.GossipsubD,
            Dlo: constants.GossipsubDlo,
            Dhi: constants.GossipsubDhi,
            Dscore: constants.GossipsubDscore,
            Dout: constants.GossipsubDout,
            Dlazy: constants.GossipsubDlazy,
            heartbeatInterval: constants.GossipsubHeartbeatInterval,
            fanoutTTL: constants.GossipsubFanoutTTL,
            mcacheLength: constants.GossipsubHistoryLength,
            mcacheGossip: constants.GossipsubHistoryGossip,
            seenTTL: constants.GossipsubSeenTTL
        }, options), {
            scoreParams: score_1.createPeerScoreParams(options.scoreParams),
            scoreThresholds: score_1.createPeerScoreThresholds(options.scoreThresholds)
        });
        // Also wants to get notified of peers connected using floodsub
        if (opts.fallbackToFloodsub) multicodecs.push(constants.FloodsubID);
        super(Object.assign({
            debugName: 'libp2p:gossipsub',
            multicodecs,
            libp2p
        }, opts));
        this._options = opts;
        /**
         * Direct peers
         * @type {Set<string>}
         */ this.direct = new Set(opts.directPeers.map((p)=>p.id.toB58String()
        ));
        // set direct peer addresses in the address book
        opts.directPeers.forEach((p)=>{
            libp2p.peerStore.addressBook.add(p.id, p.addrs);
        });
        /**
         * Cache of seen messages
         *
         * @type {TimeCache}
         */ this.seenCache = new TimeCache({
            validity: opts.seenTTL / 1000
        });
        /**
         * Map of topic meshes
         * topic => peer id set
         *
         * @type {Map<string, Set<string>>}
         */ this.mesh = new Map();
        /**
         * Map of topics to set of peers. These mesh peers are the ones to which we are publishing without a topic membership
         * topic => peer id set
         *
         * @type {Map<string, Set<string>>}
         */ this.fanout = new Map();
        /**
         * Map of last publish time for fanout topics
         * topic => last publish time
         *
         * @type {Map<string, number>}
         */ this.lastpub = new Map();
        /**
         * Map of pending messages to gossip
         * peer id => control messages
         *
         * @type {Map<string, Array<RPC.IControlIHave object>> }
         */ this.gossip = new Map();
        /**
         * Map of control messages
         * peer id => control message
         *
         * @type {Map<string, RPC.IControlMessage object>}
         */ this.control = new Map();
        /**
         * Number of IHAVEs received from peer in the last heartbeat
         * @type {Map<string, number>}
         */ this.peerhave = new Map();
        /**
         * Number of messages we have asked from peer in the last heartbeat
         * @type {Map<string, number>}
         */ this.iasked = new Map();
        /**
         * Prune backoff map
         */ this.backoff = new Map();
        /**
         * Connection direction cache, marks peers with outbound connections
         * peer id => direction
         *
         * @type {Map<string, boolean>}
         */ this.outbound = new Map();
        /**
         * A message cache that contains the messages for last few hearbeat ticks
         *
         */ this.messageCache = options.messageCache || new message_cache_1.MessageCache(opts.mcacheGossip, opts.mcacheLength, this.getMsgId.bind(this));
        /**
         * A heartbeat timer that maintains the mesh
         */ this.heartbeat = new heartbeat_1.Heartbeat(this);
        /**
         * Number of heartbeats since the beginning of time
         * This allows us to amortize some resource cleanup -- eg: backoff cleanup
         */ this.heartbeatTicks = 0;
        /**
         * Tracks IHAVE/IWANT promises broken by peers
         */ this.gossipTracer = new tracer_1.IWantTracer(this.getMsgId.bind(this));
        /**
         * libp2p
         */ this._libp2p = libp2p;
        /**
         * Peer score tracking
         */ this.score = new score_1.PeerScore(this._options.scoreParams, libp2p.connectionManager, this.getMsgId.bind(this));
    }
    /**
     * Decode a Uint8Array into an RPC object
     * Overrided to use an extended protocol-specific protobuf decoder
     * @override
     * @param {Uint8Array} bytes
     * @returns {RPC}
     */ _decodeRpc(bytes) {
        return rpc_1.RPC.decode(bytes);
    }
    /**
     * Encode an RPC object into a Uint8Array
     * Overrided to use an extended protocol-specific protobuf encoder
     * @override
     * @param {RPC} rpc
     * @returns {Uint8Array}
     */ _encodeRpc(rpc2) {
        return rpc_1.RPC.encode(rpc2).finish();
    }
    /**
     * Add a peer to the router
     * @override
     * @param {PeerId} peerId
     * @param {string} protocol
     * @returns {PeerStreams}
     */ _addPeer(peerId2, protocol) {
        const p = super._addPeer(peerId2, protocol);
        // Add to peer scoring
        this.score.addPeer(peerId2.toB58String());
        // track the connection direction
        let outbound = false;
        for (const c of this._libp2p.connectionManager.getAll(peerId2)){
            if (c.stat.direction === 'outbound') {
                if (Array.from(c.registry.values()).some((rvalue)=>protocol === rvalue.protocol
                )) {
                    outbound = true;
                    break;
                }
            }
        }
        this.outbound.set(p.id.toB58String(), outbound);
        return p;
    }
    /**
     * Removes a peer from the router
     * @override
     * @param {PeerId} peer
     * @returns {PeerStreams | undefined}
     */ _removePeer(peerId1) {
        const peerStreams = super._removePeer(peerId1);
        const id = peerId1.toB58String();
        // Remove this peer from the mesh
        // eslint-disable-next-line no-unused-vars
        for (const peers of this.mesh.values())peers.delete(id);
        // Remove this peer from the fanout
        // eslint-disable-next-line no-unused-vars
        for (const peers1 of this.fanout.values())peers1.delete(id);
        // Remove from gossip mapping
        this.gossip.delete(id);
        // Remove from control mapping
        this.control.delete(id);
        // Remove from backoff mapping
        this.outbound.delete(id);
        // Remove from peer scoring
        this.score.removePeer(id);
        return peerStreams;
    }
    /**
     * Handles an rpc request from a peer
     *
     * @override
     * @param {String} idB58Str
     * @param {PeerStreams} peerStreams
     * @param {RPC} rpc
     * @returns {Promise<boolean>}
     */ _processRpc(id9, peerStreams1, rpc1) {
        const _super = Object.create(null, {
            _processRpc: {
                get: ()=>super._processRpc
            }
        });
        return __awaiter(this, void 0, void 0, function*() {
            if (yield _super._processRpc.call(this, id9, peerStreams1, rpc1)) {
                if (rpc1.control) this._processRpcControlMessage(id9, rpc1.control);
                return true;
            }
            return false;
        });
    }
    /**
     * Handles an rpc control message from a peer
     * @param {string} id peer id
     * @param {RPC.IControlMessage} controlMsg
     * @returns {void}
     */ _processRpcControlMessage(id1, controlMsg) {
        if (!controlMsg) return;
        const iwant = controlMsg.ihave ? this._handleIHave(id1, controlMsg.ihave) : [];
        const ihave = controlMsg.iwant ? this._handleIWant(id1, controlMsg.iwant) : [];
        const prune = controlMsg.graft ? this._handleGraft(id1, controlMsg.graft) : [];
        controlMsg.prune && this._handlePrune(id1, controlMsg.prune);
        if (!iwant.length && !ihave.length && !prune.length) return;
        const outRpc = utils_1.createGossipRpc(ihave, {
            iwant,
            prune
        });
        this._sendRpc(id1, outRpc);
    }
    /**
     * Process incoming message,
     * emitting locally and forwarding on to relevant floodsub and gossipsub peers
     * @override
     * @param {InMessage} msg
     * @returns {Promise<void>}
     */ _processRpcMessage(msg1) {
        const _super = Object.create(null, {
            _processRpcMessage: {
                get: ()=>super._processRpcMessage
            }
        });
        return __awaiter(this, void 0, void 0, function*() {
            const msgID = yield this.getMsgId(msg1);
            const msgIdStr = utils_1.messageIdToString(msgID);
            // Ignore if we've already seen the message
            if (this.seenCache.has(msgIdStr)) {
                this.score.duplicateMessage(msg1);
                return;
            }
            this.seenCache.put(msgIdStr);
            yield this.score.validateMessage(msg1);
            yield _super._processRpcMessage.call(this, msg1);
        });
    }
    /**
     * Whether to accept a message from a peer
     * @override
     * @param {string} id
     * @returns {boolean}
     */ _acceptFrom(id2) {
        return this.direct.has(id2) || this.score.score(id2) >= this._options.scoreThresholds.graylistThreshold;
    }
    /**
     * Validate incoming message
     * @override
     * @param {InMessage} message
     * @returns {Promise<void>}
     */ validate(message) {
        const _super = Object.create(null, {
            validate: {
                get: ()=>super.validate
            }
        });
        return __awaiter(this, void 0, void 0, function*() {
            try {
                yield _super.validate.call(this, message);
            } catch (e) {
                this.score.rejectMessage(message, e.code);
                this.gossipTracer.rejectMessage(message, e.code);
                throw e;
            }
        });
    }
    /**
     * Handles IHAVE messages
     * @param {string} id peer id
     * @param {Array<RPC.IControlIHave>} ihave
     * @returns {RPC.IControlIWant}
     */ _handleIHave(id3, ihave) {
        if (!ihave.length) return [];
        // we ignore IHAVE gossip from any peer whose score is below the gossips threshold
        const score = this.score.score(id3);
        if (score < this._options.scoreThresholds.gossipThreshold) {
            this.log('IHAVE: ignoring peer %s with score below threshold [ score = %d ]', id3, score);
            return [];
        }
        // IHAVE flood protection
        const peerhave = (this.peerhave.get(id3) || 0) + 1;
        this.peerhave.set(id3, peerhave);
        if (peerhave > constants.GossipsubMaxIHaveMessages) {
            this.log('IHAVE: peer %s has advertised too many times (%d) within this heartbeat interval; ignoring', id3, peerhave);
            return [];
        }
        const iasked = this.iasked.get(id3) || 0;
        if (iasked >= constants.GossipsubMaxIHaveLength) {
            this.log('IHAVE: peer %s has already advertised too many messages (%d); ignoring', id3, iasked);
            return [];
        }
        // string msgId => msgId
        const iwant = new Map();
        ihave.forEach(({ topicID , messageIDs  })=>{
            if (!topicID || !messageIDs || !this.mesh.has(topicID)) return;
            messageIDs.forEach((msgID)=>{
                const msgIdStr = utils_1.messageIdToString(msgID);
                if (this.seenCache.has(msgIdStr)) return;
                iwant.set(msgIdStr, msgID);
            });
        });
        if (!iwant.size) return [];
        let iask = iwant.size;
        if (iask + iasked > constants.GossipsubMaxIHaveLength) iask = constants.GossipsubMaxIHaveLength - iasked;
        this.log('IHAVE: Asking for %d out of %d messages from %s', iask, iwant.size, id3);
        let iwantList = Array.from(iwant.values());
        // ask in random order
        utils_1.shuffle(iwantList);
        // truncate to the messages we are actually asking for and update the iasked counter
        iwantList = iwantList.slice(0, iask);
        this.iasked.set(id3, iasked + iask);
        this.gossipTracer.addPromise(id3, iwantList);
        return [
            {
                messageIDs: iwantList
            }
        ];
    }
    /**
     * Handles IWANT messages
     * Returns messages to send back to peer
     * @param {string} id peer id
     * @param {Array<RPC.IControlIWant>} iwant
     * @returns {Array<RPC.IMessage>}
     */ _handleIWant(id4, iwant) {
        if (!iwant.length) return [];
        // we don't respond to IWANT requests from any per whose score is below the gossip threshold
        const score = this.score.score(id4);
        if (score < this._options.scoreThresholds.gossipThreshold) {
            this.log('IWANT: ignoring peer %s with score below threshold [score = %d]', id4, score);
            return [];
        }
        // @type {Map<string, Message>}
        const ihave = new Map();
        iwant.forEach(({ messageIDs  })=>{
            messageIDs && messageIDs.forEach((msgID)=>{
                const [msg, count] = this.messageCache.getForPeer(msgID, id4);
                if (!msg) return;
                if (count > constants.GossipsubGossipRetransmission) {
                    this.log('IWANT: Peer %s has asked for message %s too many times: ignoring request', id4, msgID);
                    return;
                }
                ihave.set(utils_1.messageIdToString(msgID), msg);
            });
        });
        if (!ihave.size) return [];
        this.log('IWANT: Sending %d messages to %s', ihave.size, id4);
        return Array.from(ihave.values()).map(pubsub_1.utils.normalizeOutRpcMessage);
    }
    /**
     * Handles Graft messages
     * @param {string} id peer id
     * @param {Array<RPC.IControlGraft>} graft
     * @return {Array<RPC.IControlPrune>}
     */ _handleGraft(id5, graft) {
        const prune = [];
        const score = this.score.score(id5);
        const now = this._now();
        let doPX = this._options.doPX;
        graft.forEach(({ topicID  })=>{
            var _a;
            if (!topicID) return;
            const peersInMesh = this.mesh.get(topicID);
            if (!peersInMesh) {
                // don't do PX when there is an unknown topic to avoid leaking our peers
                doPX = false;
                // spam hardening: ignore GRAFTs for unknown topics
                return;
            }
            // check if peer is already in the mesh; if so do nothing
            if (peersInMesh.has(id5)) return;
            // we don't GRAFT to/from direct peers; complain loudly if this happens
            if (this.direct.has(id5)) {
                this.log('GRAFT: ignoring request from direct peer %s', id5);
                // this is possibly a bug from a non-reciprical configuration; send a PRUNE
                prune.push(topicID);
                // but don't px
                doPX = false;
                return;
            }
            // make sure we are not backing off that peer
            const expire = (_a = this.backoff.get(topicID)) === null || _a === void 0 ? void 0 : _a.get(id5);
            if (typeof expire === 'number' && now < expire) {
                this.log('GRAFT: ignoring backed off peer %s', id5);
                // add behavioral penalty
                this.score.addPenalty(id5, 1);
                // no PX
                doPX = false;
                // check the flood cutoff -- is the GRAFT coming too fast?
                const floodCutoff = expire + constants.GossipsubGraftFloodThreshold - constants.GossipsubPruneBackoff;
                if (now < floodCutoff) // extra penalty
                this.score.addPenalty(id5, 1);
                // refresh the backoff
                this._addBackoff(id5, topicID);
                prune.push(topicID);
                return;
            }
            // check the score
            if (score < 0) {
                // we don't GRAFT peers with negative score
                this.log('GRAFT: ignoring peer %s with negative score: score=%d, topic=%s', id5, score, topicID);
                // we do send them PRUNE however, because it's a matter of protocol correctness
                prune.push(topicID);
                // but we won't PX to them
                doPX = false;
                // add/refresh backoff so that we don't reGRAFT too early even if the score decays
                this._addBackoff(id5, topicID);
                return;
            }
            // check the number of mesh peers; if it is at (or over) Dhi, we only accept grafts
            // from peers with outbound connections; this is a defensive check to restrict potential
            // mesh takeover attacks combined with love bombing
            if (peersInMesh.size >= this._options.Dhi && !this.outbound.get(id5)) {
                prune.push(topicID);
                this._addBackoff(id5, topicID);
                return;
            }
            this.log('GRAFT: Add mesh link from %s in %s', id5, topicID);
            this.score.graft(id5, topicID);
            peersInMesh.add(id5);
        });
        if (!prune.length) return [];
        return prune.map((topic)=>this._makePrune(id5, topic, doPX)
        );
    }
    /**
     * Handles Prune messages
     * @param {string} id peer id
     * @param {Array<RPC.IControlPrune>} prune
     * @returns {void}
     */ _handlePrune(id6, prune) {
        const score = this.score.score(id6);
        prune.forEach(({ topicID , backoff , peers  })=>{
            if (!topicID) return;
            const peersInMesh = this.mesh.get(topicID);
            if (!peersInMesh) return;
            this.log('PRUNE: Remove mesh link to %s in %s', id6, topicID);
            this.score.prune(id6, topicID);
            peersInMesh.delete(id6);
            // is there a backoff specified by the peer? if so obey it
            if (typeof backoff === 'number' && backoff > 0) this._doAddBackoff(id6, topicID, backoff * 1000);
            else this._addBackoff(id6, topicID);
            // PX
            if (peers && peers.length) {
                // we ignore PX from peers with insufficient scores
                if (score < this._options.scoreThresholds.acceptPXThreshold) {
                    this.log('PRUNE: ignoring PX from peer %s with insufficient score [score = %d, topic = %s]', id6, score, topicID);
                    return;
                }
                this._pxConnect(peers);
            }
        });
    }
    /**
     * Add standard backoff log for a peer in a topic
     * @param {string} id
     * @param {string} topic
     * @returns {void}
     */ _addBackoff(id7, topic2) {
        this._doAddBackoff(id7, topic2, constants.GossipsubPruneBackoff);
    }
    /**
     * Add backoff expiry interval for a peer in a topic
     * @param {string} id
     * @param {string} topic
     * @param {number} interval backoff duration in milliseconds
     * @returns {void}
     */ _doAddBackoff(id8, topic1, interval) {
        let backoff = this.backoff.get(topic1);
        if (!backoff) {
            backoff = new Map();
            this.backoff.set(topic1, backoff);
        }
        const expire = this._now() + interval;
        const existingExpire = backoff.get(id8) || 0;
        if (existingExpire < expire) backoff.set(id8, expire);
    }
    /**
     * Apply penalties from broken IHAVE/IWANT promises
     * @returns {void}
     */ _applyIwantPenalties() {
        this.gossipTracer.getBrokenPromises().forEach((count, p)=>{
            this.log('peer %s didn\'t follow up in %d IWANT requests; adding penalty', p, count);
            this.score.addPenalty(p, count);
        });
    }
    /**
     * Clear expired backoff expiries
     * @returns {void}
     */ _clearBackoff() {
        // we only clear once every GossipsubPruneBackoffTicks ticks to avoid iterating over the maps too much
        if (this.heartbeatTicks % constants.GossipsubPruneBackoffTicks !== 0) return;
        const now = this._now();
        this.backoff.forEach((backoff, topic)=>{
            backoff.forEach((expire, id)=>{
                if (expire < now) backoff.delete(id);
            });
            if (backoff.size === 0) this.backoff.delete(topic);
        });
    }
    /**
     * Maybe reconnect to direct peers
     * @returns {void}
     */ _directConnect() {
        // we only do this every few ticks to allow pending connections to complete and account for
        // restarts/downtime
        if (this.heartbeatTicks % constants.GossipsubDirectConnectTicks !== 0) return;
        const toconnect = [];
        this.direct.forEach((id)=>{
            const peer = this.peers.get(id);
            if (!peer || !peer.isWritable) toconnect.push(id);
        });
        if (toconnect.length) toconnect.forEach((id)=>{
            this._connect(id);
        });
    }
    /**
     * Maybe attempt connection given signed peer records
     * @param {RPC.IPeerInfo[]} peers
     * @returns {Promise<void>}
     */ _pxConnect(peers2) {
        return __awaiter(this, void 0, void 0, function*() {
            if (peers2.length > constants.GossipsubPrunePeers) {
                utils_1.shuffle(peers2);
                peers2 = peers2.slice(0, constants.GossipsubPrunePeers);
            }
            const toconnect = [];
            yield Promise.all(peers2.map((pi)=>__awaiter(this, void 0, void 0, function*() {
                    if (!pi.peerID) return;
                    const p = PeerId.createFromBytes(pi.peerID);
                    const id = p.toB58String();
                    if (this.peers.has(id)) return;
                    if (!pi.signedPeerRecord) {
                        toconnect.push(id);
                        return;
                    }
                    // The peer sent us a signed record
                    // This is not a record from the peer who sent the record, but another peer who is connected with it
                    // Ensure that it is valid
                    try {
                        const envelope = yield Envelope.openAndCertify(pi.signedPeerRecord, 'libp2p-peer-record');
                        const eid = envelope.peerId.toB58String();
                        if (id !== eid) {
                            this.log('bogus peer record obtained through px: peer ID %s doesn\'t match expected peer %s', eid, id);
                            return;
                        }
                        if (!this._libp2p.peerStore.addressBook.consumePeerRecord(envelope)) {
                            this.log('bogus peer record obtained through px: could not add peer record to address book');
                            return;
                        }
                        toconnect.push(id);
                    } catch (e) {
                        this.log('bogus peer record obtained through px: invalid signature or not a peer record');
                    }
                })
            ));
            if (!toconnect.length) return;
            toconnect.forEach((id)=>this._connect(id)
            );
        });
    }
    /**
     * Mounts the gossipsub protocol onto the libp2p node and sends our
     * our subscriptions to every peer connected
     * @override
     * @returns {void}
     */ start() {
        super.start();
        this.heartbeat.start();
        this.score.start();
        // connect to direct peers
        this._directPeerInitial = setTimeout(()=>{
            this.direct.forEach((id)=>{
                this._connect(id);
            });
        }, constants.GossipsubDirectConnectInitialDelay);
    }
    /**
     * Unmounts the gossipsub protocol and shuts down every connection
     * @override
     * @returns {void}
     */ stop() {
        super.stop();
        this.heartbeat.stop();
        this.score.stop();
        this.mesh = new Map();
        this.fanout = new Map();
        this.lastpub = new Map();
        this.gossip = new Map();
        this.control = new Map();
        this.peerhave = new Map();
        this.iasked = new Map();
        this.backoff = new Map();
        this.outbound = new Map();
        this.gossipTracer.clear();
        clearTimeout(this._directPeerInitial);
    }
    /**
     * Connect to a peer using the gossipsub protocol
     * @param {string} id
     * @returns {void}
     */ _connect(id10) {
        this.log('Initiating connection with %s', id10);
        this._libp2p.dialProtocol(PeerId.createFromB58String(id10), this.multicodecs);
    }
    /**
     * Subscribes to a topic
     * @override
     * @param {string} topic
     * @returns {void}
     */ subscribe(topic6) {
        super.subscribe(topic6);
        this.join(topic6);
    }
    /**
     * Unsubscribe to a topic
     * @override
     * @param {string} topic
     * @returns {void}
     */ unsubscribe(topic3) {
        super.unsubscribe(topic3);
        this.leave(topic3);
    }
    /**
     * Join topic
     * @param {string} topic
     * @returns {void}
     */ join(topic4) {
        if (!this.started) throw new Error('Gossipsub has not started');
        this.log('JOIN %s', topic4);
        const fanoutPeers = this.fanout.get(topic4);
        if (fanoutPeers) {
            // these peers have a score above the publish threshold, which may be negative
            // so drop the ones with a negative score
            fanoutPeers.forEach((id)=>{
                if (this.score.score(id) < 0) fanoutPeers.delete(id);
            });
            if (fanoutPeers.size < this._options.D) // we need more peers; eager, as this would get fixed in the next heartbeat
            get_gossip_peers_1.getGossipPeers(this, topic4, this._options.D - fanoutPeers.size, (id)=>{
                // filter our current peers, direct peers, and peers with negative scores
                return !fanoutPeers.has(id) && !this.direct.has(id) && this.score.score(id) >= 0;
            }).forEach((id)=>fanoutPeers.add(id)
            );
            this.mesh.set(topic4, fanoutPeers);
            this.fanout.delete(topic4);
            this.lastpub.delete(topic4);
        } else {
            const peers = get_gossip_peers_1.getGossipPeers(this, topic4, this._options.D, (id)=>{
                // filter direct peers and peers with negative score
                return !this.direct.has(id) && this.score.score(id) >= 0;
            });
            this.mesh.set(topic4, peers);
        }
        this.mesh.get(topic4).forEach((id)=>{
            this.log('JOIN: Add mesh link to %s in %s', id, topic4);
            this._sendGraft(id, topic4);
        });
    }
    /**
     * Leave topic
     * @param {string} topic
     * @returns {void}
     */ leave(topic5) {
        if (!this.started) throw new Error('Gossipsub has not started');
        this.log('LEAVE %s', topic5);
        // Send PRUNE to mesh peers
        const meshPeers = this.mesh.get(topic5);
        if (meshPeers) {
            meshPeers.forEach((id)=>{
                this.log('LEAVE: Remove mesh link to %s in %s', id, topic5);
                this._sendPrune(id, topic5);
            });
            this.mesh.delete(topic5);
        }
    }
    /**
     * Publish messages
     *
     * @override
     * @param {InMessage} msg
     * @returns {void}
     */ _publish(msg) {
        return __awaiter(this, void 0, void 0, function*() {
            if (msg.receivedFrom !== this.peerId.toB58String()) {
                this.score.deliverMessage(msg);
                this.gossipTracer.deliverMessage(msg);
            }
            const msgID = yield this.getMsgId(msg);
            const msgIdStr = utils_1.messageIdToString(msgID);
            // put in seen cache
            this.seenCache.put(msgIdStr);
            this.messageCache.put(msg);
            const tosend = new Set();
            msg.topicIDs.forEach((topic)=>{
                const peersInTopic = this.topics.get(topic);
                if (!peersInTopic) return;
                if (this._options.floodPublish && msg.from === this.peerId.toB58String()) // flood-publish behavior
                // send to direct peers and _all_ peers meeting the publishThreshold
                peersInTopic.forEach((id)=>{
                    if (this.direct.has(id) || this.score.score(id) >= this._options.scoreThresholds.publishThreshold) tosend.add(id);
                });
                else {
                    // non-flood-publish behavior
                    // send to direct peers, subscribed floodsub peers
                    // and some mesh peers above publishThreshold
                    // direct peers
                    this.direct.forEach((id)=>{
                        tosend.add(id);
                    });
                    // floodsub peers
                    peersInTopic.forEach((id)=>{
                        const score = this.score.score(id);
                        const peerStreams = this.peers.get(id);
                        if (!peerStreams) return;
                        if (peerStreams.protocol === constants.FloodsubID && score >= this._options.scoreThresholds.publishThreshold) tosend.add(id);
                    });
                    // Gossipsub peers handling
                    let meshPeers = this.mesh.get(topic);
                    if (!meshPeers || !meshPeers.size) {
                        // We are not in the mesh for topic, use fanout peers
                        meshPeers = this.fanout.get(topic);
                        if (!meshPeers) {
                            // If we are not in the fanout, then pick peers in topic above the publishThreshold
                            const peers = get_gossip_peers_1.getGossipPeers(this, topic, this._options.D, (id)=>{
                                return this.score.score(id) >= this._options.scoreThresholds.publishThreshold;
                            });
                            if (peers.size > 0) {
                                meshPeers = peers;
                                this.fanout.set(topic, peers);
                            } else meshPeers = new Set();
                        }
                        // Store the latest publishing time
                        this.lastpub.set(topic, this._now());
                    }
                    meshPeers.forEach((peer)=>{
                        tosend.add(peer);
                    });
                }
            });
            // Publish messages to peers
            const rpc = utils_1.createGossipRpc([
                pubsub_1.utils.normalizeOutRpcMessage(msg)
            ]);
            tosend.forEach((id)=>{
                if (id === msg.from) return;
                this._sendRpc(id, rpc);
            });
        });
    }
    /**
     * Sends a GRAFT message to a peer
     * @param {string} id peer id
     * @param {string} topic
     * @returns {void}
     */ _sendGraft(id16, topic) {
        const graft = [
            {
                topicID: topic
            }
        ];
        const out = utils_1.createGossipRpc([], {
            graft
        });
        this._sendRpc(id16, out);
    }
    /**
     * Sends a PRUNE message to a peer
     * @param {string} id peer id
     * @param {string} topic
     * @returns {void}
     */ _sendPrune(id11, topic7) {
        const prune = [
            this._makePrune(id11, topic7, this._options.doPX)
        ];
        const out = utils_1.createGossipRpc([], {
            prune
        });
        this._sendRpc(id11, out);
    }
    /**
     * @override
     */ _sendRpc(id12, outRpc) {
        const peerStreams = this.peers.get(id12);
        if (!peerStreams || !peerStreams.isWritable) return;
        // piggyback control message retries
        const ctrl = this.control.get(id12);
        if (ctrl) {
            this._piggybackControl(id12, outRpc, ctrl);
            this.control.delete(id12);
        }
        // piggyback gossip
        const ihave = this.gossip.get(id12);
        if (ihave) {
            this._piggybackGossip(id12, outRpc, ihave);
            this.gossip.delete(id12);
        }
        peerStreams.write(rpc_1.RPC.encode(outRpc).finish());
    }
    _piggybackControl(id13, outRpc1, ctrl) {
        const tograft = (ctrl.graft || []).filter(({ topicID  })=>(topicID && this.mesh.get(topicID) || new Set()).has(id13)
        );
        const toprune = (ctrl.prune || []).filter(({ topicID  })=>!(topicID && this.mesh.get(topicID) || new Set()).has(id13)
        );
        if (!tograft.length && !toprune.length) return;
        if (outRpc1.control) {
            outRpc1.control.graft = outRpc1.control.graft && outRpc1.control.graft.concat(tograft);
            outRpc1.control.prune = outRpc1.control.prune && outRpc1.control.prune.concat(toprune);
        } else outRpc1.control = {
            ihave: [],
            iwant: [],
            graft: tograft,
            prune: toprune
        };
    }
    _piggybackGossip(id14, outRpc2, ihave1) {
        if (!outRpc2.control) outRpc2.control = {
            ihave: [],
            iwant: [],
            graft: [],
            prune: []
        };
        outRpc2.control.ihave = ihave1;
    }
    /**
     * Send graft and prune messages
     * @param {Map<string, Array<string>>} tograft peer id => topic[]
     * @param {Map<string, Array<string>>} toprune peer id => topic[]
     */ _sendGraftPrune(tograft, toprune, noPX) {
        const doPX = this._options.doPX;
        for (const [id, topics] of tograft){
            const graft = topics.map((topicID)=>({
                    topicID
                })
            );
            let prune = [];
            // If a peer also has prunes, process them now
            const pruning = toprune.get(id);
            if (pruning) {
                prune = pruning.map((topicID)=>this._makePrune(id, topicID, doPX && !noPX.get(id))
                );
                toprune.delete(id);
            }
            const outRpc = utils_1.createGossipRpc([], {
                graft,
                prune
            });
            this._sendRpc(id, outRpc);
        }
        for (const [id15, topics1] of toprune){
            const prune = topics1.map((topicID)=>this._makePrune(id15, topicID, doPX && !noPX.get(id15))
            );
            const outRpc = utils_1.createGossipRpc([], {
                prune
            });
            this._sendRpc(id15, outRpc);
        }
    }
    /**
     * Emits gossip to peers in a particular topic
     * @param {string} topic
     * @param {Set<string>} exclude peers to exclude
     * @returns {void}
     */ _emitGossip(topic8, exclude) {
        const messageIDs = this.messageCache.getGossipIDs(topic8);
        if (!messageIDs.length) return;
        // shuffle to emit in random order
        utils_1.shuffle(messageIDs);
        // if we are emitting more than GossipsubMaxIHaveLength ids, truncate the list
        if (messageIDs.length > constants.GossipsubMaxIHaveLength) // we do the truncation (with shuffling) per peer below
        this.log('too many messages for gossip; will truncate IHAVE list (%d messages)', messageIDs.length);
        // Send gossip to GossipFactor peers above threshold with a minimum of D_lazy
        // First we collect the peers above gossipThreshold that are not in the exclude set
        // and then randomly select from that set
        // We also exclude direct peers, as there is no reason to emit gossip to them
        const peersToGossip = [];
        const topicPeers = this.topics.get(topic8);
        if (!topicPeers) // no topic peers, no gossip
        return;
        topicPeers.forEach((id)=>{
            const peerStreams = this.peers.get(id);
            if (!peerStreams) return;
            if (!exclude.has(id) && !this.direct.has(id) && utils_1.hasGossipProtocol(peerStreams.protocol) && this.score.score(id) >= this._options.scoreThresholds.gossipThreshold) peersToGossip.push(id);
        });
        let target = this._options.Dlazy;
        const factor = constants.GossipsubGossipFactor * peersToGossip.length;
        if (factor > target) target = factor;
        if (target > peersToGossip.length) target = peersToGossip.length;
        else utils_1.shuffle(peersToGossip);
        // Emit the IHAVE gossip to the selected peers up to the target
        peersToGossip.slice(0, target).forEach((id)=>{
            let peerMessageIDs = messageIDs;
            if (messageIDs.length > constants.GossipsubMaxIHaveLength) // shuffle and slice message IDs per peer so that we emit a different set for each peer
            // we have enough reduncancy in the system that this will significantly increase the message
            // coverage when we do truncate
            peerMessageIDs = utils_1.shuffle(peerMessageIDs.slice()).slice(0, constants.GossipsubMaxIHaveLength);
            this._pushGossip(id, {
                topicID: topic8,
                messageIDs: peerMessageIDs
            });
        });
    }
    /**
     * Flush gossip and control messages
     */ _flush() {
        // send gossip first, which will also piggyback control
        for (const [peer, ihave] of this.gossip.entries()){
            this.gossip.delete(peer);
            const out = utils_1.createGossipRpc([], {
                ihave
            });
            this._sendRpc(peer, out);
        }
        // send the remaining control messages
        for (const [peer1, control] of this.control.entries()){
            this.control.delete(peer1);
            const out = utils_1.createGossipRpc([], {
                graft: control.graft,
                prune: control.prune
            });
            this._sendRpc(peer1, out);
        }
    }
    /**
     * Adds new IHAVE messages to pending gossip
     * @param {PeerStreams} peerStreams
     * @param {Array<RPC.IControlIHave>} controlIHaveMsgs
     * @returns {void}
     */ _pushGossip(id, controlIHaveMsgs) {
        this.log('Add gossip to %s', id);
        const gossip = this.gossip.get(id) || [];
        this.gossip.set(id, gossip.concat(controlIHaveMsgs));
    }
    /**
     * Returns the current time in milliseconds
     * @returns {number}
     */ _now() {
        return Date.now();
    }
    /**
     * Make a PRUNE control message for a peer in a topic
     * @param {string} id
     * @param {string} topic
     * @param {boolean} doPX
     * @returns {RPC.IControlPrune}
     */ _makePrune(id17, topic9, doPX) {
        if (this.peers.get(id17).protocol === constants.GossipsubIDv10) // Gossipsub v1.0 -- no backoff, the peer won't be able to parse it anyway
        return {
            topicID: topic9,
            peers: []
        };
        // backoff is measured in seconds
        // GossipsubPruneBackoff is measured in milliseconds
        const backoff = constants.GossipsubPruneBackoff / 1000;
        const px = [];
        if (doPX) {
            // select peers for Peer eXchange
            const peers = get_gossip_peers_1.getGossipPeers(this, topic9, constants.GossipsubPrunePeers, (xid)=>{
                return xid !== id17 && this.score.score(xid) >= 0;
            });
            peers.forEach((p)=>{
                // see if we have a signed record to send back; if we don't, just send
                // the peer ID and let the pruned peer find them in the DHT -- we can't trust
                // unsigned address records through PX anyways
                // Finding signed records in the DHT is not supported at the time of writing in js-libp2p
                const peerId = PeerId.createFromB58String(p);
                px.push({
                    peerID: peerId.toBytes(),
                    signedPeerRecord: this._libp2p.peerStore.addressBook.getRawEnvelope(peerId)
                });
            });
        }
        return {
            topicID: topic9,
            peers: px,
            backoff: backoff
        };
    }
}
Gossipsub.multicodec = constants.GossipsubIDv11;
module.exports = Gossipsub;

},{"libp2p-interfaces/src/pubsub":"4BSVF","./message-cache":"6J9JI","./message/rpc":"bbhyk","./constants":"dwqwi","./heartbeat":"ijt8w","./get-gossip-peers":"8LLZe","./utils":"j1LCn","./score":"iqXcJ","./tracer":"lSw9z","time-cache":"2bWKq","peer-id":"4VGWt","libp2p/src/record/envelope":"dFiHn"}],"4BSVF":[function(require,module,exports) {
'use strict';
const debug = require('debug');
const { EventEmitter  } = require('events');
const errcode = require('err-code');
const { pipe  } = require('it-pipe');
const { default: Queue  } = require('p-queue');
const MulticodecTopology = require('../topology/multicodec-topology');
const { codes  } = require('./errors');
const { RPC  } = require('./message/rpc');
const PeerStreams = require('./peer-streams');
const { SignaturePolicy  } = require('./signature-policy');
const utils = require('./utils');
const { signMessage , verifySignature  } = require('./message/sign');
/**
 * @typedef {any} Libp2p
 * @typedef {import('peer-id')} PeerId
 * @typedef {import('bl')} BufferList
 * @typedef {import('../stream-muxer/types').MuxedStream} MuxedStream
 * @typedef {import('../connection/connection')} Connection
 * @typedef {import('./signature-policy').SignaturePolicyType} SignaturePolicyType
 * @typedef {import('./message/rpc').IRPC} IRPC
 * @typedef {import('./message/rpc').RPC.SubOpts} RPCSubOpts
 * @typedef {import('./message/rpc').RPC.Message} RPCMessage
 */ /**
 * @typedef {Object} InMessage
 * @property {string} [from]
 * @property {string} receivedFrom
 * @property {string[]} topicIDs
 * @property {Uint8Array} [seqno]
 * @property {Uint8Array} data
 * @property {Uint8Array} [signature]
 * @property {Uint8Array} [key]
 *
 * @typedef {Object} PubsubProperties
 * @property {string} debugName - log namespace
 * @property {Array<string>|string} multicodecs - protocol identificers to connect
 * @property {Libp2p} libp2p
 *
 * @typedef {Object} PubsubOptions
 * @property {SignaturePolicyType} [globalSignaturePolicy = SignaturePolicy.StrictSign] - defines how signatures should be handled
 * @property {boolean} [canRelayMessage = false] - if can relay messages not subscribed
 * @property {boolean} [emitSelf = false] - if publish should emit to self, if subscribed
 * @property {number} [messageProcessingConcurrency = 10] - handle this many incoming pubsub messages concurrently
 */ /**
 * PubsubBaseProtocol handles the peers and connections logic for pubsub routers
 * and specifies the API that pubsub routers should have.
 */ class PubsubBaseProtocol extends EventEmitter {
    /**
   * @param {PubsubProperties & PubsubOptions} props
   * @abstract
   */ constructor({ debugName , multicodecs , libp2p , globalSignaturePolicy =SignaturePolicy.StrictSign , canRelayMessage =false , emitSelf =false , messageProcessingConcurrency =10  }){
        if (typeof debugName !== 'string') throw new Error('a debugname `string` is required');
        if (!multicodecs) throw new Error('multicodecs are required');
        if (!libp2p) throw new Error('libp2p is required');
        super();
        this.log = Object.assign(debug(debugName), {
            err: debug(`${debugName}:error`)
        });
        /**
     * @type {Array<string>}
     */ this.multicodecs = utils.ensureArray(multicodecs);
        this._libp2p = libp2p;
        this.registrar = libp2p.registrar;
        /**
     * @type {PeerId}
     */ this.peerId = libp2p.peerId;
        this.started = false;
        /**
     * Map of topics to which peers are subscribed to
     *
     * @type {Map<string, Set<string>>}
     */ this.topics = new Map();
        /**
     * List of our subscriptions
     *
     * @type {Set<string>}
     */ this.subscriptions = new Set();
        /**
     * Map of peer streams
     *
     * @type {Map<string, import('./peer-streams')>}
     */ this.peers = new Map();
        // validate signature policy
        if (!SignaturePolicy[globalSignaturePolicy]) throw errcode(new Error('Invalid global signature policy'), codes.ERR_INVALID_SIGNATURE_POLICY);
        /**
     * The signature policy to follow by default
     *
     * @type {string}
     */ this.globalSignaturePolicy = globalSignaturePolicy;
        /**
     * If router can relay received messages, even if not subscribed
     *
     * @type {boolean}
     */ this.canRelayMessage = canRelayMessage;
        /**
     * if publish should emit to self, if subscribed
     *
     * @type {boolean}
     */ this.emitSelf = emitSelf;
        /**
     * Topic validator function
     *
     * @typedef {function(string, InMessage): Promise<void>} validator
     */ /**
     * Topic validator map
     *
     * Keyed by topic
     * Topic validators are functions with the following input:
     *
     * @type {Map<string, validator>}
     */ this.topicValidators = new Map();
        /**
     * @type {Queue}
     */ this.queue = new Queue({
            concurrency: messageProcessingConcurrency
        });
        this._registrarId = undefined;
        this._onIncomingStream = this._onIncomingStream.bind(this);
        this._onPeerConnected = this._onPeerConnected.bind(this);
        this._onPeerDisconnected = this._onPeerDisconnected.bind(this);
    }
    // LIFECYCLE METHODS
    /**
   * Register the pubsub protocol onto the libp2p node.
   *
   * @returns {void}
   */ start() {
        if (this.started) return;
        this.log('starting');
        // Incoming streams
        // Called after a peer dials us
        this.registrar.handle(this.multicodecs, this._onIncomingStream);
        // register protocol with topology
        // Topology callbacks called on connection manager changes
        const topology = new MulticodecTopology({
            multicodecs: this.multicodecs,
            handlers: {
                onConnect: this._onPeerConnected,
                onDisconnect: this._onPeerDisconnected
            }
        });
        this._registrarId = this.registrar.register(topology);
        this.log('started');
        this.started = true;
    }
    /**
   * Unregister the pubsub protocol and the streams with other peers will be closed.
   *
   * @returns {void}
   */ stop() {
        if (!this.started) return;
        // unregister protocol and handlers
        this.registrar.unregister(this._registrarId);
        this.log('stopping');
        this.peers.forEach((peerStreams)=>peerStreams.close()
        );
        this.peers = new Map();
        this.subscriptions = new Set();
        this.started = false;
        this.log('stopped');
    }
    /**
   * On an inbound stream opened.
   *
   * @protected
   * @param {Object} props
   * @param {string} props.protocol
   * @param {MuxedStream} props.stream
   * @param {Connection} props.connection - connection
   */ _onIncomingStream({ protocol , stream , connection  }) {
        const peerId = connection.remotePeer;
        const idB58Str = peerId.toB58String();
        const peer = this._addPeer(peerId, protocol);
        const inboundStream = peer.attachInboundStream(stream);
        this._processMessages(idB58Str, inboundStream, peer);
    }
    /**
   * Registrar notifies an established connection with pubsub protocol.
   *
   * @protected
   * @param {PeerId} peerId - remote peer-id
   * @param {Connection} conn - connection to the peer
   */ async _onPeerConnected(peerId, conn) {
        const idB58Str = peerId.toB58String();
        this.log('connected', idB58Str);
        try {
            const { stream , protocol  } = await conn.newStream(this.multicodecs);
            const peer = this._addPeer(peerId, protocol);
            await peer.attachOutboundStream(stream);
        } catch (err) {
            this.log.err(err);
        }
        // Immediately send my own subscriptions to the newly established conn
        this._sendSubscriptions(idB58Str, Array.from(this.subscriptions), true);
    }
    /**
   * Registrar notifies a closing connection with pubsub protocol.
   *
   * @protected
   * @param {PeerId} peerId - peerId
   * @param {Error} [err] - error for connection end
   */ _onPeerDisconnected(peerId1, err1) {
        const idB58Str = peerId1.toB58String();
        this.log('connection ended', idB58Str, err1 ? err1.message : '');
        this._removePeer(peerId1);
    }
    /**
   * Notifies the router that a peer has been connected
   *
   * @protected
   * @param {PeerId} peerId
   * @param {string} protocol
   * @returns {PeerStreams}
   */ _addPeer(peerId2, protocol1) {
        const id = peerId2.toB58String();
        const existing = this.peers.get(id);
        // If peer streams already exists, do nothing
        if (existing) return existing;
        // else create a new peer streams
        this.log('new peer', id);
        const peerStreams = new PeerStreams({
            id: peerId2,
            protocol: protocol1
        });
        this.peers.set(id, peerStreams);
        peerStreams.once('close', ()=>this._removePeer(peerId2)
        );
        return peerStreams;
    }
    /**
   * Notifies the router that a peer has been disconnected.
   *
   * @protected
   * @param {PeerId} peerId
   * @returns {PeerStreams | undefined}
   */ _removePeer(peerId3) {
        if (!peerId3) return;
        const id = peerId3.toB58String();
        const peerStreams = this.peers.get(id);
        if (!peerStreams) return;
        // close peer streams
        peerStreams.removeAllListeners();
        peerStreams.close();
        // delete peer streams
        this.log('delete peer', id);
        this.peers.delete(id);
        // remove peer from topics map
        for (const peers of this.topics.values())peers.delete(id);
        return peerStreams;
    }
    // MESSAGE METHODS
    /**
   * Responsible for processing each RPC message received by other peers.
   *
   * @param {string} idB58Str - peer id string in base58
   * @param {AsyncIterable<Uint8Array|BufferList>} stream - inbound stream
   * @param {PeerStreams} peerStreams - PubSub peer
   * @returns {Promise<void>}
   */ async _processMessages(idB58Str, stream1, peerStreams) {
        try {
            await pipe(stream1, async (source)=>{
                for await (const data of source){
                    const rpcBytes = data instanceof Uint8Array ? data : data.slice();
                    const rpcMsg = this._decodeRpc(rpcBytes);
                    (async ()=>{
                        try {
                            await this._processRpc(idB58Str, peerStreams, rpcMsg);
                        } catch (err) {
                            this.log.err(err);
                        }
                    })();
                }
            });
        } catch (err) {
            this._onPeerDisconnected(peerStreams.id, err);
        }
    }
    /**
   * Handles an rpc request from a peer
   *
   * @param {string} idB58Str
   * @param {PeerStreams} peerStreams
   * @param {RPC} rpc
   * @returns {Promise<boolean>}
   */ async _processRpc(idB58Str1, peerStreams1, rpc) {
        this.log('rpc from', idB58Str1);
        const subs = rpc.subscriptions;
        const msgs = rpc.msgs;
        if (subs.length) {
            // update peer subscriptions
            subs.forEach((subOpt)=>{
                this._processRpcSubOpt(idB58Str1, subOpt);
            });
            this.emit('pubsub:subscription-change', peerStreams1.id, subs);
        }
        if (!this._acceptFrom(idB58Str1)) {
            this.log('received message from unacceptable peer %s', idB58Str1);
            return false;
        }
        if (msgs.length) this.queue.addAll(msgs.map((message)=>async ()=>{
                if (!(this.canRelayMessage || message.topicIDs && message.topicIDs.some((topic)=>this.subscriptions.has(topic)
                ))) {
                    this.log('received message we didn\'t subscribe to. Dropping.');
                    return;
                }
                try {
                    const msg = utils.normalizeInRpcMessage(message, idB58Str1);
                    await this._processRpcMessage(msg);
                } catch (err) {
                    this.log.err(err);
                }
            }
        ));
        return true;
    }
    /**
   * Handles a subscription change from a peer
   *
   * @param {string} id
   * @param {RPC.ISubOpts} subOpt
   */ _processRpcSubOpt(id4, subOpt) {
        const t = subOpt.topicID;
        if (!t) return;
        let topicSet = this.topics.get(t);
        if (!topicSet) {
            topicSet = new Set();
            this.topics.set(t, topicSet);
        }
        if (subOpt.subscribe) // subscribe peer to new topic
        topicSet.add(id4);
        else // unsubscribe from existing topic
        topicSet.delete(id4);
    }
    /**
   * Handles an message from a peer
   *
   * @param {InMessage} msg
   * @returns {Promise<void>}
   */ async _processRpcMessage(msg) {
        if (this.peerId.toB58String() === msg.from && !this.emitSelf) return;
        // Ensure the message is valid before processing it
        try {
            await this.validate(msg);
        } catch (err) {
            this.log('Message is invalid, dropping it. %O', err);
            return;
        }
        // Emit to self
        this._emitMessage(msg);
        return this._publish(utils.normalizeOutRpcMessage(msg));
    }
    /**
   * Emit a message from a peer
   *
   * @param {InMessage} message
   */ _emitMessage(message) {
        message.topicIDs.forEach((topic)=>{
            if (this.subscriptions.has(topic)) this.emit(topic, message);
        });
    }
    /**
   * The default msgID implementation
   * Child class can override this.
   *
   * @param {InMessage} msg - the message object
   * @returns {Promise<Uint8Array> | Uint8Array} message id as bytes
   */ getMsgId(msg1) {
        const signaturePolicy = this.globalSignaturePolicy;
        switch(signaturePolicy){
            case SignaturePolicy.StrictSign:
                // @ts-ignore seqno is optional in protobuf definition but it will exist
                return utils.msgId(msg1.from, msg1.seqno);
            case SignaturePolicy.StrictNoSign:
                return utils.noSignMsgId(msg1.data);
            default:
                throw errcode(new Error('Cannot get message id: unhandled signature policy: ' + signaturePolicy), codes.ERR_UNHANDLED_SIGNATURE_POLICY);
        }
    }
    /**
   * Whether to accept a message from a peer
   * Override to create a graylist
   *
   * @param {string} id
   * @returns {boolean}
   */ _acceptFrom(id1) {
        return true;
    }
    /**
   * Decode Uint8Array into an RPC object.
   * This can be override to use a custom router protobuf.
   *
   * @param {Uint8Array} bytes
   * @returns {RPC}
   */ _decodeRpc(bytes) {
        return RPC.decode(bytes);
    }
    /**
   * Encode RPC object into a Uint8Array.
   * This can be override to use a custom router protobuf.
   *
   * @param {IRPC} rpc
   * @returns {Uint8Array}
   */ _encodeRpc(rpc1) {
        return RPC.encode(rpc1).finish();
    }
    /**
   * Send an rpc object to a peer
   *
   * @param {string} id - peer id
   * @param {IRPC} rpc
   * @returns {void}
   */ _sendRpc(id2, rpc2) {
        const peerStreams = this.peers.get(id2);
        if (!peerStreams || !peerStreams.isWritable) {
            const msg = `Cannot send RPC to ${id2} as there is no open stream to it available`;
            this.log.err(msg);
            return;
        }
        peerStreams.write(this._encodeRpc(rpc2));
    }
    /**
   * Send subscroptions to a peer
   *
   * @param {string} id - peer id
   * @param {string[]} topics
   * @param {boolean} subscribe - set to false for unsubscriptions
   * @returns {void}
   */ _sendSubscriptions(id3, topics, subscribe) {
        return this._sendRpc(id3, {
            subscriptions: topics.map((t)=>({
                    topicID: t,
                    subscribe: subscribe
                })
            )
        });
    }
    /**
   * Validates the given message. The signature will be checked for authenticity.
   * Throws an error on invalid messages
   *
   * @param {InMessage} message
   * @returns {Promise<void>}
   */ async validate(message1) {
        const signaturePolicy = this.globalSignaturePolicy;
        switch(signaturePolicy){
            case SignaturePolicy.StrictNoSign:
                if (message1.from) throw errcode(new Error('StrictNoSigning: from should not be present'), codes.ERR_UNEXPECTED_FROM);
                if (message1.signature) throw errcode(new Error('StrictNoSigning: signature should not be present'), codes.ERR_UNEXPECTED_SIGNATURE);
                if (message1.key) throw errcode(new Error('StrictNoSigning: key should not be present'), codes.ERR_UNEXPECTED_KEY);
                if (message1.seqno) throw errcode(new Error('StrictNoSigning: seqno should not be present'), codes.ERR_UNEXPECTED_SEQNO);
                break;
            case SignaturePolicy.StrictSign:
                if (!message1.signature) throw errcode(new Error('StrictSigning: Signing required and no signature was present'), codes.ERR_MISSING_SIGNATURE);
                if (!message1.seqno) throw errcode(new Error('StrictSigning: Signing required and no seqno was present'), codes.ERR_MISSING_SEQNO);
                if (!await verifySignature(message1)) throw errcode(new Error('StrictSigning: Invalid message signature'), codes.ERR_INVALID_SIGNATURE);
                break;
            default:
                throw errcode(new Error('Cannot validate message: unhandled signature policy: ' + signaturePolicy), codes.ERR_UNHANDLED_SIGNATURE_POLICY);
        }
        for (const topic of message1.topicIDs){
            const validatorFn = this.topicValidators.get(topic);
            if (validatorFn) await validatorFn(topic, message1);
        }
    }
    /**
   * Normalizes the message and signs it, if signing is enabled.
   * Should be used by the routers to create the message to send.
   *
   * @protected
   * @param {InMessage} message
   * @returns {Promise<InMessage>}
   */ _buildMessage(message2) {
        const signaturePolicy = this.globalSignaturePolicy;
        switch(signaturePolicy){
            case SignaturePolicy.StrictSign:
                message2.from = this.peerId.toB58String();
                message2.seqno = utils.randomSeqno();
                return signMessage(this.peerId, message2);
            case SignaturePolicy.StrictNoSign:
                return Promise.resolve(message2);
            default:
                throw errcode(new Error('Cannot build message: unhandled signature policy: ' + signaturePolicy), codes.ERR_UNHANDLED_SIGNATURE_POLICY);
        }
    }
    // API METHODS
    /**
   * Get a list of the peer-ids that are subscribed to one topic.
   *
   * @param {string} topic
   * @returns {Array<string>}
   */ getSubscribers(topic) {
        if (!this.started) throw errcode(new Error('not started yet'), 'ERR_NOT_STARTED_YET');
        if (!topic || typeof topic !== 'string') throw errcode(new Error('a string topic must be provided'), 'ERR_NOT_VALID_TOPIC');
        const peersInTopic = this.topics.get(topic);
        if (!peersInTopic) return [];
        return Array.from(peersInTopic);
    }
    /**
   * Publishes messages to all subscribed peers
   *
   * @param {string} topic
   * @param {Uint8Array} message
   * @returns {Promise<void>}
   */ async publish(topic1, message3) {
        if (!this.started) throw new Error('Pubsub has not started');
        this.log('publish', topic1, message3);
        const from = this.peerId.toB58String();
        const msgObject = {
            receivedFrom: from,
            data: message3,
            topicIDs: [
                topic1
            ]
        };
        // ensure that the message follows the signature policy
        const outMsg = await this._buildMessage(msgObject);
        // @ts-ignore different type as from is converted
        const msg = utils.normalizeInRpcMessage(outMsg);
        // Emit to self if I'm interested and emitSelf enabled
        this.emitSelf && this._emitMessage(msg);
        // send to all the other peers
        await this._publish(msg);
    }
    /**
   * Overriding the implementation of publish should handle the appropriate algorithms for the publish/subscriber implementation.
   * For example, a Floodsub implementation might simply publish each message to each topic for every peer
   *
   * @abstract
   * @param {InMessage|RPCMessage} message
   * @returns {Promise<void>}
   *
   */ _publish(message4) {
        throw errcode(new Error('publish must be implemented by the subclass'), 'ERR_NOT_IMPLEMENTED');
    }
    /**
   * Subscribes to a given topic.
   *
   * @abstract
   * @param {string} topic
   * @returns {void}
   */ subscribe(topic2) {
        if (!this.started) throw new Error('Pubsub has not started');
        if (!this.subscriptions.has(topic2)) {
            this.subscriptions.add(topic2);
            this.peers.forEach((_, id)=>this._sendSubscriptions(id, [
                    topic2
                ], true)
            );
        }
    }
    /**
   * Unsubscribe from the given topic.
   *
   * @param {string} topic
   * @returns {void}
   */ unsubscribe(topic3) {
        if (!this.started) throw new Error('Pubsub is not started');
        if (this.subscriptions.has(topic3) && this.listenerCount(topic3) === 0) {
            this.subscriptions.delete(topic3);
            this.peers.forEach((_, id)=>this._sendSubscriptions(id, [
                    topic3
                ], false)
            );
        }
    }
    /**
   * Get the list of topics which the peer is subscribed to.
   *
   * @returns {Array<string>}
   */ getTopics() {
        if (!this.started) throw new Error('Pubsub is not started');
        return Array.from(this.subscriptions);
    }
}
PubsubBaseProtocol.utils = utils;
PubsubBaseProtocol.SignaturePolicy = SignaturePolicy;
module.exports = PubsubBaseProtocol;

},{"debug":"lWlU4","events":"bHM3D","err-code":"eQvyh","it-pipe":"4jukm","p-queue":"ccCVf","../topology/multicodec-topology":"czyip","./errors":"gGoLI","./message/rpc":"jUtL4","./peer-streams":"452JY","./signature-policy":"6HHwm","./utils":"3NUS2","./message/sign":"36q3g"}],"czyip":[function(require,module,exports) {
'use strict';
const Topology = require('./index');
const multicodecTopologySymbol = Symbol.for('@libp2p/js-interfaces/topology/multicodec-topology');
class MulticodecTopology extends Topology {
    /**
   * @param {TopologyOptions & MulticodecOptions} props
   */ constructor({ min , max , multicodecs , handlers  }){
        super({
            min,
            max,
            handlers
        });
        if (!multicodecs) throw new Error('one or more multicodec should be provided');
        if (!handlers) throw new Error('the handlers should be provided');
        if (typeof handlers.onConnect !== 'function') throw new Error('the \'onConnect\' handler must be provided');
        if (typeof handlers.onDisconnect !== 'function') throw new Error('the \'onDisconnect\' handler must be provided');
        this.multicodecs = Array.isArray(multicodecs) ? multicodecs : [
            multicodecs
        ];
        this._registrar = undefined;
        this._onProtocolChange = this._onProtocolChange.bind(this);
        this._onPeerConnect = this._onPeerConnect.bind(this);
    }
    get [Symbol.toStringTag]() {
        return 'Topology';
    }
    get [multicodecTopologySymbol]() {
        return true;
    }
    /**
   * Checks if the given value is a `MulticodecTopology` instance.
   *
   * @param {any} other
   * @returns {other is MulticodecTopology}
   */ static isMulticodecTopology(other) {
        return Boolean(other && other[multicodecTopologySymbol]);
    }
    /**
   * @param {any} registrar
   */ set registrar(registrar) {
        this._registrar = registrar;
        this._registrar.peerStore.on('change:protocols', this._onProtocolChange);
        this._registrar.connectionManager.on('peer:connect', this._onPeerConnect);
        // Update topology peers
        this._updatePeers(this._registrar.peerStore.peers.values());
    }
    /**
   * Update topology.
   *
   * @param {Array<{id: PeerId, multiaddrs: Array<Multiaddr>, protocols: Array<string>}>} peerDataIterable
   * @returns {void}
   */ _updatePeers(peerDataIterable) {
        for (const { id , protocols  } of peerDataIterable)if (this.multicodecs.filter((multicodec)=>protocols.includes(multicodec)
        ).length) {
            // Add the peer regardless of whether or not there is currently a connection
            this.peers.add(id.toB58String());
            // If there is a connection, call _onConnect
            const connection = this._registrar.getConnection(id);
            connection && this._onConnect(id, connection);
        } else // Remove any peers we might be tracking that are no longer of value to us
        this.peers.delete(id.toB58String());
    }
    /**
   * Check if a new peer support the multicodecs for this topology.
   *
   * @param {Object} props
   * @param {PeerId} props.peerId
   * @param {Array<string>} props.protocols
   */ _onProtocolChange({ peerId , protocols  }) {
        const hadPeer = this.peers.has(peerId.toB58String());
        const hasProtocol = protocols.filter((protocol)=>this.multicodecs.includes(protocol)
        );
        // Not supporting the protocol anymore?
        if (hadPeer && hasProtocol.length === 0) this._onDisconnect(peerId);
        // New to protocol support
        for (const protocol1 of protocols)if (this.multicodecs.includes(protocol1)) {
            const peerData = this._registrar.peerStore.get(peerId);
            this._updatePeers([
                peerData
            ]);
            return;
        }
    }
    /**
   * Verify if a new connected peer has a topology multicodec and call _onConnect.
   *
   * @param {Connection} connection
   * @returns {void}
   */ _onPeerConnect(connection) {
        // @ts-ignore - remotePeer does not existist on Connection
        const peerId = connection.remotePeer;
        const protocols = this._registrar.peerStore.protoBook.get(peerId);
        if (!protocols) return;
        if (this.multicodecs.find((multicodec)=>protocols.includes(multicodec)
        )) {
            this.peers.add(peerId.toB58String());
            this._onConnect(peerId, connection);
        }
    }
}
/**
 * @typedef {import('peer-id')} PeerId
 * @typedef {import('multiaddr')} Multiaddr
 * @typedef {import('../connection/connection')} Connection
 * @typedef {import('.').Options} TopologyOptions
 * @typedef {Object} MulticodecOptions
 * @property {string[]} multicodecs - protocol multicodecs
 * @property {Required<Handlers>} handlers
 * @typedef {import('.').Handlers} Handlers
 */ module.exports = MulticodecTopology;

},{"./index":"gFGI4"}],"gFGI4":[function(require,module,exports) {
'use strict';
const noop = ()=>{
};
const topologySymbol = Symbol.for('@libp2p/js-interfaces/topology');
/**
 * @typedef {import('peer-id')} PeerId
 */ /**
 * @typedef {Object} Options
 * @property {number} [min=0] - minimum needed connections.
 * @property {number} [max=Infinity] - maximum needed connections.
 * @property {Handlers} [handlers]
 *
 * @typedef {Object} Handlers
 * @property {(peerId: PeerId, conn: Connection) => void} [onConnect] - protocol "onConnect" handler
 * @property {(peerId: PeerId, error?:Error) => void} [onDisconnect] - protocol "onDisconnect" handler
 *
 * @typedef {import('../connection/connection')} Connection
 */ class Topology {
    /**
   * @param {Options} options
   */ constructor({ min =0 , max =Infinity , handlers ={
    }  }){
        this.min = min;
        this.max = max;
        // Handlers
        this._onConnect = handlers.onConnect || noop;
        this._onDisconnect = handlers.onDisconnect || noop;
        /**
     * Set of peers that support the protocol.
     *
     * @type {Set<string>}
     */ this.peers = new Set();
    }
    get [Symbol.toStringTag]() {
        return 'Topology';
    }
    get [topologySymbol]() {
        return true;
    }
    /**
   * Checks if the given value is a Topology instance.
   *
   * @param {any} other
   * @returns {other is Topology}
   */ static isTopology(other) {
        return Boolean(other && other[topologySymbol]);
    }
    /**
   * @param {any} registrar
   */ set registrar(registrar) {
        this._registrar = registrar;
    }
    /**
   * Notify about peer disconnected event.
   *
   * @param {PeerId} peerId
   * @returns {void}
   */ disconnect(peerId) {
        this._onDisconnect(peerId);
    }
}
module.exports = Topology;

},{}],"gGoLI":[function(require,module,exports) {
'use strict';
exports.codes = {
    /**
   * Signature policy is invalid
   */ ERR_INVALID_SIGNATURE_POLICY: 'ERR_INVALID_SIGNATURE_POLICY',
    /**
   * Signature policy is unhandled
   */ ERR_UNHANDLED_SIGNATURE_POLICY: 'ERR_UNHANDLED_SIGNATURE_POLICY',
    // Strict signing codes
    /**
   * Message expected to have a `signature`, but doesn't
   */ ERR_MISSING_SIGNATURE: 'ERR_MISSING_SIGNATURE',
    /**
   * Message expected to have a `seqno`, but doesn't
   */ ERR_MISSING_SEQNO: 'ERR_MISSING_SEQNO',
    /**
   * Message `signature` is invalid
   */ ERR_INVALID_SIGNATURE: 'ERR_INVALID_SIGNATURE',
    // Strict no-signing codes
    /**
   * Message expected to not have a `from`, but does
   */ ERR_UNEXPECTED_FROM: 'ERR_UNEXPECTED_FROM',
    /**
   * Message expected to not have a `signature`, but does
   */ ERR_UNEXPECTED_SIGNATURE: 'ERR_UNEXPECTED_SIGNATURE',
    /**
   * Message expected to not have a `key`, but does
   */ ERR_UNEXPECTED_KEY: 'ERR_UNEXPECTED_KEY',
    /**
   * Message expected to not have a `seqno`, but does
   */ ERR_UNEXPECTED_SEQNO: 'ERR_UNEXPECTED_SEQNO'
};

},{}],"jUtL4":[function(require,module,exports) {
/*eslint-disable*/ "use strict";
var $protobuf = require("protobufjs/minimal");
// Common aliases
var $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util;
// Exported root namespace
var $root = $protobuf.roots["libp2p-pubsub-rpc"] || ($protobuf.roots["libp2p-pubsub-rpc"] = {
});
$root.RPC = (function() {
    /**
     * Properties of a RPC.
     * @exports IRPC
     * @interface IRPC
     * @property {Array.<RPC.ISubOpts>|null} [subscriptions] RPC subscriptions
     * @property {Array.<RPC.IMessage>|null} [msgs] RPC msgs
     */ /**
     * Constructs a new RPC.
     * @exports RPC
     * @classdesc Represents a RPC.
     * @implements IRPC
     * @constructor
     * @param {IRPC=} [p] Properties to set
     */ function RPC(p) {
        this.subscriptions = [];
        this.msgs = [];
        if (p) {
            for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
        }
    }
    /**
     * RPC subscriptions.
     * @member {Array.<RPC.ISubOpts>} subscriptions
     * @memberof RPC
     * @instance
     */ RPC.prototype.subscriptions = $util.emptyArray;
    /**
     * RPC msgs.
     * @member {Array.<RPC.IMessage>} msgs
     * @memberof RPC
     * @instance
     */ RPC.prototype.msgs = $util.emptyArray;
    /**
     * Encodes the specified RPC message. Does not implicitly {@link RPC.verify|verify} messages.
     * @function encode
     * @memberof RPC
     * @static
     * @param {IRPC} m RPC message or plain object to encode
     * @param {$protobuf.Writer} [w] Writer to encode to
     * @returns {$protobuf.Writer} Writer
     */ RPC.encode = function encode(m, w) {
        if (!w) w = $Writer.create();
        if (m.subscriptions != null && m.subscriptions.length) for(var i = 0; i < m.subscriptions.length; ++i)$root.RPC.SubOpts.encode(m.subscriptions[i], w.uint32(10).fork()).ldelim();
        if (m.msgs != null && m.msgs.length) for(var i = 0; i < m.msgs.length; ++i)$root.RPC.Message.encode(m.msgs[i], w.uint32(18).fork()).ldelim();
        return w;
    };
    /**
     * Decodes a RPC message from the specified reader or buffer.
     * @function decode
     * @memberof RPC
     * @static
     * @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
     * @param {number} [l] Message length if known beforehand
     * @returns {RPC} RPC
     * @throws {Error} If the payload is not a reader or valid buffer
     * @throws {$protobuf.util.ProtocolError} If required fields are missing
     */ RPC.decode = function decode(r, l) {
        if (!(r instanceof $Reader)) r = $Reader.create(r);
        var c = l === undefined ? r.len : r.pos + l, m = new $root.RPC();
        while(r.pos < c){
            var t = r.uint32();
            switch(t >>> 3){
                case 1:
                    if (!(m.subscriptions && m.subscriptions.length)) m.subscriptions = [];
                    m.subscriptions.push($root.RPC.SubOpts.decode(r, r.uint32()));
                    break;
                case 2:
                    if (!(m.msgs && m.msgs.length)) m.msgs = [];
                    m.msgs.push($root.RPC.Message.decode(r, r.uint32()));
                    break;
                default:
                    r.skipType(t & 7);
                    break;
            }
        }
        return m;
    };
    /**
     * Creates a RPC message from a plain object. Also converts values to their respective internal types.
     * @function fromObject
     * @memberof RPC
     * @static
     * @param {Object.<string,*>} d Plain object
     * @returns {RPC} RPC
     */ RPC.fromObject = function fromObject(d) {
        if (d instanceof $root.RPC) return d;
        var m = new $root.RPC();
        if (d.subscriptions) {
            if (!Array.isArray(d.subscriptions)) throw TypeError(".RPC.subscriptions: array expected");
            m.subscriptions = [];
            for(var i = 0; i < d.subscriptions.length; ++i){
                if (typeof d.subscriptions[i] !== "object") throw TypeError(".RPC.subscriptions: object expected");
                m.subscriptions[i] = $root.RPC.SubOpts.fromObject(d.subscriptions[i]);
            }
        }
        if (d.msgs) {
            if (!Array.isArray(d.msgs)) throw TypeError(".RPC.msgs: array expected");
            m.msgs = [];
            for(var i = 0; i < d.msgs.length; ++i){
                if (typeof d.msgs[i] !== "object") throw TypeError(".RPC.msgs: object expected");
                m.msgs[i] = $root.RPC.Message.fromObject(d.msgs[i]);
            }
        }
        return m;
    };
    /**
     * Creates a plain object from a RPC message. Also converts values to other types if specified.
     * @function toObject
     * @memberof RPC
     * @static
     * @param {RPC} m RPC
     * @param {$protobuf.IConversionOptions} [o] Conversion options
     * @returns {Object.<string,*>} Plain object
     */ RPC.toObject = function toObject(m, o) {
        if (!o) o = {
        };
        var d = {
        };
        if (o.arrays || o.defaults) {
            d.subscriptions = [];
            d.msgs = [];
        }
        if (m.subscriptions && m.subscriptions.length) {
            d.subscriptions = [];
            for(var j = 0; j < m.subscriptions.length; ++j)d.subscriptions[j] = $root.RPC.SubOpts.toObject(m.subscriptions[j], o);
        }
        if (m.msgs && m.msgs.length) {
            d.msgs = [];
            for(var j = 0; j < m.msgs.length; ++j)d.msgs[j] = $root.RPC.Message.toObject(m.msgs[j], o);
        }
        return d;
    };
    /**
     * Converts this RPC to JSON.
     * @function toJSON
     * @memberof RPC
     * @instance
     * @returns {Object.<string,*>} JSON object
     */ RPC.prototype.toJSON = function toJSON() {
        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
    };
    RPC.SubOpts = (function() {
        /**
         * Properties of a SubOpts.
         * @memberof RPC
         * @interface ISubOpts
         * @property {boolean|null} [subscribe] SubOpts subscribe
         * @property {string|null} [topicID] SubOpts topicID
         */ /**
         * Constructs a new SubOpts.
         * @memberof RPC
         * @classdesc Represents a SubOpts.
         * @implements ISubOpts
         * @constructor
         * @param {RPC.ISubOpts=} [p] Properties to set
         */ function SubOpts(p) {
            if (p) {
                for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
            }
        }
        /**
         * SubOpts subscribe.
         * @member {boolean|null|undefined} subscribe
         * @memberof RPC.SubOpts
         * @instance
         */ SubOpts.prototype.subscribe = null;
        /**
         * SubOpts topicID.
         * @member {string|null|undefined} topicID
         * @memberof RPC.SubOpts
         * @instance
         */ SubOpts.prototype.topicID = null;
        // OneOf field names bound to virtual getters and setters
        var $oneOfFields;
        /**
         * SubOpts _subscribe.
         * @member {"subscribe"|undefined} _subscribe
         * @memberof RPC.SubOpts
         * @instance
         */ Object.defineProperty(SubOpts.prototype, "_subscribe", {
            get: $util.oneOfGetter($oneOfFields = [
                "subscribe"
            ]),
            set: $util.oneOfSetter($oneOfFields)
        });
        /**
         * SubOpts _topicID.
         * @member {"topicID"|undefined} _topicID
         * @memberof RPC.SubOpts
         * @instance
         */ Object.defineProperty(SubOpts.prototype, "_topicID", {
            get: $util.oneOfGetter($oneOfFields = [
                "topicID"
            ]),
            set: $util.oneOfSetter($oneOfFields)
        });
        /**
         * Encodes the specified SubOpts message. Does not implicitly {@link RPC.SubOpts.verify|verify} messages.
         * @function encode
         * @memberof RPC.SubOpts
         * @static
         * @param {RPC.ISubOpts} m SubOpts message or plain object to encode
         * @param {$protobuf.Writer} [w] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */ SubOpts.encode = function encode(m, w) {
            if (!w) w = $Writer.create();
            if (m.subscribe != null && Object.hasOwnProperty.call(m, "subscribe")) w.uint32(8).bool(m.subscribe);
            if (m.topicID != null && Object.hasOwnProperty.call(m, "topicID")) w.uint32(18).string(m.topicID);
            return w;
        };
        /**
         * Decodes a SubOpts message from the specified reader or buffer.
         * @function decode
         * @memberof RPC.SubOpts
         * @static
         * @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
         * @param {number} [l] Message length if known beforehand
         * @returns {RPC.SubOpts} SubOpts
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */ SubOpts.decode = function decode(r, l) {
            if (!(r instanceof $Reader)) r = $Reader.create(r);
            var c = l === undefined ? r.len : r.pos + l, m = new $root.RPC.SubOpts();
            while(r.pos < c){
                var t = r.uint32();
                switch(t >>> 3){
                    case 1:
                        m.subscribe = r.bool();
                        break;
                    case 2:
                        m.topicID = r.string();
                        break;
                    default:
                        r.skipType(t & 7);
                        break;
                }
            }
            return m;
        };
        /**
         * Creates a SubOpts message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof RPC.SubOpts
         * @static
         * @param {Object.<string,*>} d Plain object
         * @returns {RPC.SubOpts} SubOpts
         */ SubOpts.fromObject = function fromObject(d) {
            if (d instanceof $root.RPC.SubOpts) return d;
            var m = new $root.RPC.SubOpts();
            if (d.subscribe != null) m.subscribe = Boolean(d.subscribe);
            if (d.topicID != null) m.topicID = String(d.topicID);
            return m;
        };
        /**
         * Creates a plain object from a SubOpts message. Also converts values to other types if specified.
         * @function toObject
         * @memberof RPC.SubOpts
         * @static
         * @param {RPC.SubOpts} m SubOpts
         * @param {$protobuf.IConversionOptions} [o] Conversion options
         * @returns {Object.<string,*>} Plain object
         */ SubOpts.toObject = function toObject(m, o) {
            if (!o) o = {
            };
            var d = {
            };
            if (m.subscribe != null && m.hasOwnProperty("subscribe")) {
                d.subscribe = m.subscribe;
                if (o.oneofs) d._subscribe = "subscribe";
            }
            if (m.topicID != null && m.hasOwnProperty("topicID")) {
                d.topicID = m.topicID;
                if (o.oneofs) d._topicID = "topicID";
            }
            return d;
        };
        /**
         * Converts this SubOpts to JSON.
         * @function toJSON
         * @memberof RPC.SubOpts
         * @instance
         * @returns {Object.<string,*>} JSON object
         */ SubOpts.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };
        return SubOpts;
    })();
    RPC.Message = (function() {
        /**
         * Properties of a Message.
         * @memberof RPC
         * @interface IMessage
         * @property {Uint8Array|null} [from] Message from
         * @property {Uint8Array|null} [data] Message data
         * @property {Uint8Array|null} [seqno] Message seqno
         * @property {Array.<string>|null} [topicIDs] Message topicIDs
         * @property {Uint8Array|null} [signature] Message signature
         * @property {Uint8Array|null} [key] Message key
         */ /**
         * Constructs a new Message.
         * @memberof RPC
         * @classdesc Represents a Message.
         * @implements IMessage
         * @constructor
         * @param {RPC.IMessage=} [p] Properties to set
         */ function Message(p) {
            this.topicIDs = [];
            if (p) {
                for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
            }
        }
        /**
         * Message from.
         * @member {Uint8Array|null|undefined} from
         * @memberof RPC.Message
         * @instance
         */ Message.prototype.from = null;
        /**
         * Message data.
         * @member {Uint8Array|null|undefined} data
         * @memberof RPC.Message
         * @instance
         */ Message.prototype.data = null;
        /**
         * Message seqno.
         * @member {Uint8Array|null|undefined} seqno
         * @memberof RPC.Message
         * @instance
         */ Message.prototype.seqno = null;
        /**
         * Message topicIDs.
         * @member {Array.<string>} topicIDs
         * @memberof RPC.Message
         * @instance
         */ Message.prototype.topicIDs = $util.emptyArray;
        /**
         * Message signature.
         * @member {Uint8Array|null|undefined} signature
         * @memberof RPC.Message
         * @instance
         */ Message.prototype.signature = null;
        /**
         * Message key.
         * @member {Uint8Array|null|undefined} key
         * @memberof RPC.Message
         * @instance
         */ Message.prototype.key = null;
        // OneOf field names bound to virtual getters and setters
        var $oneOfFields;
        /**
         * Message _from.
         * @member {"from"|undefined} _from
         * @memberof RPC.Message
         * @instance
         */ Object.defineProperty(Message.prototype, "_from", {
            get: $util.oneOfGetter($oneOfFields = [
                "from"
            ]),
            set: $util.oneOfSetter($oneOfFields)
        });
        /**
         * Message _data.
         * @member {"data"|undefined} _data
         * @memberof RPC.Message
         * @instance
         */ Object.defineProperty(Message.prototype, "_data", {
            get: $util.oneOfGetter($oneOfFields = [
                "data"
            ]),
            set: $util.oneOfSetter($oneOfFields)
        });
        /**
         * Message _seqno.
         * @member {"seqno"|undefined} _seqno
         * @memberof RPC.Message
         * @instance
         */ Object.defineProperty(Message.prototype, "_seqno", {
            get: $util.oneOfGetter($oneOfFields = [
                "seqno"
            ]),
            set: $util.oneOfSetter($oneOfFields)
        });
        /**
         * Message _signature.
         * @member {"signature"|undefined} _signature
         * @memberof RPC.Message
         * @instance
         */ Object.defineProperty(Message.prototype, "_signature", {
            get: $util.oneOfGetter($oneOfFields = [
                "signature"
            ]),
            set: $util.oneOfSetter($oneOfFields)
        });
        /**
         * Message _key.
         * @member {"key"|undefined} _key
         * @memberof RPC.Message
         * @instance
         */ Object.defineProperty(Message.prototype, "_key", {
            get: $util.oneOfGetter($oneOfFields = [
                "key"
            ]),
            set: $util.oneOfSetter($oneOfFields)
        });
        /**
         * Encodes the specified Message message. Does not implicitly {@link RPC.Message.verify|verify} messages.
         * @function encode
         * @memberof RPC.Message
         * @static
         * @param {RPC.IMessage} m Message message or plain object to encode
         * @param {$protobuf.Writer} [w] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */ Message.encode = function encode(m, w) {
            if (!w) w = $Writer.create();
            if (m.from != null && Object.hasOwnProperty.call(m, "from")) w.uint32(10).bytes(m.from);
            if (m.data != null && Object.hasOwnProperty.call(m, "data")) w.uint32(18).bytes(m.data);
            if (m.seqno != null && Object.hasOwnProperty.call(m, "seqno")) w.uint32(26).bytes(m.seqno);
            if (m.topicIDs != null && m.topicIDs.length) for(var i = 0; i < m.topicIDs.length; ++i)w.uint32(34).string(m.topicIDs[i]);
            if (m.signature != null && Object.hasOwnProperty.call(m, "signature")) w.uint32(42).bytes(m.signature);
            if (m.key != null && Object.hasOwnProperty.call(m, "key")) w.uint32(50).bytes(m.key);
            return w;
        };
        /**
         * Decodes a Message message from the specified reader or buffer.
         * @function decode
         * @memberof RPC.Message
         * @static
         * @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
         * @param {number} [l] Message length if known beforehand
         * @returns {RPC.Message} Message
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */ Message.decode = function decode(r, l) {
            if (!(r instanceof $Reader)) r = $Reader.create(r);
            var c = l === undefined ? r.len : r.pos + l, m = new $root.RPC.Message();
            while(r.pos < c){
                var t = r.uint32();
                switch(t >>> 3){
                    case 1:
                        m.from = r.bytes();
                        break;
                    case 2:
                        m.data = r.bytes();
                        break;
                    case 3:
                        m.seqno = r.bytes();
                        break;
                    case 4:
                        if (!(m.topicIDs && m.topicIDs.length)) m.topicIDs = [];
                        m.topicIDs.push(r.string());
                        break;
                    case 5:
                        m.signature = r.bytes();
                        break;
                    case 6:
                        m.key = r.bytes();
                        break;
                    default:
                        r.skipType(t & 7);
                        break;
                }
            }
            return m;
        };
        /**
         * Creates a Message message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof RPC.Message
         * @static
         * @param {Object.<string,*>} d Plain object
         * @returns {RPC.Message} Message
         */ Message.fromObject = function fromObject(d) {
            if (d instanceof $root.RPC.Message) return d;
            var m = new $root.RPC.Message();
            if (d.from != null) {
                if (typeof d.from === "string") $util.base64.decode(d.from, m.from = $util.newBuffer($util.base64.length(d.from)), 0);
                else if (d.from.length) m.from = d.from;
            }
            if (d.data != null) {
                if (typeof d.data === "string") $util.base64.decode(d.data, m.data = $util.newBuffer($util.base64.length(d.data)), 0);
                else if (d.data.length) m.data = d.data;
            }
            if (d.seqno != null) {
                if (typeof d.seqno === "string") $util.base64.decode(d.seqno, m.seqno = $util.newBuffer($util.base64.length(d.seqno)), 0);
                else if (d.seqno.length) m.seqno = d.seqno;
            }
            if (d.topicIDs) {
                if (!Array.isArray(d.topicIDs)) throw TypeError(".RPC.Message.topicIDs: array expected");
                m.topicIDs = [];
                for(var i = 0; i < d.topicIDs.length; ++i)m.topicIDs[i] = String(d.topicIDs[i]);
            }
            if (d.signature != null) {
                if (typeof d.signature === "string") $util.base64.decode(d.signature, m.signature = $util.newBuffer($util.base64.length(d.signature)), 0);
                else if (d.signature.length) m.signature = d.signature;
            }
            if (d.key != null) {
                if (typeof d.key === "string") $util.base64.decode(d.key, m.key = $util.newBuffer($util.base64.length(d.key)), 0);
                else if (d.key.length) m.key = d.key;
            }
            return m;
        };
        /**
         * Creates a plain object from a Message message. Also converts values to other types if specified.
         * @function toObject
         * @memberof RPC.Message
         * @static
         * @param {RPC.Message} m Message
         * @param {$protobuf.IConversionOptions} [o] Conversion options
         * @returns {Object.<string,*>} Plain object
         */ Message.toObject = function toObject(m, o) {
            if (!o) o = {
            };
            var d = {
            };
            if (o.arrays || o.defaults) d.topicIDs = [];
            if (m.from != null && m.hasOwnProperty("from")) {
                d.from = o.bytes === String ? $util.base64.encode(m.from, 0, m.from.length) : o.bytes === Array ? Array.prototype.slice.call(m.from) : m.from;
                if (o.oneofs) d._from = "from";
            }
            if (m.data != null && m.hasOwnProperty("data")) {
                d.data = o.bytes === String ? $util.base64.encode(m.data, 0, m.data.length) : o.bytes === Array ? Array.prototype.slice.call(m.data) : m.data;
                if (o.oneofs) d._data = "data";
            }
            if (m.seqno != null && m.hasOwnProperty("seqno")) {
                d.seqno = o.bytes === String ? $util.base64.encode(m.seqno, 0, m.seqno.length) : o.bytes === Array ? Array.prototype.slice.call(m.seqno) : m.seqno;
                if (o.oneofs) d._seqno = "seqno";
            }
            if (m.topicIDs && m.topicIDs.length) {
                d.topicIDs = [];
                for(var j = 0; j < m.topicIDs.length; ++j)d.topicIDs[j] = m.topicIDs[j];
            }
            if (m.signature != null && m.hasOwnProperty("signature")) {
                d.signature = o.bytes === String ? $util.base64.encode(m.signature, 0, m.signature.length) : o.bytes === Array ? Array.prototype.slice.call(m.signature) : m.signature;
                if (o.oneofs) d._signature = "signature";
            }
            if (m.key != null && m.hasOwnProperty("key")) {
                d.key = o.bytes === String ? $util.base64.encode(m.key, 0, m.key.length) : o.bytes === Array ? Array.prototype.slice.call(m.key) : m.key;
                if (o.oneofs) d._key = "key";
            }
            return d;
        };
        /**
         * Converts this Message to JSON.
         * @function toJSON
         * @memberof RPC.Message
         * @instance
         * @returns {Object.<string,*>} JSON object
         */ Message.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };
        return Message;
    })();
    return RPC;
})();
module.exports = $root;

},{"protobufjs/minimal":"9Jmso"}],"452JY":[function(require,module,exports) {
'use strict';
const debug = require('debug');
const log = Object.assign(debug('libp2p-pubsub:peer-streams'), {
    error: debug('libp2p-pubsub:peer-streams:err')
});
const { EventEmitter  } = require('events');
const lp = require('it-length-prefixed');
const pushable = require('it-pushable');
const { pipe  } = require('it-pipe');
const { source: abortable  } = require('abortable-iterator');
const AbortController = require('abort-controller').default;
/**
 * @typedef {import('../stream-muxer/types').MuxedStream} MuxedStream
 * @typedef {import('peer-id')} PeerId
 * @typedef {import('it-pushable').Pushable<Uint8Array>} PushableStream
 */ /**
 * Thin wrapper around a peer's inbound / outbound pubsub streams
 */ class PeerStreams extends EventEmitter {
    /**
   * @param {object} properties - properties of the PeerStreams.
   * @param {PeerId} properties.id
   * @param {string} properties.protocol
   */ constructor({ id , protocol  }){
        super();
        /**
     * @type {import('peer-id')}
     */ this.id = id;
        /**
     * Established protocol
     *
     * @type {string}
     */ this.protocol = protocol;
        /**
     * The raw outbound stream, as retrieved from conn.newStream
     *
     * @private
     * @type {null|MuxedStream}
     */ this._rawOutboundStream = null;
        /**
     * The raw inbound stream, as retrieved from the callback from libp2p.handle
     *
     * @private
     * @type {null|MuxedStream}
     */ this._rawInboundStream = null;
        /**
     * An AbortController for controlled shutdown of the inbound stream
     *
     * @private
     * @type {AbortController}
     */ this._inboundAbortController = new AbortController();
        /**
     * Write stream -- its preferable to use the write method
     *
     * @type {null|PushableStream}
     */ this.outboundStream = null;
        /**
     * Read stream
     *
     * @type {null| AsyncIterable<Uint8Array>}
     */ this.inboundStream = null;
    }
    /**
   * Do we have a connection to read from?
   *
   * @type {boolean}
   */ get isReadable() {
        return Boolean(this.inboundStream);
    }
    /**
   * Do we have a connection to write on?
   *
   * @type {boolean}
   */ get isWritable() {
        return Boolean(this.outboundStream);
    }
    /**
   * Send a message to this peer.
   * Throws if there is no `stream` to write to available.
   *
   * @param {Uint8Array} data
   * @returns {void}
   */ write(data) {
        if (!this.outboundStream) {
            const id = this.id.toB58String();
            throw new Error('No writable connection to ' + id);
        }
        this.outboundStream.push(data);
    }
    /**
   * Attach a raw inbound stream and setup a read stream
   *
   * @param {MuxedStream} stream
   * @returns {AsyncIterable<Uint8Array>}
   */ attachInboundStream(stream) {
        // Create and attach a new inbound stream
        // The inbound stream is:
        // - abortable, set to only return on abort, rather than throw
        // - transformed with length-prefix transform
        this._rawInboundStream = stream;
        this.inboundStream = abortable(pipe(this._rawInboundStream, lp.decode()), this._inboundAbortController.signal, {
            returnOnAbort: true
        });
        this.emit('stream:inbound');
        return this.inboundStream;
    }
    /**
   * Attach a raw outbound stream and setup a write stream
   *
   * @param {MuxedStream} stream
   * @returns {Promise<void>}
   */ async attachOutboundStream(stream1) {
        // If an outbound stream already exists, gently close it
        const _prevStream = this.outboundStream;
        if (this.outboundStream) // End the stream without emitting a close event
        await this.outboundStream.end();
        this._rawOutboundStream = stream1;
        this.outboundStream = pushable({
            onEnd: (shouldEmit)=>{
                // close writable side of the stream
                this._rawOutboundStream && this._rawOutboundStream.reset && this._rawOutboundStream.reset();
                this._rawOutboundStream = null;
                this.outboundStream = null;
                if (shouldEmit) this.emit('close');
            }
        });
        pipe(this.outboundStream, lp.encode(), this._rawOutboundStream).catch(/** @param {Error} err */ (err)=>{
            log.error(err);
        });
        // Only emit if the connection is new
        if (!_prevStream) this.emit('stream:outbound');
    }
    /**
   * Closes the open connection to peer
   *
   * @returns {void}
   */ close() {
        // End the outbound stream
        if (this.outboundStream) this.outboundStream.end();
        // End the inbound stream
        if (this.inboundStream) this._inboundAbortController.abort();
        this._rawOutboundStream = null;
        this.outboundStream = null;
        this._rawInboundStream = null;
        this.inboundStream = null;
        this.emit('close');
    }
}
module.exports = PeerStreams;

},{"debug":"lWlU4","events":"bHM3D","it-length-prefixed":"2cvC1","it-pushable":"hRi4l","it-pipe":"4jukm","abortable-iterator":"3n79Y","abort-controller":"hVuZx"}],"2cvC1":[function(require,module,exports) {
'use strict';
/**
 * @typedef {import('./types').EncoderOptions} EncoderOptions
 * @typedef {import('./types').DecoderOptions} DecoderOptions
 */ exports.encode = require('./encode');
exports.decode = require('./decode');
exports.varintEncode = require('./varint-encode');
exports.varintDecode = require('./varint-decode');
exports.int32BEEncode = require('./int32BE-encode');
exports.int32BEDecode = require('./int32BE-decode');

},{"./encode":"aMc8n","./decode":"1E0a7","./varint-encode":"g5cTX","./varint-decode":"g546n","./int32BE-encode":"bULuG","./int32BE-decode":"3A8jY"}],"aMc8n":[function(require,module,exports) {
'use strict';
const { Buffer  } = require('buffer');
// @ts-ignore
const BufferList = require('bl/BufferList');
const varintEncode = require('./varint-encode');
const MIN_POOL_SIZE = 8 // Varint.encode(Number.MAX_SAFE_INTEGER).length
;
const DEFAULT_POOL_SIZE = 10240;
/**
 * @param {import('./types').EncoderOptions} [options]
 */ function encode(options) {
    options = options || {
    };
    const poolSize = Math.max(options.poolSize || DEFAULT_POOL_SIZE, options.minPoolSize || MIN_POOL_SIZE);
    const encodeLength = options.lengthEncoder || varintEncode;
    /**
   * @param {AsyncIterable<BufferList>} source
   */ const encoder = async function*(source) {
        let pool = Buffer.alloc(poolSize);
        let poolOffset = 0;
        for await (const chunk of source){
            encodeLength(chunk.length, pool, poolOffset);
            const encodedLength = pool.slice(poolOffset, poolOffset + encodeLength.bytes);
            poolOffset += encodeLength.bytes;
            if (pool.length - poolOffset < MIN_POOL_SIZE) {
                pool = Buffer.alloc(poolSize);
                poolOffset = 0;
            }
            yield new BufferList().append(encodedLength).append(chunk);
        // yield Buffer.concat([encodedLength, chunk])
        }
    };
    return encoder;
}
/**
 * @param {BufferList | Buffer} chunk
 * @param {import('./types').EncoderOptions} [options]
 */ encode.single = (chunk, options)=>{
    options = options || {
    };
    const encodeLength = options.lengthEncoder || varintEncode;
    return new BufferList([
        encodeLength(chunk.length),
        chunk.slice()
    ]);
};
module.exports = encode;
module.exports.MIN_POOL_SIZE = MIN_POOL_SIZE;
module.exports.DEFAULT_POOL_SIZE = DEFAULT_POOL_SIZE;

},{"buffer":"eKea5","bl/BufferList":"cK5XN","./varint-encode":"g5cTX"}],"g5cTX":[function(require,module,exports) {
'use strict';
// @ts-ignore no types
const Varint = require('varint');
const { Buffer  } = require('buffer');
/**
 * Encode the passed length `value` to the `target` buffer at the given `offset`
 *
 * @type {import('./types').LengthEncoderFunction}
 */ // @ts-ignore cannot declare expected bytes property
const varintEncode = (value, target, offset)=>{
    const ret = Varint.encode(value, target, offset);
    varintEncode.bytes = Varint.encode.bytes;
    // If no target, create Buffer from returned array
    return target || Buffer.from(ret);
};
module.exports = varintEncode;

},{"varint":"l84uL","buffer":"eKea5"}],"1E0a7":[function(require,module,exports) {
'use strict';
const { Buffer  } = require('buffer');
// @ts-ignore
const BufferList = require('bl/BufferList');
const varintDecode = require('./varint-decode');
// Maximum length of the length section of the message
const MAX_LENGTH_LENGTH = 8 // Varint.encode(Number.MAX_SAFE_INTEGER).length
;
// Maximum length of the data section of the message
const MAX_DATA_LENGTH = 4194304;
const Empty = Buffer.alloc(0);
const ReadModes = {
    LENGTH: 'readLength',
    DATA: 'readData'
};
const ReadHandlers = {
    /**
   * @param {BufferList} chunk
   * @param {BufferList} buffer
   * @param {import('./types').ReadState | undefined} state
   * @param {import('./types').DecoderOptions} options
   * @returns {import('./types').ReadResult}
   */ [ReadModes.LENGTH]: (chunk, buffer, state, options)=>{
        // console.log(ReadModes.LENGTH, chunk.length)
        buffer = buffer.append(chunk);
        let dataLength;
        try {
            dataLength = options.lengthDecoder(buffer);
        } catch (err) {
            if (buffer.length > options.maxLengthLength) throw Object.assign(err, {
                message: 'message length too long',
                code: 'ERR_MSG_LENGTH_TOO_LONG'
            });
            if (err instanceof RangeError) return {
                mode: ReadModes.LENGTH,
                buffer,
                chunk: undefined,
                state: undefined,
                data: undefined
            };
            throw err;
        }
        if (dataLength > options.maxDataLength) throw Object.assign(new Error('message data too long'), {
            code: 'ERR_MSG_DATA_TOO_LONG'
        });
        chunk = buffer.shallowSlice(options.lengthDecoder.bytes);
        buffer = new BufferList();
        if (options.onLength) options.onLength(dataLength);
        if (dataLength <= 0) {
            if (options.onData) options.onData(Empty);
            return {
                mode: ReadModes.LENGTH,
                chunk,
                buffer,
                data: Empty
            };
        }
        return {
            mode: ReadModes.DATA,
            chunk,
            buffer,
            state: {
                dataLength
            },
            data: undefined
        };
    },
    /**
   * @param {BufferList} chunk
   * @param {BufferList} buffer
   * @param {import('./types').ReadState | undefined} state
   * @param {import('./types').DecoderOptions} options
   * @returns {import('./types').ReadResult}
   */ [ReadModes.DATA]: (chunk, buffer, state, options)=>{
        // console.log(ReadModes.DATA, chunk.length)
        buffer = buffer.append(chunk);
        if (!state) throw new Error('state is required');
        if (buffer.length < state.dataLength) return {
            mode: ReadModes.DATA,
            buffer,
            state,
            chunk: undefined,
            data: undefined
        };
        const { dataLength  } = state;
        const data = buffer.shallowSlice(0, dataLength);
        const nextChunk = buffer.length > dataLength ? buffer.shallowSlice(dataLength) : undefined;
        buffer = new BufferList();
        if (options.onData) options.onData(data);
        return {
            mode: ReadModes.LENGTH,
            chunk: nextChunk,
            buffer,
            state: undefined,
            data
        };
    }
};
/**
 * @param {any} [options]
 */ function decode(options) {
    options = options || {
    };
    /**
   * @type {import('./types').DecoderOptions}
   */ const opts = {
        lengthDecoder: options.lengthDecoder || varintDecode,
        maxLengthLength: options.maxLengthLength || MAX_LENGTH_LENGTH,
        maxDataLength: options.maxDataLength || MAX_DATA_LENGTH,
        onLength: options.onLength,
        onData: options.onData
    };
    /**
   * @param {AsyncIterable<BufferList>} source
   */ const decoder = async function*(source) {
        let buffer = new BufferList();
        let mode = ReadModes.LENGTH // current parsing mode
        ;
        let state // accumulated state for the current mode
        ;
        for await (const chunk of source){
            /** @type {BufferList | undefined} */ let nextChunk = chunk;
            // Each chunk may contain multiple messages - keep calling handler for the
            // current parsing mode until all handlers have consumed the chunk.
            while(nextChunk){
                const result = ReadHandlers[mode](nextChunk, buffer, state, opts);
                mode = result.mode;
                nextChunk = result.chunk;
                buffer = result.buffer;
                state = result.state;
                if (result.data) yield result.data;
            }
        }
        if (buffer.length) throw Object.assign(new Error('unexpected end of input'), {
            code: 'ERR_UNEXPECTED_EOF'
        });
    };
    return decoder;
}
/**
 * @param {*} reader
 * @param {import('./types').DecoderOptions} [options]
 * @returns
 */ decode.fromReader = (reader, options)=>{
    let byteLength = 1 // Read single byte chunks until the length is known
    ;
    const varByteSource = {
        [Symbol.asyncIterator] () {
            return this;
        },
        next: async ()=>{
            try {
                return await reader.next(byteLength);
            } catch (err) {
                if (err.code === 'ERR_UNDER_READ') return {
                    done: true,
                    value: null
                };
                throw err;
            } finally{
                // Reset the byteLength so we continue to check for varints
                byteLength = 1;
            }
        }
    };
    /**
   * Once the length has been parsed, read chunk for that length
   *
   * @param {number} l
   */ const onLength = (l)=>{
        byteLength = l;
    };
    return decode({
        ...options || {
        },
        onLength
    })(varByteSource);
};
module.exports = decode;
module.exports.MAX_LENGTH_LENGTH = MAX_LENGTH_LENGTH;
module.exports.MAX_DATA_LENGTH = MAX_DATA_LENGTH;

},{"buffer":"eKea5","bl/BufferList":"cK5XN","./varint-decode":"g546n"}],"g546n":[function(require,module,exports) {
'use strict';
// @ts-ignore no types
const Varint = require('varint');
const { Buffer  } = require('buffer');
/**
 * @param {any} bl
 */ const toBufferProxy = (bl)=>new Proxy({
    }, {
        get: (_, prop)=>{
            // @ts-ignore magic
            return prop[0] === 'l' ? bl[prop] : bl.get(parseInt(prop));
        }
    })
;
/**
 * @type {import('./types').LengthDecoderFunction}
 */ // @ts-ignore cannot declare expected bytes property
const varintDecode = (data)=>{
    const len = Varint.decode(Buffer.isBuffer(data) ? data : toBufferProxy(data));
    varintDecode.bytes = Varint.decode.bytes;
    return len;
};
module.exports = varintDecode;

},{"varint":"l84uL","buffer":"eKea5"}],"bULuG":[function(require,module,exports) {
'use strict';
const { Buffer  } = require('buffer');
/**
 * @param {number} value
 * @param {Buffer} target
 * @param {number} offset
 */ const int32BEEncode = (value, target, offset)=>{
    target = target || Buffer.allocUnsafe(4);
    target.writeInt32BE(value, offset);
    return target;
};
int32BEEncode.bytes = 4 // Always because fixed length
;
module.exports = int32BEEncode;

},{"buffer":"eKea5"}],"3A8jY":[function(require,module,exports) {
'use strict';
/**
 * @param {import('buffer').Buffer} data
 */ const int32BEDecode = (data)=>{
    if (data.length < 4) throw RangeError('Could not decode int32BE');
    return data.readInt32BE(0);
};
int32BEDecode.bytes = 4 // Always because fixed length
;
module.exports = int32BEDecode;

},{}],"3n79Y":[function(require,module,exports) {
const getIterator = require('get-iterator');
const AbortError = require('./AbortError');
// Wrap an iterator to make it abortable, allow cleanup when aborted via onAbort
const toAbortableSource = (source, signal, options)=>toMultiAbortableSource(source, Array.isArray(signal) ? signal : [
        {
            signal,
            options
        }
    ])
;
const toMultiAbortableSource = (source, signals)=>{
    source = getIterator(source);
    signals = signals.map(({ signal , options  })=>({
            signal,
            options: options || {
            }
        })
    );
    async function* abortable() {
        let nextAbortHandler;
        const abortHandler = ()=>{
            if (nextAbortHandler) nextAbortHandler();
        };
        for (const { signal  } of signals)signal.addEventListener('abort', abortHandler);
        while(true){
            let result;
            try {
                for (const { signal: signal2 , options: options1  } of signals)if (signal2.aborted) {
                    const { abortMessage , abortCode  } = options1;
                    throw new AbortError(abortMessage, abortCode);
                }
                const abort = new Promise((resolve, reject)=>{
                    nextAbortHandler = ()=>{
                        const { options  } = signals.find(({ signal  })=>signal.aborted
                        );
                        const { abortMessage , abortCode  } = options;
                        reject(new AbortError(abortMessage, abortCode));
                    };
                });
                // Race the iterator and the abort signals
                result = await Promise.race([
                    abort,
                    source.next()
                ]);
                nextAbortHandler = null;
            } catch (err) {
                for (const { signal: signal3  } of signals)signal3.removeEventListener('abort', abortHandler);
                // Might not have been aborted by a known signal
                const aborter = signals.find(({ signal  })=>signal.aborted
                );
                const isKnownAborter = err.type === 'aborted' && aborter;
                if (isKnownAborter && aborter.options.onAbort) // Do any custom abort handling for the iterator
                await aborter.options.onAbort(source);
                // End the iterator if it is a generator
                if (typeof source.return === 'function') await source.return();
                if (isKnownAborter && aborter.options.returnOnAbort) return;
                throw err;
            }
            if (result.done) break;
            yield result.value;
        }
        for (const { signal: signal1  } of signals)signal1.removeEventListener('abort', abortHandler);
    }
    return abortable();
};
const toAbortableSink = (sink, signal, options)=>toMultiAbortableSink(sink, Array.isArray(signal) ? signal : [
        {
            signal,
            options
        }
    ])
;
const toMultiAbortableSink = (sink, signals)=>(source)=>sink(toMultiAbortableSource(source, signals))
;
const toAbortableDuplex = (duplex, signal, options)=>toMultiAbortableDuplex(duplex, Array.isArray(signal) ? signal : [
        {
            signal,
            options
        }
    ])
;
const toMultiAbortableDuplex = (duplex, signals)=>({
        sink: toMultiAbortableSink(duplex.sink, signals),
        source: toMultiAbortableSource(duplex.source, signals)
    })
;
module.exports = toAbortableSource;
module.exports.AbortError = AbortError;
module.exports.source = toAbortableSource;
module.exports.sink = toAbortableSink;
module.exports.transform = toAbortableSink;
module.exports.duplex = toAbortableDuplex;

},{"get-iterator":"lJJ8v","./AbortError":"lcUuQ"}],"lJJ8v":[function(require,module,exports) {
// If the passed object is an (async) iterable, then get the iterator
// If it's probably an iterator already (i.e. has next function) return it
// else throw
module.exports = function getIterator(obj) {
    if (obj) {
        if (typeof obj[Symbol.iterator] === 'function') return obj[Symbol.iterator]();
        if (typeof obj[Symbol.asyncIterator] === 'function') return obj[Symbol.asyncIterator]();
        if (typeof obj.next === 'function') return obj // probably an iterator
        ;
    }
    throw new Error('argument is not an iterator or iterable');
};

},{}],"lcUuQ":[function(require,module,exports) {
module.exports = class AbortError extends Error {
    constructor(message, code){
        super(message || 'The operation was aborted');
        this.type = 'aborted';
        this.code = code || 'ABORT_ERR';
    }
};

},{}],"6HHwm":[function(require,module,exports) {
'use strict';
/**
 * Enum for Signature Policy
 * Details how message signatures are produced/consumed
 */ const SignaturePolicy = {
    /**
   * On the producing side:
   * * Build messages with the signature, key (from may be enough for certain inlineable public key types), from and seqno fields.
   *
   * On the consuming side:
   * * Enforce the fields to be present, reject otherwise.
   * * Propagate only if the fields are valid and signature can be verified, reject otherwise.
   */ StrictSign: 'StrictSign',
    /**
   * On the producing side:
   * * Build messages without the signature, key, from and seqno fields.
   * * The corresponding protobuf key-value pairs are absent from the marshalled message, not just empty.
   *
   * On the consuming side:
   * * Enforce the fields to be absent, reject otherwise.
   * * Propagate only if the fields are absent, reject otherwise.
   * * A message_id function will not be able to use the above fields, and should instead rely on the data field. A commonplace strategy is to calculate a hash.
   */ StrictNoSign: 'StrictNoSign'
};
exports.SignaturePolicy = SignaturePolicy /**
 * @typedef {SignaturePolicy[keyof SignaturePolicy]} SignaturePolicyType
 */ ;

},{}],"3NUS2":[function(require,module,exports) {
'use strict';
// @ts-ignore libp2p crypto has no types
const randomBytes = require('libp2p-crypto/src/random-bytes');
const { toString: uint8ArrayToString  } = require('uint8arrays/to-string');
const { fromString: uint8ArrayFromString  } = require('uint8arrays/from-string');
const PeerId = require('peer-id');
const { sha256  } = require('multiformats/hashes/sha2');
/**
 * @typedef {import('./message/rpc').RPC.IMessage} IMessage
 * @typedef {import('./message/rpc').RPC.Message} Message
 * @typedef {import('.').InMessage} NormalizedIMessage
 */ /**
 * Generatea random sequence number.
 *
 * @returns {Uint8Array}
 * @private
 */ const randomSeqno = ()=>{
    return randomBytes(8);
};
/**
 * Generate a message id, based on the `from` and `seqno`.
 *
 * @param {Uint8Array|string} from
 * @param {Uint8Array} seqno
 * @returns {Uint8Array}
 * @private
 */ const msgId1 = (from, seqno)=>{
    let fromBytes;
    if (from instanceof Uint8Array) fromBytes = PeerId.createFromBytes(from).id;
    else fromBytes = PeerId.parse(from).id;
    const msgId = new Uint8Array(fromBytes.length + seqno.length);
    msgId.set(fromBytes, 0);
    msgId.set(seqno, fromBytes.length);
    return msgId;
};
/**
 * Generate a message id, based on message `data`.
 *
 * @param {Uint8Array} data
 * @private
 */ const noSignMsgId = (data)=>sha256.encode(data)
;
/**
 * Check if any member of the first set is also a member
 * of the second set.
 *
 * @param {Set<number>|Array<number>} a
 * @param {Set<number>|Array<number>} b
 * @returns {boolean}
 * @private
 */ const anyMatch = (a, b)=>{
    let bHas;
    if (Array.isArray(b)) /**
     * @param {number} val
     */ bHas = (val)=>b.indexOf(val) > -1
    ;
    else /**
     * @param {number} val
     */ bHas = (val)=>b.has(val)
    ;
    for (const val1 of a){
        if (bHas(val1)) return true;
    }
    return false;
};
/**
 * Make everything an array.
 *
 * @template T
 * @param {T|T[]} maybeArray
 * @returns {T[]}
 * @private
 */ const ensureArray = (maybeArray)=>{
    if (!Array.isArray(maybeArray)) return [
        maybeArray
    ];
    return maybeArray;
};
/**
 * Ensures `message.from` is base58 encoded
 *
 * @template {{from?:any}} T
 * @param {T & IMessage} message
 * @param {string} [peerId]
 * @returns {NormalizedIMessage}
 */ const normalizeInRpcMessage = (message, peerId)=>{
    /** @type {NormalizedIMessage} */ // @ts-ignore receivedFrom not yet defined
    const m = Object.assign({
    }, message);
    if (message.from instanceof Uint8Array) m.from = uint8ArrayToString(message.from, 'base58btc');
    if (peerId) m.receivedFrom = peerId;
    return m;
};
/**
 * @template {{from?:any, data?:any}} T
 *
 * @param {T & NormalizedIMessage} message
 * @returns {Message}
 */ const normalizeOutRpcMessage = (message)=>{
    /** @type {Message} */ // @ts-ignore from not yet defined
    const m = Object.assign({
    }, message);
    if (typeof message.from === 'string') m.from = uint8ArrayFromString(message.from, 'base58btc');
    if (typeof message.data === 'string') m.data = uint8ArrayFromString(message.data);
    return m;
};
module.exports = {
    randomSeqno,
    msgId: msgId1,
    noSignMsgId,
    anyMatch,
    ensureArray,
    normalizeInRpcMessage,
    normalizeOutRpcMessage
};

},{"libp2p-crypto/src/random-bytes":"1G1Dz","uint8arrays/to-string":"g3mCQ","uint8arrays/from-string":"lo45E","peer-id":"4VGWt","multiformats/hashes/sha2":"i8JnP"}],"36q3g":[function(require,module,exports) {
'use strict';
const PeerId = require('peer-id');
const { RPC  } = require('./rpc');
const { concat: uint8ArrayConcat  } = require('uint8arrays/concat');
const { fromString: uint8ArrayFromString  } = require('uint8arrays/from-string');
const SignPrefix = uint8ArrayFromString('libp2p-pubsub:');
const { normalizeOutRpcMessage  } = require('../utils');
/**
 * @typedef {import('..').InMessage}
 */ /**
 * Signs the provided message with the given `peerId`
 *
 * @param {PeerId} peerId
 * @param {InMessage} message
 * @returns {Promise<InMessage>}
 */ async function signMessage(peerId, message) {
    // Get the message in bytes, and prepend with the pubsub prefix
    const bytes = uint8ArrayConcat([
        SignPrefix,
        RPC.Message.encode(normalizeOutRpcMessage(message)).finish()
    ]);
    const signature = await peerId.privKey.sign(bytes);
    return {
        ...message,
        signature: signature,
        key: peerId.pubKey.bytes
    };
}
/**
 * Verifies the signature of the given message
 *
 * @param {InMessage} message
 * @returns {Promise<boolean>}
 */ async function verifySignature(message) {
    if (!message.signature) throw new Error('Message must contain a signature to be verified');
    if (!message.from) throw new Error('Message must contain a from property to be verified');
    // Get message sans the signature
    const bytes = uint8ArrayConcat([
        SignPrefix,
        RPC.Message.encode({
            ...message,
            from: PeerId.createFromB58String(message.from).toBytes(),
            signature: undefined,
            key: undefined
        }).finish()
    ]);
    // Get the public key
    const pubKey = await messagePublicKey(message);
    // verify the base message
    return pubKey.verify(bytes, message.signature);
}
/**
 * Returns the PublicKey associated with the given message.
 * If no, valid PublicKey can be retrieved an error will be returned.
 *
 * @param {InMessage} message
 * @returns {Promise<PublicKey>}
 */ async function messagePublicKey(message) {
    // should be available in the from property of the message (peer id)
    if (!message.from) throw new Error('Could not get the public key from the originator id');
    const from = PeerId.createFromB58String(message.from);
    if (message.key) {
        const keyPeerId = await PeerId.createFromPubKey(message.key);
        // the key belongs to the sender, return the key
        if (keyPeerId.equals(from)) return keyPeerId.pubKey;
        // We couldn't validate pubkey is from the originator, error
        throw new Error('Public Key does not match the originator');
    } else if (from.pubKey) return from.pubKey;
    else throw new Error('Could not get the public key from the originator id');
}
/**
 * @typedef {import('..').InMessage} InMessage
 * @typedef {import('libp2p-crypto').PublicKey} PublicKey
 */ module.exports = {
    messagePublicKey,
    signMessage,
    SignPrefix,
    verifySignature
};

},{"peer-id":"4VGWt","./rpc":"jUtL4","uint8arrays/concat":"fLIrL","uint8arrays/from-string":"lo45E","../utils":"3NUS2"}],"6J9JI":[function(require,module,exports) {
"use strict";
var __awaiter = this && this.__awaiter || function(thisArg, _arguments, P, generator) {
    function adopt(value) {
        return value instanceof P ? value : new P(function(resolve) {
            resolve(value);
        });
    }
    return new (P || (P = Promise))(function(resolve, reject) {
        function fulfilled(value) {
            try {
                step(generator.next(value));
            } catch (e) {
                reject(e);
            }
        }
        function rejected(value) {
            try {
                step(generator["throw"](value));
            } catch (e) {
                reject(e);
            }
        }
        function step(result) {
            result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
        }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.MessageCache = void 0;
const utils_1 = require("./utils");
class MessageCache {
    /**
     * @param {Number} gossip
     * @param {Number} history
     * @param {msgIdFn} msgIdFn a function that returns message id from a message
     *
     * @constructor
     */ constructor(gossip, history, msgIdFn){
        /**
         * @type {Map<string, RPC.Message>}
         */ this.msgs = new Map();
        this.peertx = new Map();
        /**
         * @type {Array<Array<CacheEntry>>}
         */ this.history = [];
        for(let i = 0; i < history; i++)this.history[i] = [];
        /**
         * @type {Number}
         */ this.gossip = gossip;
        /**
         * @type {Function}
         */ this.msgIdFn = msgIdFn;
    }
    /**
     * Adds a message to the current window and the cache
     *
     * @param {RPC.Message} msg
     * @returns {Promise<void>}
     */ put(msg) {
        return __awaiter(this, void 0, void 0, function*() {
            const msgID = yield this.getMsgId(msg);
            const msgIdStr = utils_1.messageIdToString(msgID);
            this.msgs.set(msgIdStr, msg);
            this.history[0].push({
                msgID,
                topics: msg.topicIDs
            });
        });
    }
    /**
     * Get message id of message.
     * @param {RPC.Message} msg
     * @returns {Promise<Uint8Array> | Uint8Array}
     */ getMsgId(msg1) {
        return this.msgIdFn(msg1);
    }
    /**
     * Retrieves a message from the cache by its ID, if it is still present
     *
     * @param {Uint8Array} msgID
     * @returns {Message}
     */ get(msgID) {
        return this.msgs.get(utils_1.messageIdToString(msgID));
    }
    /**
     * Retrieves a message from the cache by its ID, if it is present
     * for a specific peer.
     * Returns the message and the number of times the peer has requested the message
     *
     * @param {string} msgID
     * @param {string} p
     * @returns {[InMessage | undefined, number]}
     */ getForPeer(msgID1, p) {
        const msgIdStr = utils_1.messageIdToString(msgID1);
        const msg = this.msgs.get(msgIdStr);
        if (!msg) return [
            undefined,
            0
        ];
        let peertx = this.peertx.get(msgIdStr);
        if (!peertx) {
            peertx = new Map();
            this.peertx.set(msgIdStr, peertx);
        }
        const count = (peertx.get(p) || 0) + 1;
        peertx.set(p, count);
        return [
            msg,
            count
        ];
    }
    /**
     * Retrieves a list of message IDs for a given topic
     *
     * @param {String} topic
     *
     * @returns {Array<Uint8Array>}
     */ getGossipIDs(topic) {
        const msgIDs = [];
        for(let i = 0; i < this.gossip; i++)this.history[i].forEach((entry)=>{
            for (const t of entry.topics)if (t === topic) {
                msgIDs.push(entry.msgID);
                break;
            }
        });
        return msgIDs;
    }
    /**
     * Shifts the current window, discarding messages older than this.history.length of the cache
     *
     * @returns {void}
     */ shift() {
        const last = this.history[this.history.length - 1];
        last.forEach((entry)=>{
            const msgIdStr = utils_1.messageIdToString(entry.msgID);
            this.msgs.delete(msgIdStr);
            this.peertx.delete(msgIdStr);
        });
        this.history.pop();
        this.history.unshift([]);
    }
}
exports.MessageCache = MessageCache;

},{"./utils":"j1LCn"}],"j1LCn":[function(require,module,exports) {
"use strict";
var __createBinding = this && this.__createBinding || (Object.create ? function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    Object.defineProperty(o, k2, {
        enumerable: true,
        get: function() {
            return m[k];
        }
    });
} : function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
});
var __exportStar = this && this.__exportStar || function(m, exports) {
    for(var p in m)if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", {
    value: true
});
__exportStar(require("./create-gossip-rpc"), exports);
__exportStar(require("./shuffle"), exports);
__exportStar(require("./has-gossip-protocol"), exports);
__exportStar(require("./messageIdToString"), exports);

},{"./create-gossip-rpc":"9Waxk","./shuffle":"frBIi","./has-gossip-protocol":"4wSpx","./messageIdToString":"dqQmv"}],"9Waxk":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.createGossipRpc = void 0;
/**
 * Create a gossipsub RPC object
 * @param {Array<RPC.IMessage>} msgs
 * @param {Partial<RPC.IControlMessage>} control
 * @returns {IRPC}
 */ function createGossipRpc(msgs = [], control = {
}) {
    return {
        subscriptions: [],
        msgs: msgs,
        control: Object.assign({
            ihave: [],
            iwant: [],
            graft: [],
            prune: []
        }, control)
    };
}
exports.createGossipRpc = createGossipRpc;

},{}],"frBIi":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.shuffle = void 0;
/**
 * Pseudo-randomly shuffles an array
 *
 * Mutates the input array
 *
 * @param {Array} arr
 * @returns {Array}
 */ function shuffle(arr) {
    if (arr.length <= 1) return arr;
    const randInt = ()=>{
        return Math.floor(Math.random() * Math.floor(arr.length));
    };
    for(let i = 0; i < arr.length; i++){
        const j = randInt();
        const tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }
    return arr;
}
exports.shuffle = shuffle;

},{}],"4wSpx":[function(require,module,exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.hasGossipProtocol = void 0;
const constants_1 = require("../constants");
function hasGossipProtocol(protocol) {
    return protocol === constants_1.GossipsubIDv10 || protocol === constants_1.GossipsubIDv11;
}
exports.hasGossipProtocol = hasGossipProtocol;

},{"../constants":"dwqwi"}],"dwqwi":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.ERR_TOPIC_VALIDATOR_IGNORE = exports.ERR_TOPIC_VALIDATOR_REJECT = exports.TimeCacheDuration = exports.GossipsubSeenTTL = exports.GossipsubIWantFollowupTime = exports.GossipsubMaxIHaveMessages = exports.GossipsubMaxIHaveLength = exports.GossipsubGraftFloodThreshold = exports.GossipsubOpportunisticGraftPeers = exports.GossipsubOpportunisticGraftTicks = exports.GossipsubDirectConnectInitialDelay = exports.GossipsubDirectConnectTicks = exports.GossipsubConnectionTimeout = exports.GossipsubMaxPendingConnections = exports.GossipsubConnectors = exports.GossipsubPruneBackoffTicks = exports.GossipsubPruneBackoff = exports.GossipsubPrunePeers = exports.GossipsubFanoutTTL = exports.GossipsubHeartbeatInterval = exports.GossipsubHeartbeatInitialDelay = exports.GossipsubGossipRetransmission = exports.GossipsubGossipFactor = exports.GossipsubDlazy = exports.GossipsubHistoryGossip = exports.GossipsubHistoryLength = exports.GossipsubDout = exports.GossipsubDscore = exports.GossipsubDhi = exports.GossipsubDlo = exports.GossipsubD = exports.GossipsubIDv11 = exports.GossipsubIDv10 = exports.FloodsubID = exports.minute = exports.second = void 0;
exports.second = 1000;
exports.minute = 60 * exports.second;
// Protocol identifiers
exports.FloodsubID = '/floodsub/1.0.0';
/**
 * The protocol ID for version 1.0.0 of the Gossipsub protocol
 * It is advertised along with GossipsubIDv11 for backwards compatability
 */ exports.GossipsubIDv10 = '/meshsub/1.0.0';
/**
 * The protocol ID for version 1.1.0 of the Gossipsub protocol
 * See the spec for details about how v1.1.0 compares to v1.0.0:
 * https://github.com/libp2p/specs/blob/master/pubsub/gossipsub/gossipsub-v1.1.md
 */ exports.GossipsubIDv11 = '/meshsub/1.1.0';
// Overlay parameters
/**
 * GossipsubD sets the optimal degree for a Gossipsub topic mesh. For example, if GossipsubD == 6,
 * each peer will want to have about six peers in their mesh for each topic they're subscribed to.
 * GossipsubD should be set somewhere between GossipsubDlo and GossipsubDhi.
 */ exports.GossipsubD = 6;
/**
 * GossipsubDlo sets the lower bound on the number of peers we keep in a Gossipsub topic mesh.
 * If we have fewer than GossipsubDlo peers, we will attempt to graft some more into the mesh at
 * the next heartbeat.
 */ exports.GossipsubDlo = 4;
/**
 * GossipsubDhi sets the upper bound on the number of peers we keep in a Gossipsub topic mesh.
 * If we have more than GossipsubDhi peers, we will select some to prune from the mesh at the next heartbeat.
 */ exports.GossipsubDhi = 12;
/**
 * GossipsubDscore affects how peers are selected when pruning a mesh due to over subscription.
 * At least GossipsubDscore of the retained peers will be high-scoring, while the remainder are
 * chosen randomly.
 */ exports.GossipsubDscore = 4;
/**
 * GossipsubDout sets the quota for the number of outbound connections to maintain in a topic mesh.
 * When the mesh is pruned due to over subscription, we make sure that we have outbound connections
 * to at least GossipsubDout of the survivor peers. This prevents sybil attackers from overwhelming
 * our mesh with incoming connections.
 *
 * GossipsubDout must be set below GossipsubDlo, and must not exceed GossipsubD / 2.
 */ exports.GossipsubDout = 2;
// Gossip parameters
/**
 * GossipsubHistoryLength controls the size of the message cache used for gossip.
 * The message cache will remember messages for GossipsubHistoryLength heartbeats.
 */ exports.GossipsubHistoryLength = 5;
/**
 * GossipsubHistoryGossip controls how many cached message ids we will advertise in
 * IHAVE gossip messages. When asked for our seen message IDs, we will return
 * only those from the most recent GossipsubHistoryGossip heartbeats. The slack between
 * GossipsubHistoryGossip and GossipsubHistoryLength allows us to avoid advertising messages
 * that will be expired by the time they're requested.
 *
 * GossipsubHistoryGossip must be less than or equal to GossipsubHistoryLength to
 * avoid a runtime panic.
 */ exports.GossipsubHistoryGossip = 3;
/**
 * GossipsubDlazy affects how many peers we will emit gossip to at each heartbeat.
 * We will send gossip to at least GossipsubDlazy peers outside our mesh. The actual
 * number may be more, depending on GossipsubGossipFactor and how many peers we're
 * connected to.
 */ exports.GossipsubDlazy = 6;
/**
 * GossipsubGossipFactor affects how many peers we will emit gossip to at each heartbeat.
 * We will send gossip to GossipsubGossipFactor * (total number of non-mesh peers), or
 * GossipsubDlazy, whichever is greater.
 */ exports.GossipsubGossipFactor = 0.25;
/**
 * GossipsubGossipRetransmission controls how many times we will allow a peer to request
 * the same message id through IWANT gossip before we start ignoring them. This is designed
 * to prevent peers from spamming us with requests and wasting our resources.
 */ exports.GossipsubGossipRetransmission = 3;
// Heartbeat interval
/**
 * GossipsubHeartbeatInitialDelay is the short delay before the heartbeat timer begins
 * after the router is initialized.
 */ exports.GossipsubHeartbeatInitialDelay = 100;
/**
 * GossipsubHeartbeatInterval controls the time between heartbeats.
 */ exports.GossipsubHeartbeatInterval = exports.second;
/**
 * GossipsubFanoutTTL controls how long we keep track of the fanout state. If it's been
 * GossipsubFanoutTTL since we've published to a topic that we're not subscribed to,
 * we'll delete the fanout map for that topic.
 */ exports.GossipsubFanoutTTL = exports.minute;
/**
 * GossipsubPrunePeers controls the number of peers to include in prune Peer eXchange.
 * When we prune a peer that's eligible for PX (has a good score, etc), we will try to
 * send them signed peer records for up to GossipsubPrunePeers other peers that we
 * know of.
 */ exports.GossipsubPrunePeers = 16;
/**
 * GossipsubPruneBackoff controls the backoff time for pruned peers. This is how long
 * a peer must wait before attempting to graft into our mesh again after being pruned.
 * When pruning a peer, we send them our value of GossipsubPruneBackoff so they know
 * the minimum time to wait. Peers running older versions may not send a backoff time,
 * so if we receive a prune message without one, we will wait at least GossipsubPruneBackoff
 * before attempting to re-graft.
 */ exports.GossipsubPruneBackoff = exports.minute;
/**
 * GossipsubPruneBackoffTicks is the number of heartbeat ticks for attempting to prune expired
 * backoff timers.
 */ exports.GossipsubPruneBackoffTicks = 15;
/**
 * GossipsubConnectors controls the number of active connection attempts for peers obtained through PX.
 */ exports.GossipsubConnectors = 8;
/**
 * GossipsubMaxPendingConnections sets the maximum number of pending connections for peers attempted through px.
 */ exports.GossipsubMaxPendingConnections = 128;
/**
 * GossipsubConnectionTimeout controls the timeout for connection attempts.
 */ exports.GossipsubConnectionTimeout = 30 * exports.second;
/**
 * GossipsubDirectConnectTicks is the number of heartbeat ticks for attempting to reconnect direct peers
 * that are not currently connected.
 */ exports.GossipsubDirectConnectTicks = 300;
/**
 * GossipsubDirectConnectInitialDelay is the initial delay before opening connections to direct peers
 */ exports.GossipsubDirectConnectInitialDelay = exports.second;
/**
 * GossipsubOpportunisticGraftTicks is the number of heartbeat ticks for attempting to improve the mesh
 * with opportunistic grafting. Every GossipsubOpportunisticGraftTicks we will attempt to select some
 * high-scoring mesh peers to replace lower-scoring ones, if the median score of our mesh peers falls
 * below a threshold
 */ exports.GossipsubOpportunisticGraftTicks = 60;
/**
 * GossipsubOpportunisticGraftPeers is the number of peers to opportunistically graft.
 */ exports.GossipsubOpportunisticGraftPeers = 2;
/**
 * If a GRAFT comes before GossipsubGraftFloodThreshold has elapsed since the last PRUNE,
 * then there is an extra score penalty applied to the peer through P7.
 */ exports.GossipsubGraftFloodThreshold = 10 * exports.second;
/**
 * GossipsubMaxIHaveLength is the maximum number of messages to include in an IHAVE message.
 * Also controls the maximum number of IHAVE ids we will accept and request with IWANT from a
 * peer within a heartbeat, to protect from IHAVE floods. You should adjust this value from the
 * default if your system is pushing more than 5000 messages in GossipsubHistoryGossip heartbeats;
 * with the defaults this is 1666 messages/s.
 */ exports.GossipsubMaxIHaveLength = 5000;
/**
 * GossipsubMaxIHaveMessages is the maximum number of IHAVE messages to accept from a peer within a heartbeat.
 */ exports.GossipsubMaxIHaveMessages = 10;
/**
 * Time to wait for a message requested through IWANT following an IHAVE advertisement.
 * If the message is not received within this window, a broken promise is declared and
 * the router may apply bahavioural penalties.
 */ exports.GossipsubIWantFollowupTime = 3 * exports.second;
/**
 * Time in milliseconds to keep message ids in the seen cache
 */ exports.GossipsubSeenTTL = 30 * exports.second;
exports.TimeCacheDuration = 120000;
exports.ERR_TOPIC_VALIDATOR_REJECT = 'ERR_TOPIC_VALIDATOR_REJECT';
exports.ERR_TOPIC_VALIDATOR_IGNORE = 'ERR_TOPIC_VALIDATOR_IGNORE';

},{}],"dqQmv":[function(require,module,exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.messageIdToString = void 0;
const to_string_1 = require("uint8arrays/to-string");
function messageIdToString(msgId) {
    return to_string_1.toString(msgId, 'base64');
}
exports.messageIdToString = messageIdToString;

},{"uint8arrays/to-string":"g3mCQ"}],"bbhyk":[function(require,module,exports) {
/*eslint-disable*/ (function(global, factory) {
    /* AMD */ if (typeof define === 'function' && define.amd) define([
        "protobufjs/minimal"
    ], factory);
    else if (typeof require === 'function' && typeof module === 'object' && module && module.exports) module.exports = factory(require("protobufjs/minimal"));
})(this, function($protobuf) {
    "use strict";
    // Common aliases
    var $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util;
    // Exported root namespace
    var $root = $protobuf.roots["default"] || ($protobuf.roots["default"] = {
    });
    $root.RPC = (function() {
        /**
         * Properties of a RPC.
         * @exports IRPC
         * @interface IRPC
         * @property {Array.<RPC.ISubOpts>|null} [subscriptions] RPC subscriptions
         * @property {Array.<RPC.IMessage>|null} [msgs] RPC msgs
         * @property {RPC.IControlMessage|null} [control] RPC control
         */ /**
         * Constructs a new RPC.
         * @exports RPC
         * @classdesc Represents a RPC.
         * @implements IRPC
         * @constructor
         * @param {IRPC=} [p] Properties to set
         */ function RPC(p) {
            this.subscriptions = [];
            this.msgs = [];
            if (p) {
                for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
            }
        }
        /**
         * RPC subscriptions.
         * @member {Array.<RPC.ISubOpts>} subscriptions
         * @memberof RPC
         * @instance
         */ RPC.prototype.subscriptions = $util.emptyArray;
        /**
         * RPC msgs.
         * @member {Array.<RPC.IMessage>} msgs
         * @memberof RPC
         * @instance
         */ RPC.prototype.msgs = $util.emptyArray;
        /**
         * RPC control.
         * @member {RPC.IControlMessage|null|undefined} control
         * @memberof RPC
         * @instance
         */ RPC.prototype.control = null;
        // OneOf field names bound to virtual getters and setters
        var $oneOfFields1;
        /**
         * RPC _control.
         * @member {"control"|undefined} _control
         * @memberof RPC
         * @instance
         */ Object.defineProperty(RPC.prototype, "_control", {
            get: $util.oneOfGetter($oneOfFields1 = [
                "control"
            ]),
            set: $util.oneOfSetter($oneOfFields1)
        });
        /**
         * Encodes the specified RPC message. Does not implicitly {@link RPC.verify|verify} messages.
         * @function encode
         * @memberof RPC
         * @static
         * @param {IRPC} m RPC message or plain object to encode
         * @param {$protobuf.Writer} [w] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */ RPC.encode = function encode(m, w) {
            if (!w) w = $Writer.create();
            if (m.subscriptions != null && m.subscriptions.length) for(var i = 0; i < m.subscriptions.length; ++i)$root.RPC.SubOpts.encode(m.subscriptions[i], w.uint32(10).fork()).ldelim();
            if (m.msgs != null && m.msgs.length) for(var i = 0; i < m.msgs.length; ++i)$root.RPC.Message.encode(m.msgs[i], w.uint32(18).fork()).ldelim();
            if (m.control != null && Object.hasOwnProperty.call(m, "control")) $root.RPC.ControlMessage.encode(m.control, w.uint32(26).fork()).ldelim();
            return w;
        };
        /**
         * Decodes a RPC message from the specified reader or buffer.
         * @function decode
         * @memberof RPC
         * @static
         * @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
         * @param {number} [l] Message length if known beforehand
         * @returns {RPC} RPC
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */ RPC.decode = function decode(r, l) {
            if (!(r instanceof $Reader)) r = $Reader.create(r);
            var c = l === undefined ? r.len : r.pos + l, m = new $root.RPC();
            while(r.pos < c){
                var t = r.uint32();
                switch(t >>> 3){
                    case 1:
                        if (!(m.subscriptions && m.subscriptions.length)) m.subscriptions = [];
                        m.subscriptions.push($root.RPC.SubOpts.decode(r, r.uint32()));
                        break;
                    case 2:
                        if (!(m.msgs && m.msgs.length)) m.msgs = [];
                        m.msgs.push($root.RPC.Message.decode(r, r.uint32()));
                        break;
                    case 3:
                        m.control = $root.RPC.ControlMessage.decode(r, r.uint32());
                        break;
                    default:
                        r.skipType(t & 7);
                        break;
                }
            }
            return m;
        };
        /**
         * Creates a RPC message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof RPC
         * @static
         * @param {Object.<string,*>} d Plain object
         * @returns {RPC} RPC
         */ RPC.fromObject = function fromObject(d) {
            if (d instanceof $root.RPC) return d;
            var m = new $root.RPC();
            if (d.subscriptions) {
                if (!Array.isArray(d.subscriptions)) throw TypeError(".RPC.subscriptions: array expected");
                m.subscriptions = [];
                for(var i = 0; i < d.subscriptions.length; ++i){
                    if (typeof d.subscriptions[i] !== "object") throw TypeError(".RPC.subscriptions: object expected");
                    m.subscriptions[i] = $root.RPC.SubOpts.fromObject(d.subscriptions[i]);
                }
            }
            if (d.msgs) {
                if (!Array.isArray(d.msgs)) throw TypeError(".RPC.msgs: array expected");
                m.msgs = [];
                for(var i = 0; i < d.msgs.length; ++i){
                    if (typeof d.msgs[i] !== "object") throw TypeError(".RPC.msgs: object expected");
                    m.msgs[i] = $root.RPC.Message.fromObject(d.msgs[i]);
                }
            }
            if (d.control != null) {
                if (typeof d.control !== "object") throw TypeError(".RPC.control: object expected");
                m.control = $root.RPC.ControlMessage.fromObject(d.control);
            }
            return m;
        };
        /**
         * Creates a plain object from a RPC message. Also converts values to other types if specified.
         * @function toObject
         * @memberof RPC
         * @static
         * @param {RPC} m RPC
         * @param {$protobuf.IConversionOptions} [o] Conversion options
         * @returns {Object.<string,*>} Plain object
         */ RPC.toObject = function toObject(m, o) {
            if (!o) o = {
            };
            var d = {
            };
            if (o.arrays || o.defaults) {
                d.subscriptions = [];
                d.msgs = [];
            }
            if (m.subscriptions && m.subscriptions.length) {
                d.subscriptions = [];
                for(var j = 0; j < m.subscriptions.length; ++j)d.subscriptions[j] = $root.RPC.SubOpts.toObject(m.subscriptions[j], o);
            }
            if (m.msgs && m.msgs.length) {
                d.msgs = [];
                for(var j = 0; j < m.msgs.length; ++j)d.msgs[j] = $root.RPC.Message.toObject(m.msgs[j], o);
            }
            if (m.control != null && m.hasOwnProperty("control")) {
                d.control = $root.RPC.ControlMessage.toObject(m.control, o);
                if (o.oneofs) d._control = "control";
            }
            return d;
        };
        /**
         * Converts this RPC to JSON.
         * @function toJSON
         * @memberof RPC
         * @instance
         * @returns {Object.<string,*>} JSON object
         */ RPC.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };
        RPC.SubOpts = (function() {
            /**
             * Properties of a SubOpts.
             * @memberof RPC
             * @interface ISubOpts
             * @property {boolean|null} [subscribe] SubOpts subscribe
             * @property {string|null} [topicID] SubOpts topicID
             */ /**
             * Constructs a new SubOpts.
             * @memberof RPC
             * @classdesc Represents a SubOpts.
             * @implements ISubOpts
             * @constructor
             * @param {RPC.ISubOpts=} [p] Properties to set
             */ function SubOpts(p) {
                if (p) {
                    for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
                }
            }
            /**
             * SubOpts subscribe.
             * @member {boolean|null|undefined} subscribe
             * @memberof RPC.SubOpts
             * @instance
             */ SubOpts.prototype.subscribe = null;
            /**
             * SubOpts topicID.
             * @member {string|null|undefined} topicID
             * @memberof RPC.SubOpts
             * @instance
             */ SubOpts.prototype.topicID = null;
            // OneOf field names bound to virtual getters and setters
            var $oneOfFields;
            /**
             * SubOpts _subscribe.
             * @member {"subscribe"|undefined} _subscribe
             * @memberof RPC.SubOpts
             * @instance
             */ Object.defineProperty(SubOpts.prototype, "_subscribe", {
                get: $util.oneOfGetter($oneOfFields = [
                    "subscribe"
                ]),
                set: $util.oneOfSetter($oneOfFields)
            });
            /**
             * SubOpts _topicID.
             * @member {"topicID"|undefined} _topicID
             * @memberof RPC.SubOpts
             * @instance
             */ Object.defineProperty(SubOpts.prototype, "_topicID", {
                get: $util.oneOfGetter($oneOfFields = [
                    "topicID"
                ]),
                set: $util.oneOfSetter($oneOfFields)
            });
            /**
             * Encodes the specified SubOpts message. Does not implicitly {@link RPC.SubOpts.verify|verify} messages.
             * @function encode
             * @memberof RPC.SubOpts
             * @static
             * @param {RPC.ISubOpts} m SubOpts message or plain object to encode
             * @param {$protobuf.Writer} [w] Writer to encode to
             * @returns {$protobuf.Writer} Writer
             */ SubOpts.encode = function encode(m, w) {
                if (!w) w = $Writer.create();
                if (m.subscribe != null && Object.hasOwnProperty.call(m, "subscribe")) w.uint32(8).bool(m.subscribe);
                if (m.topicID != null && Object.hasOwnProperty.call(m, "topicID")) w.uint32(18).string(m.topicID);
                return w;
            };
            /**
             * Decodes a SubOpts message from the specified reader or buffer.
             * @function decode
             * @memberof RPC.SubOpts
             * @static
             * @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
             * @param {number} [l] Message length if known beforehand
             * @returns {RPC.SubOpts} SubOpts
             * @throws {Error} If the payload is not a reader or valid buffer
             * @throws {$protobuf.util.ProtocolError} If required fields are missing
             */ SubOpts.decode = function decode(r, l) {
                if (!(r instanceof $Reader)) r = $Reader.create(r);
                var c = l === undefined ? r.len : r.pos + l, m = new $root.RPC.SubOpts();
                while(r.pos < c){
                    var t = r.uint32();
                    switch(t >>> 3){
                        case 1:
                            m.subscribe = r.bool();
                            break;
                        case 2:
                            m.topicID = r.string();
                            break;
                        default:
                            r.skipType(t & 7);
                            break;
                    }
                }
                return m;
            };
            /**
             * Creates a SubOpts message from a plain object. Also converts values to their respective internal types.
             * @function fromObject
             * @memberof RPC.SubOpts
             * @static
             * @param {Object.<string,*>} d Plain object
             * @returns {RPC.SubOpts} SubOpts
             */ SubOpts.fromObject = function fromObject(d) {
                if (d instanceof $root.RPC.SubOpts) return d;
                var m = new $root.RPC.SubOpts();
                if (d.subscribe != null) m.subscribe = Boolean(d.subscribe);
                if (d.topicID != null) m.topicID = String(d.topicID);
                return m;
            };
            /**
             * Creates a plain object from a SubOpts message. Also converts values to other types if specified.
             * @function toObject
             * @memberof RPC.SubOpts
             * @static
             * @param {RPC.SubOpts} m SubOpts
             * @param {$protobuf.IConversionOptions} [o] Conversion options
             * @returns {Object.<string,*>} Plain object
             */ SubOpts.toObject = function toObject(m, o) {
                if (!o) o = {
                };
                var d = {
                };
                if (m.subscribe != null && m.hasOwnProperty("subscribe")) {
                    d.subscribe = m.subscribe;
                    if (o.oneofs) d._subscribe = "subscribe";
                }
                if (m.topicID != null && m.hasOwnProperty("topicID")) {
                    d.topicID = m.topicID;
                    if (o.oneofs) d._topicID = "topicID";
                }
                return d;
            };
            /**
             * Converts this SubOpts to JSON.
             * @function toJSON
             * @memberof RPC.SubOpts
             * @instance
             * @returns {Object.<string,*>} JSON object
             */ SubOpts.prototype.toJSON = function toJSON() {
                return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
            };
            return SubOpts;
        })();
        RPC.Message = (function() {
            /**
             * Properties of a Message.
             * @memberof RPC
             * @interface IMessage
             * @property {Uint8Array|null} [from] Message from
             * @property {Uint8Array|null} [data] Message data
             * @property {Uint8Array|null} [seqno] Message seqno
             * @property {Array.<string>|null} [topicIDs] Message topicIDs
             * @property {Uint8Array|null} [signature] Message signature
             * @property {Uint8Array|null} [key] Message key
             */ /**
             * Constructs a new Message.
             * @memberof RPC
             * @classdesc Represents a Message.
             * @implements IMessage
             * @constructor
             * @param {RPC.IMessage=} [p] Properties to set
             */ function Message(p) {
                this.topicIDs = [];
                if (p) {
                    for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
                }
            }
            /**
             * Message from.
             * @member {Uint8Array|null|undefined} from
             * @memberof RPC.Message
             * @instance
             */ Message.prototype.from = null;
            /**
             * Message data.
             * @member {Uint8Array|null|undefined} data
             * @memberof RPC.Message
             * @instance
             */ Message.prototype.data = null;
            /**
             * Message seqno.
             * @member {Uint8Array|null|undefined} seqno
             * @memberof RPC.Message
             * @instance
             */ Message.prototype.seqno = null;
            /**
             * Message topicIDs.
             * @member {Array.<string>} topicIDs
             * @memberof RPC.Message
             * @instance
             */ Message.prototype.topicIDs = $util.emptyArray;
            /**
             * Message signature.
             * @member {Uint8Array|null|undefined} signature
             * @memberof RPC.Message
             * @instance
             */ Message.prototype.signature = null;
            /**
             * Message key.
             * @member {Uint8Array|null|undefined} key
             * @memberof RPC.Message
             * @instance
             */ Message.prototype.key = null;
            // OneOf field names bound to virtual getters and setters
            var $oneOfFields;
            /**
             * Message _from.
             * @member {"from"|undefined} _from
             * @memberof RPC.Message
             * @instance
             */ Object.defineProperty(Message.prototype, "_from", {
                get: $util.oneOfGetter($oneOfFields = [
                    "from"
                ]),
                set: $util.oneOfSetter($oneOfFields)
            });
            /**
             * Message _data.
             * @member {"data"|undefined} _data
             * @memberof RPC.Message
             * @instance
             */ Object.defineProperty(Message.prototype, "_data", {
                get: $util.oneOfGetter($oneOfFields = [
                    "data"
                ]),
                set: $util.oneOfSetter($oneOfFields)
            });
            /**
             * Message _seqno.
             * @member {"seqno"|undefined} _seqno
             * @memberof RPC.Message
             * @instance
             */ Object.defineProperty(Message.prototype, "_seqno", {
                get: $util.oneOfGetter($oneOfFields = [
                    "seqno"
                ]),
                set: $util.oneOfSetter($oneOfFields)
            });
            /**
             * Message _signature.
             * @member {"signature"|undefined} _signature
             * @memberof RPC.Message
             * @instance
             */ Object.defineProperty(Message.prototype, "_signature", {
                get: $util.oneOfGetter($oneOfFields = [
                    "signature"
                ]),
                set: $util.oneOfSetter($oneOfFields)
            });
            /**
             * Message _key.
             * @member {"key"|undefined} _key
             * @memberof RPC.Message
             * @instance
             */ Object.defineProperty(Message.prototype, "_key", {
                get: $util.oneOfGetter($oneOfFields = [
                    "key"
                ]),
                set: $util.oneOfSetter($oneOfFields)
            });
            /**
             * Encodes the specified Message message. Does not implicitly {@link RPC.Message.verify|verify} messages.
             * @function encode
             * @memberof RPC.Message
             * @static
             * @param {RPC.IMessage} m Message message or plain object to encode
             * @param {$protobuf.Writer} [w] Writer to encode to
             * @returns {$protobuf.Writer} Writer
             */ Message.encode = function encode(m, w) {
                if (!w) w = $Writer.create();
                if (m.from != null && Object.hasOwnProperty.call(m, "from")) w.uint32(10).bytes(m.from);
                if (m.data != null && Object.hasOwnProperty.call(m, "data")) w.uint32(18).bytes(m.data);
                if (m.seqno != null && Object.hasOwnProperty.call(m, "seqno")) w.uint32(26).bytes(m.seqno);
                if (m.topicIDs != null && m.topicIDs.length) for(var i = 0; i < m.topicIDs.length; ++i)w.uint32(34).string(m.topicIDs[i]);
                if (m.signature != null && Object.hasOwnProperty.call(m, "signature")) w.uint32(42).bytes(m.signature);
                if (m.key != null && Object.hasOwnProperty.call(m, "key")) w.uint32(50).bytes(m.key);
                return w;
            };
            /**
             * Decodes a Message message from the specified reader or buffer.
             * @function decode
             * @memberof RPC.Message
             * @static
             * @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
             * @param {number} [l] Message length if known beforehand
             * @returns {RPC.Message} Message
             * @throws {Error} If the payload is not a reader or valid buffer
             * @throws {$protobuf.util.ProtocolError} If required fields are missing
             */ Message.decode = function decode(r, l) {
                if (!(r instanceof $Reader)) r = $Reader.create(r);
                var c = l === undefined ? r.len : r.pos + l, m = new $root.RPC.Message();
                while(r.pos < c){
                    var t = r.uint32();
                    switch(t >>> 3){
                        case 1:
                            m.from = r.bytes();
                            break;
                        case 2:
                            m.data = r.bytes();
                            break;
                        case 3:
                            m.seqno = r.bytes();
                            break;
                        case 4:
                            if (!(m.topicIDs && m.topicIDs.length)) m.topicIDs = [];
                            m.topicIDs.push(r.string());
                            break;
                        case 5:
                            m.signature = r.bytes();
                            break;
                        case 6:
                            m.key = r.bytes();
                            break;
                        default:
                            r.skipType(t & 7);
                            break;
                    }
                }
                return m;
            };
            /**
             * Creates a Message message from a plain object. Also converts values to their respective internal types.
             * @function fromObject
             * @memberof RPC.Message
             * @static
             * @param {Object.<string,*>} d Plain object
             * @returns {RPC.Message} Message
             */ Message.fromObject = function fromObject(d) {
                if (d instanceof $root.RPC.Message) return d;
                var m = new $root.RPC.Message();
                if (d.from != null) {
                    if (typeof d.from === "string") $util.base64.decode(d.from, m.from = $util.newBuffer($util.base64.length(d.from)), 0);
                    else if (d.from.length) m.from = d.from;
                }
                if (d.data != null) {
                    if (typeof d.data === "string") $util.base64.decode(d.data, m.data = $util.newBuffer($util.base64.length(d.data)), 0);
                    else if (d.data.length) m.data = d.data;
                }
                if (d.seqno != null) {
                    if (typeof d.seqno === "string") $util.base64.decode(d.seqno, m.seqno = $util.newBuffer($util.base64.length(d.seqno)), 0);
                    else if (d.seqno.length) m.seqno = d.seqno;
                }
                if (d.topicIDs) {
                    if (!Array.isArray(d.topicIDs)) throw TypeError(".RPC.Message.topicIDs: array expected");
                    m.topicIDs = [];
                    for(var i = 0; i < d.topicIDs.length; ++i)m.topicIDs[i] = String(d.topicIDs[i]);
                }
                if (d.signature != null) {
                    if (typeof d.signature === "string") $util.base64.decode(d.signature, m.signature = $util.newBuffer($util.base64.length(d.signature)), 0);
                    else if (d.signature.length) m.signature = d.signature;
                }
                if (d.key != null) {
                    if (typeof d.key === "string") $util.base64.decode(d.key, m.key = $util.newBuffer($util.base64.length(d.key)), 0);
                    else if (d.key.length) m.key = d.key;
                }
                return m;
            };
            /**
             * Creates a plain object from a Message message. Also converts values to other types if specified.
             * @function toObject
             * @memberof RPC.Message
             * @static
             * @param {RPC.Message} m Message
             * @param {$protobuf.IConversionOptions} [o] Conversion options
             * @returns {Object.<string,*>} Plain object
             */ Message.toObject = function toObject(m, o) {
                if (!o) o = {
                };
                var d = {
                };
                if (o.arrays || o.defaults) d.topicIDs = [];
                if (m.from != null && m.hasOwnProperty("from")) {
                    d.from = o.bytes === String ? $util.base64.encode(m.from, 0, m.from.length) : o.bytes === Array ? Array.prototype.slice.call(m.from) : m.from;
                    if (o.oneofs) d._from = "from";
                }
                if (m.data != null && m.hasOwnProperty("data")) {
                    d.data = o.bytes === String ? $util.base64.encode(m.data, 0, m.data.length) : o.bytes === Array ? Array.prototype.slice.call(m.data) : m.data;
                    if (o.oneofs) d._data = "data";
                }
                if (m.seqno != null && m.hasOwnProperty("seqno")) {
                    d.seqno = o.bytes === String ? $util.base64.encode(m.seqno, 0, m.seqno.length) : o.bytes === Array ? Array.prototype.slice.call(m.seqno) : m.seqno;
                    if (o.oneofs) d._seqno = "seqno";
                }
                if (m.topicIDs && m.topicIDs.length) {
                    d.topicIDs = [];
                    for(var j = 0; j < m.topicIDs.length; ++j)d.topicIDs[j] = m.topicIDs[j];
                }
                if (m.signature != null && m.hasOwnProperty("signature")) {
                    d.signature = o.bytes === String ? $util.base64.encode(m.signature, 0, m.signature.length) : o.bytes === Array ? Array.prototype.slice.call(m.signature) : m.signature;
                    if (o.oneofs) d._signature = "signature";
                }
                if (m.key != null && m.hasOwnProperty("key")) {
                    d.key = o.bytes === String ? $util.base64.encode(m.key, 0, m.key.length) : o.bytes === Array ? Array.prototype.slice.call(m.key) : m.key;
                    if (o.oneofs) d._key = "key";
                }
                return d;
            };
            /**
             * Converts this Message to JSON.
             * @function toJSON
             * @memberof RPC.Message
             * @instance
             * @returns {Object.<string,*>} JSON object
             */ Message.prototype.toJSON = function toJSON() {
                return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
            };
            return Message;
        })();
        RPC.ControlMessage = (function() {
            /**
             * Properties of a ControlMessage.
             * @memberof RPC
             * @interface IControlMessage
             * @property {Array.<RPC.IControlIHave>|null} [ihave] ControlMessage ihave
             * @property {Array.<RPC.IControlIWant>|null} [iwant] ControlMessage iwant
             * @property {Array.<RPC.IControlGraft>|null} [graft] ControlMessage graft
             * @property {Array.<RPC.IControlPrune>|null} [prune] ControlMessage prune
             */ /**
             * Constructs a new ControlMessage.
             * @memberof RPC
             * @classdesc Represents a ControlMessage.
             * @implements IControlMessage
             * @constructor
             * @param {RPC.IControlMessage=} [p] Properties to set
             */ function ControlMessage(p) {
                this.ihave = [];
                this.iwant = [];
                this.graft = [];
                this.prune = [];
                if (p) {
                    for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
                }
            }
            /**
             * ControlMessage ihave.
             * @member {Array.<RPC.IControlIHave>} ihave
             * @memberof RPC.ControlMessage
             * @instance
             */ ControlMessage.prototype.ihave = $util.emptyArray;
            /**
             * ControlMessage iwant.
             * @member {Array.<RPC.IControlIWant>} iwant
             * @memberof RPC.ControlMessage
             * @instance
             */ ControlMessage.prototype.iwant = $util.emptyArray;
            /**
             * ControlMessage graft.
             * @member {Array.<RPC.IControlGraft>} graft
             * @memberof RPC.ControlMessage
             * @instance
             */ ControlMessage.prototype.graft = $util.emptyArray;
            /**
             * ControlMessage prune.
             * @member {Array.<RPC.IControlPrune>} prune
             * @memberof RPC.ControlMessage
             * @instance
             */ ControlMessage.prototype.prune = $util.emptyArray;
            /**
             * Encodes the specified ControlMessage message. Does not implicitly {@link RPC.ControlMessage.verify|verify} messages.
             * @function encode
             * @memberof RPC.ControlMessage
             * @static
             * @param {RPC.IControlMessage} m ControlMessage message or plain object to encode
             * @param {$protobuf.Writer} [w] Writer to encode to
             * @returns {$protobuf.Writer} Writer
             */ ControlMessage.encode = function encode(m, w) {
                if (!w) w = $Writer.create();
                if (m.ihave != null && m.ihave.length) for(var i = 0; i < m.ihave.length; ++i)$root.RPC.ControlIHave.encode(m.ihave[i], w.uint32(10).fork()).ldelim();
                if (m.iwant != null && m.iwant.length) for(var i = 0; i < m.iwant.length; ++i)$root.RPC.ControlIWant.encode(m.iwant[i], w.uint32(18).fork()).ldelim();
                if (m.graft != null && m.graft.length) for(var i = 0; i < m.graft.length; ++i)$root.RPC.ControlGraft.encode(m.graft[i], w.uint32(26).fork()).ldelim();
                if (m.prune != null && m.prune.length) for(var i = 0; i < m.prune.length; ++i)$root.RPC.ControlPrune.encode(m.prune[i], w.uint32(34).fork()).ldelim();
                return w;
            };
            /**
             * Decodes a ControlMessage message from the specified reader or buffer.
             * @function decode
             * @memberof RPC.ControlMessage
             * @static
             * @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
             * @param {number} [l] Message length if known beforehand
             * @returns {RPC.ControlMessage} ControlMessage
             * @throws {Error} If the payload is not a reader or valid buffer
             * @throws {$protobuf.util.ProtocolError} If required fields are missing
             */ ControlMessage.decode = function decode(r, l) {
                if (!(r instanceof $Reader)) r = $Reader.create(r);
                var c = l === undefined ? r.len : r.pos + l, m = new $root.RPC.ControlMessage();
                while(r.pos < c){
                    var t = r.uint32();
                    switch(t >>> 3){
                        case 1:
                            if (!(m.ihave && m.ihave.length)) m.ihave = [];
                            m.ihave.push($root.RPC.ControlIHave.decode(r, r.uint32()));
                            break;
                        case 2:
                            if (!(m.iwant && m.iwant.length)) m.iwant = [];
                            m.iwant.push($root.RPC.ControlIWant.decode(r, r.uint32()));
                            break;
                        case 3:
                            if (!(m.graft && m.graft.length)) m.graft = [];
                            m.graft.push($root.RPC.ControlGraft.decode(r, r.uint32()));
                            break;
                        case 4:
                            if (!(m.prune && m.prune.length)) m.prune = [];
                            m.prune.push($root.RPC.ControlPrune.decode(r, r.uint32()));
                            break;
                        default:
                            r.skipType(t & 7);
                            break;
                    }
                }
                return m;
            };
            /**
             * Creates a ControlMessage message from a plain object. Also converts values to their respective internal types.
             * @function fromObject
             * @memberof RPC.ControlMessage
             * @static
             * @param {Object.<string,*>} d Plain object
             * @returns {RPC.ControlMessage} ControlMessage
             */ ControlMessage.fromObject = function fromObject(d) {
                if (d instanceof $root.RPC.ControlMessage) return d;
                var m = new $root.RPC.ControlMessage();
                if (d.ihave) {
                    if (!Array.isArray(d.ihave)) throw TypeError(".RPC.ControlMessage.ihave: array expected");
                    m.ihave = [];
                    for(var i = 0; i < d.ihave.length; ++i){
                        if (typeof d.ihave[i] !== "object") throw TypeError(".RPC.ControlMessage.ihave: object expected");
                        m.ihave[i] = $root.RPC.ControlIHave.fromObject(d.ihave[i]);
                    }
                }
                if (d.iwant) {
                    if (!Array.isArray(d.iwant)) throw TypeError(".RPC.ControlMessage.iwant: array expected");
                    m.iwant = [];
                    for(var i = 0; i < d.iwant.length; ++i){
                        if (typeof d.iwant[i] !== "object") throw TypeError(".RPC.ControlMessage.iwant: object expected");
                        m.iwant[i] = $root.RPC.ControlIWant.fromObject(d.iwant[i]);
                    }
                }
                if (d.graft) {
                    if (!Array.isArray(d.graft)) throw TypeError(".RPC.ControlMessage.graft: array expected");
                    m.graft = [];
                    for(var i = 0; i < d.graft.length; ++i){
                        if (typeof d.graft[i] !== "object") throw TypeError(".RPC.ControlMessage.graft: object expected");
                        m.graft[i] = $root.RPC.ControlGraft.fromObject(d.graft[i]);
                    }
                }
                if (d.prune) {
                    if (!Array.isArray(d.prune)) throw TypeError(".RPC.ControlMessage.prune: array expected");
                    m.prune = [];
                    for(var i = 0; i < d.prune.length; ++i){
                        if (typeof d.prune[i] !== "object") throw TypeError(".RPC.ControlMessage.prune: object expected");
                        m.prune[i] = $root.RPC.ControlPrune.fromObject(d.prune[i]);
                    }
                }
                return m;
            };
            /**
             * Creates a plain object from a ControlMessage message. Also converts values to other types if specified.
             * @function toObject
             * @memberof RPC.ControlMessage
             * @static
             * @param {RPC.ControlMessage} m ControlMessage
             * @param {$protobuf.IConversionOptions} [o] Conversion options
             * @returns {Object.<string,*>} Plain object
             */ ControlMessage.toObject = function toObject(m, o) {
                if (!o) o = {
                };
                var d = {
                };
                if (o.arrays || o.defaults) {
                    d.ihave = [];
                    d.iwant = [];
                    d.graft = [];
                    d.prune = [];
                }
                if (m.ihave && m.ihave.length) {
                    d.ihave = [];
                    for(var j = 0; j < m.ihave.length; ++j)d.ihave[j] = $root.RPC.ControlIHave.toObject(m.ihave[j], o);
                }
                if (m.iwant && m.iwant.length) {
                    d.iwant = [];
                    for(var j = 0; j < m.iwant.length; ++j)d.iwant[j] = $root.RPC.ControlIWant.toObject(m.iwant[j], o);
                }
                if (m.graft && m.graft.length) {
                    d.graft = [];
                    for(var j = 0; j < m.graft.length; ++j)d.graft[j] = $root.RPC.ControlGraft.toObject(m.graft[j], o);
                }
                if (m.prune && m.prune.length) {
                    d.prune = [];
                    for(var j = 0; j < m.prune.length; ++j)d.prune[j] = $root.RPC.ControlPrune.toObject(m.prune[j], o);
                }
                return d;
            };
            /**
             * Converts this ControlMessage to JSON.
             * @function toJSON
             * @memberof RPC.ControlMessage
             * @instance
             * @returns {Object.<string,*>} JSON object
             */ ControlMessage.prototype.toJSON = function toJSON() {
                return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
            };
            return ControlMessage;
        })();
        RPC.ControlIHave = (function() {
            /**
             * Properties of a ControlIHave.
             * @memberof RPC
             * @interface IControlIHave
             * @property {string|null} [topicID] ControlIHave topicID
             * @property {Array.<Uint8Array>|null} [messageIDs] ControlIHave messageIDs
             */ /**
             * Constructs a new ControlIHave.
             * @memberof RPC
             * @classdesc Represents a ControlIHave.
             * @implements IControlIHave
             * @constructor
             * @param {RPC.IControlIHave=} [p] Properties to set
             */ function ControlIHave(p) {
                this.messageIDs = [];
                if (p) {
                    for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
                }
            }
            /**
             * ControlIHave topicID.
             * @member {string|null|undefined} topicID
             * @memberof RPC.ControlIHave
             * @instance
             */ ControlIHave.prototype.topicID = null;
            /**
             * ControlIHave messageIDs.
             * @member {Array.<Uint8Array>} messageIDs
             * @memberof RPC.ControlIHave
             * @instance
             */ ControlIHave.prototype.messageIDs = $util.emptyArray;
            // OneOf field names bound to virtual getters and setters
            var $oneOfFields;
            /**
             * ControlIHave _topicID.
             * @member {"topicID"|undefined} _topicID
             * @memberof RPC.ControlIHave
             * @instance
             */ Object.defineProperty(ControlIHave.prototype, "_topicID", {
                get: $util.oneOfGetter($oneOfFields = [
                    "topicID"
                ]),
                set: $util.oneOfSetter($oneOfFields)
            });
            /**
             * Encodes the specified ControlIHave message. Does not implicitly {@link RPC.ControlIHave.verify|verify} messages.
             * @function encode
             * @memberof RPC.ControlIHave
             * @static
             * @param {RPC.IControlIHave} m ControlIHave message or plain object to encode
             * @param {$protobuf.Writer} [w] Writer to encode to
             * @returns {$protobuf.Writer} Writer
             */ ControlIHave.encode = function encode(m, w) {
                if (!w) w = $Writer.create();
                if (m.topicID != null && Object.hasOwnProperty.call(m, "topicID")) w.uint32(10).string(m.topicID);
                if (m.messageIDs != null && m.messageIDs.length) for(var i = 0; i < m.messageIDs.length; ++i)w.uint32(18).bytes(m.messageIDs[i]);
                return w;
            };
            /**
             * Decodes a ControlIHave message from the specified reader or buffer.
             * @function decode
             * @memberof RPC.ControlIHave
             * @static
             * @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
             * @param {number} [l] Message length if known beforehand
             * @returns {RPC.ControlIHave} ControlIHave
             * @throws {Error} If the payload is not a reader or valid buffer
             * @throws {$protobuf.util.ProtocolError} If required fields are missing
             */ ControlIHave.decode = function decode(r, l) {
                if (!(r instanceof $Reader)) r = $Reader.create(r);
                var c = l === undefined ? r.len : r.pos + l, m = new $root.RPC.ControlIHave();
                while(r.pos < c){
                    var t = r.uint32();
                    switch(t >>> 3){
                        case 1:
                            m.topicID = r.string();
                            break;
                        case 2:
                            if (!(m.messageIDs && m.messageIDs.length)) m.messageIDs = [];
                            m.messageIDs.push(r.bytes());
                            break;
                        default:
                            r.skipType(t & 7);
                            break;
                    }
                }
                return m;
            };
            /**
             * Creates a ControlIHave message from a plain object. Also converts values to their respective internal types.
             * @function fromObject
             * @memberof RPC.ControlIHave
             * @static
             * @param {Object.<string,*>} d Plain object
             * @returns {RPC.ControlIHave} ControlIHave
             */ ControlIHave.fromObject = function fromObject(d) {
                if (d instanceof $root.RPC.ControlIHave) return d;
                var m = new $root.RPC.ControlIHave();
                if (d.topicID != null) m.topicID = String(d.topicID);
                if (d.messageIDs) {
                    if (!Array.isArray(d.messageIDs)) throw TypeError(".RPC.ControlIHave.messageIDs: array expected");
                    m.messageIDs = [];
                    for(var i = 0; i < d.messageIDs.length; ++i){
                        if (typeof d.messageIDs[i] === "string") $util.base64.decode(d.messageIDs[i], m.messageIDs[i] = $util.newBuffer($util.base64.length(d.messageIDs[i])), 0);
                        else if (d.messageIDs[i].length) m.messageIDs[i] = d.messageIDs[i];
                    }
                }
                return m;
            };
            /**
             * Creates a plain object from a ControlIHave message. Also converts values to other types if specified.
             * @function toObject
             * @memberof RPC.ControlIHave
             * @static
             * @param {RPC.ControlIHave} m ControlIHave
             * @param {$protobuf.IConversionOptions} [o] Conversion options
             * @returns {Object.<string,*>} Plain object
             */ ControlIHave.toObject = function toObject(m, o) {
                if (!o) o = {
                };
                var d = {
                };
                if (o.arrays || o.defaults) d.messageIDs = [];
                if (m.topicID != null && m.hasOwnProperty("topicID")) {
                    d.topicID = m.topicID;
                    if (o.oneofs) d._topicID = "topicID";
                }
                if (m.messageIDs && m.messageIDs.length) {
                    d.messageIDs = [];
                    for(var j = 0; j < m.messageIDs.length; ++j)d.messageIDs[j] = o.bytes === String ? $util.base64.encode(m.messageIDs[j], 0, m.messageIDs[j].length) : o.bytes === Array ? Array.prototype.slice.call(m.messageIDs[j]) : m.messageIDs[j];
                }
                return d;
            };
            /**
             * Converts this ControlIHave to JSON.
             * @function toJSON
             * @memberof RPC.ControlIHave
             * @instance
             * @returns {Object.<string,*>} JSON object
             */ ControlIHave.prototype.toJSON = function toJSON() {
                return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
            };
            return ControlIHave;
        })();
        RPC.ControlIWant = (function() {
            /**
             * Properties of a ControlIWant.
             * @memberof RPC
             * @interface IControlIWant
             * @property {Array.<Uint8Array>|null} [messageIDs] ControlIWant messageIDs
             */ /**
             * Constructs a new ControlIWant.
             * @memberof RPC
             * @classdesc Represents a ControlIWant.
             * @implements IControlIWant
             * @constructor
             * @param {RPC.IControlIWant=} [p] Properties to set
             */ function ControlIWant(p) {
                this.messageIDs = [];
                if (p) {
                    for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
                }
            }
            /**
             * ControlIWant messageIDs.
             * @member {Array.<Uint8Array>} messageIDs
             * @memberof RPC.ControlIWant
             * @instance
             */ ControlIWant.prototype.messageIDs = $util.emptyArray;
            /**
             * Encodes the specified ControlIWant message. Does not implicitly {@link RPC.ControlIWant.verify|verify} messages.
             * @function encode
             * @memberof RPC.ControlIWant
             * @static
             * @param {RPC.IControlIWant} m ControlIWant message or plain object to encode
             * @param {$protobuf.Writer} [w] Writer to encode to
             * @returns {$protobuf.Writer} Writer
             */ ControlIWant.encode = function encode(m, w) {
                if (!w) w = $Writer.create();
                if (m.messageIDs != null && m.messageIDs.length) for(var i = 0; i < m.messageIDs.length; ++i)w.uint32(10).bytes(m.messageIDs[i]);
                return w;
            };
            /**
             * Decodes a ControlIWant message from the specified reader or buffer.
             * @function decode
             * @memberof RPC.ControlIWant
             * @static
             * @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
             * @param {number} [l] Message length if known beforehand
             * @returns {RPC.ControlIWant} ControlIWant
             * @throws {Error} If the payload is not a reader or valid buffer
             * @throws {$protobuf.util.ProtocolError} If required fields are missing
             */ ControlIWant.decode = function decode(r, l) {
                if (!(r instanceof $Reader)) r = $Reader.create(r);
                var c = l === undefined ? r.len : r.pos + l, m = new $root.RPC.ControlIWant();
                while(r.pos < c){
                    var t = r.uint32();
                    switch(t >>> 3){
                        case 1:
                            if (!(m.messageIDs && m.messageIDs.length)) m.messageIDs = [];
                            m.messageIDs.push(r.bytes());
                            break;
                        default:
                            r.skipType(t & 7);
                            break;
                    }
                }
                return m;
            };
            /**
             * Creates a ControlIWant message from a plain object. Also converts values to their respective internal types.
             * @function fromObject
             * @memberof RPC.ControlIWant
             * @static
             * @param {Object.<string,*>} d Plain object
             * @returns {RPC.ControlIWant} ControlIWant
             */ ControlIWant.fromObject = function fromObject(d) {
                if (d instanceof $root.RPC.ControlIWant) return d;
                var m = new $root.RPC.ControlIWant();
                if (d.messageIDs) {
                    if (!Array.isArray(d.messageIDs)) throw TypeError(".RPC.ControlIWant.messageIDs: array expected");
                    m.messageIDs = [];
                    for(var i = 0; i < d.messageIDs.length; ++i){
                        if (typeof d.messageIDs[i] === "string") $util.base64.decode(d.messageIDs[i], m.messageIDs[i] = $util.newBuffer($util.base64.length(d.messageIDs[i])), 0);
                        else if (d.messageIDs[i].length) m.messageIDs[i] = d.messageIDs[i];
                    }
                }
                return m;
            };
            /**
             * Creates a plain object from a ControlIWant message. Also converts values to other types if specified.
             * @function toObject
             * @memberof RPC.ControlIWant
             * @static
             * @param {RPC.ControlIWant} m ControlIWant
             * @param {$protobuf.IConversionOptions} [o] Conversion options
             * @returns {Object.<string,*>} Plain object
             */ ControlIWant.toObject = function toObject(m, o) {
                if (!o) o = {
                };
                var d = {
                };
                if (o.arrays || o.defaults) d.messageIDs = [];
                if (m.messageIDs && m.messageIDs.length) {
                    d.messageIDs = [];
                    for(var j = 0; j < m.messageIDs.length; ++j)d.messageIDs[j] = o.bytes === String ? $util.base64.encode(m.messageIDs[j], 0, m.messageIDs[j].length) : o.bytes === Array ? Array.prototype.slice.call(m.messageIDs[j]) : m.messageIDs[j];
                }
                return d;
            };
            /**
             * Converts this ControlIWant to JSON.
             * @function toJSON
             * @memberof RPC.ControlIWant
             * @instance
             * @returns {Object.<string,*>} JSON object
             */ ControlIWant.prototype.toJSON = function toJSON() {
                return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
            };
            return ControlIWant;
        })();
        RPC.ControlGraft = (function() {
            /**
             * Properties of a ControlGraft.
             * @memberof RPC
             * @interface IControlGraft
             * @property {string|null} [topicID] ControlGraft topicID
             */ /**
             * Constructs a new ControlGraft.
             * @memberof RPC
             * @classdesc Represents a ControlGraft.
             * @implements IControlGraft
             * @constructor
             * @param {RPC.IControlGraft=} [p] Properties to set
             */ function ControlGraft(p) {
                if (p) {
                    for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
                }
            }
            /**
             * ControlGraft topicID.
             * @member {string|null|undefined} topicID
             * @memberof RPC.ControlGraft
             * @instance
             */ ControlGraft.prototype.topicID = null;
            // OneOf field names bound to virtual getters and setters
            var $oneOfFields;
            /**
             * ControlGraft _topicID.
             * @member {"topicID"|undefined} _topicID
             * @memberof RPC.ControlGraft
             * @instance
             */ Object.defineProperty(ControlGraft.prototype, "_topicID", {
                get: $util.oneOfGetter($oneOfFields = [
                    "topicID"
                ]),
                set: $util.oneOfSetter($oneOfFields)
            });
            /**
             * Encodes the specified ControlGraft message. Does not implicitly {@link RPC.ControlGraft.verify|verify} messages.
             * @function encode
             * @memberof RPC.ControlGraft
             * @static
             * @param {RPC.IControlGraft} m ControlGraft message or plain object to encode
             * @param {$protobuf.Writer} [w] Writer to encode to
             * @returns {$protobuf.Writer} Writer
             */ ControlGraft.encode = function encode(m, w) {
                if (!w) w = $Writer.create();
                if (m.topicID != null && Object.hasOwnProperty.call(m, "topicID")) w.uint32(10).string(m.topicID);
                return w;
            };
            /**
             * Decodes a ControlGraft message from the specified reader or buffer.
             * @function decode
             * @memberof RPC.ControlGraft
             * @static
             * @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
             * @param {number} [l] Message length if known beforehand
             * @returns {RPC.ControlGraft} ControlGraft
             * @throws {Error} If the payload is not a reader or valid buffer
             * @throws {$protobuf.util.ProtocolError} If required fields are missing
             */ ControlGraft.decode = function decode(r, l) {
                if (!(r instanceof $Reader)) r = $Reader.create(r);
                var c = l === undefined ? r.len : r.pos + l, m = new $root.RPC.ControlGraft();
                while(r.pos < c){
                    var t = r.uint32();
                    switch(t >>> 3){
                        case 1:
                            m.topicID = r.string();
                            break;
                        default:
                            r.skipType(t & 7);
                            break;
                    }
                }
                return m;
            };
            /**
             * Creates a ControlGraft message from a plain object. Also converts values to their respective internal types.
             * @function fromObject
             * @memberof RPC.ControlGraft
             * @static
             * @param {Object.<string,*>} d Plain object
             * @returns {RPC.ControlGraft} ControlGraft
             */ ControlGraft.fromObject = function fromObject(d) {
                if (d instanceof $root.RPC.ControlGraft) return d;
                var m = new $root.RPC.ControlGraft();
                if (d.topicID != null) m.topicID = String(d.topicID);
                return m;
            };
            /**
             * Creates a plain object from a ControlGraft message. Also converts values to other types if specified.
             * @function toObject
             * @memberof RPC.ControlGraft
             * @static
             * @param {RPC.ControlGraft} m ControlGraft
             * @param {$protobuf.IConversionOptions} [o] Conversion options
             * @returns {Object.<string,*>} Plain object
             */ ControlGraft.toObject = function toObject(m, o) {
                if (!o) o = {
                };
                var d = {
                };
                if (m.topicID != null && m.hasOwnProperty("topicID")) {
                    d.topicID = m.topicID;
                    if (o.oneofs) d._topicID = "topicID";
                }
                return d;
            };
            /**
             * Converts this ControlGraft to JSON.
             * @function toJSON
             * @memberof RPC.ControlGraft
             * @instance
             * @returns {Object.<string,*>} JSON object
             */ ControlGraft.prototype.toJSON = function toJSON() {
                return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
            };
            return ControlGraft;
        })();
        RPC.ControlPrune = (function() {
            /**
             * Properties of a ControlPrune.
             * @memberof RPC
             * @interface IControlPrune
             * @property {string|null} [topicID] ControlPrune topicID
             * @property {Array.<RPC.IPeerInfo>|null} [peers] ControlPrune peers
             * @property {number|null} [backoff] ControlPrune backoff
             */ /**
             * Constructs a new ControlPrune.
             * @memberof RPC
             * @classdesc Represents a ControlPrune.
             * @implements IControlPrune
             * @constructor
             * @param {RPC.IControlPrune=} [p] Properties to set
             */ function ControlPrune(p) {
                this.peers = [];
                if (p) {
                    for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
                }
            }
            /**
             * ControlPrune topicID.
             * @member {string|null|undefined} topicID
             * @memberof RPC.ControlPrune
             * @instance
             */ ControlPrune.prototype.topicID = null;
            /**
             * ControlPrune peers.
             * @member {Array.<RPC.IPeerInfo>} peers
             * @memberof RPC.ControlPrune
             * @instance
             */ ControlPrune.prototype.peers = $util.emptyArray;
            /**
             * ControlPrune backoff.
             * @member {number|null|undefined} backoff
             * @memberof RPC.ControlPrune
             * @instance
             */ ControlPrune.prototype.backoff = null;
            // OneOf field names bound to virtual getters and setters
            var $oneOfFields;
            /**
             * ControlPrune _topicID.
             * @member {"topicID"|undefined} _topicID
             * @memberof RPC.ControlPrune
             * @instance
             */ Object.defineProperty(ControlPrune.prototype, "_topicID", {
                get: $util.oneOfGetter($oneOfFields = [
                    "topicID"
                ]),
                set: $util.oneOfSetter($oneOfFields)
            });
            /**
             * ControlPrune _backoff.
             * @member {"backoff"|undefined} _backoff
             * @memberof RPC.ControlPrune
             * @instance
             */ Object.defineProperty(ControlPrune.prototype, "_backoff", {
                get: $util.oneOfGetter($oneOfFields = [
                    "backoff"
                ]),
                set: $util.oneOfSetter($oneOfFields)
            });
            /**
             * Encodes the specified ControlPrune message. Does not implicitly {@link RPC.ControlPrune.verify|verify} messages.
             * @function encode
             * @memberof RPC.ControlPrune
             * @static
             * @param {RPC.IControlPrune} m ControlPrune message or plain object to encode
             * @param {$protobuf.Writer} [w] Writer to encode to
             * @returns {$protobuf.Writer} Writer
             */ ControlPrune.encode = function encode(m, w) {
                if (!w) w = $Writer.create();
                if (m.topicID != null && Object.hasOwnProperty.call(m, "topicID")) w.uint32(10).string(m.topicID);
                if (m.peers != null && m.peers.length) for(var i = 0; i < m.peers.length; ++i)$root.RPC.PeerInfo.encode(m.peers[i], w.uint32(18).fork()).ldelim();
                if (m.backoff != null && Object.hasOwnProperty.call(m, "backoff")) w.uint32(24).uint64(m.backoff);
                return w;
            };
            /**
             * Decodes a ControlPrune message from the specified reader or buffer.
             * @function decode
             * @memberof RPC.ControlPrune
             * @static
             * @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
             * @param {number} [l] Message length if known beforehand
             * @returns {RPC.ControlPrune} ControlPrune
             * @throws {Error} If the payload is not a reader or valid buffer
             * @throws {$protobuf.util.ProtocolError} If required fields are missing
             */ ControlPrune.decode = function decode(r, l) {
                if (!(r instanceof $Reader)) r = $Reader.create(r);
                var c = l === undefined ? r.len : r.pos + l, m = new $root.RPC.ControlPrune();
                while(r.pos < c){
                    var t = r.uint32();
                    switch(t >>> 3){
                        case 1:
                            m.topicID = r.string();
                            break;
                        case 2:
                            if (!(m.peers && m.peers.length)) m.peers = [];
                            m.peers.push($root.RPC.PeerInfo.decode(r, r.uint32()));
                            break;
                        case 3:
                            m.backoff = r.uint64();
                            break;
                        default:
                            r.skipType(t & 7);
                            break;
                    }
                }
                return m;
            };
            /**
             * Creates a ControlPrune message from a plain object. Also converts values to their respective internal types.
             * @function fromObject
             * @memberof RPC.ControlPrune
             * @static
             * @param {Object.<string,*>} d Plain object
             * @returns {RPC.ControlPrune} ControlPrune
             */ ControlPrune.fromObject = function fromObject(d) {
                if (d instanceof $root.RPC.ControlPrune) return d;
                var m = new $root.RPC.ControlPrune();
                if (d.topicID != null) m.topicID = String(d.topicID);
                if (d.peers) {
                    if (!Array.isArray(d.peers)) throw TypeError(".RPC.ControlPrune.peers: array expected");
                    m.peers = [];
                    for(var i = 0; i < d.peers.length; ++i){
                        if (typeof d.peers[i] !== "object") throw TypeError(".RPC.ControlPrune.peers: object expected");
                        m.peers[i] = $root.RPC.PeerInfo.fromObject(d.peers[i]);
                    }
                }
                if (d.backoff != null) {
                    if ($util.Long) (m.backoff = $util.Long.fromValue(d.backoff)).unsigned = true;
                    else if (typeof d.backoff === "string") m.backoff = parseInt(d.backoff, 10);
                    else if (typeof d.backoff === "number") m.backoff = d.backoff;
                    else if (typeof d.backoff === "object") m.backoff = new $util.LongBits(d.backoff.low >>> 0, d.backoff.high >>> 0).toNumber(true);
                }
                return m;
            };
            /**
             * Creates a plain object from a ControlPrune message. Also converts values to other types if specified.
             * @function toObject
             * @memberof RPC.ControlPrune
             * @static
             * @param {RPC.ControlPrune} m ControlPrune
             * @param {$protobuf.IConversionOptions} [o] Conversion options
             * @returns {Object.<string,*>} Plain object
             */ ControlPrune.toObject = function toObject(m, o) {
                if (!o) o = {
                };
                var d = {
                };
                if (o.arrays || o.defaults) d.peers = [];
                if (m.topicID != null && m.hasOwnProperty("topicID")) {
                    d.topicID = m.topicID;
                    if (o.oneofs) d._topicID = "topicID";
                }
                if (m.peers && m.peers.length) {
                    d.peers = [];
                    for(var j = 0; j < m.peers.length; ++j)d.peers[j] = $root.RPC.PeerInfo.toObject(m.peers[j], o);
                }
                if (m.backoff != null && m.hasOwnProperty("backoff")) {
                    if (typeof m.backoff === "number") d.backoff = o.longs === String ? String(m.backoff) : m.backoff;
                    else d.backoff = o.longs === String ? $util.Long.prototype.toString.call(m.backoff) : o.longs === Number ? new $util.LongBits(m.backoff.low >>> 0, m.backoff.high >>> 0).toNumber(true) : m.backoff;
                    if (o.oneofs) d._backoff = "backoff";
                }
                return d;
            };
            /**
             * Converts this ControlPrune to JSON.
             * @function toJSON
             * @memberof RPC.ControlPrune
             * @instance
             * @returns {Object.<string,*>} JSON object
             */ ControlPrune.prototype.toJSON = function toJSON() {
                return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
            };
            return ControlPrune;
        })();
        RPC.PeerInfo = (function() {
            /**
             * Properties of a PeerInfo.
             * @memberof RPC
             * @interface IPeerInfo
             * @property {Uint8Array|null} [peerID] PeerInfo peerID
             * @property {Uint8Array|null} [signedPeerRecord] PeerInfo signedPeerRecord
             */ /**
             * Constructs a new PeerInfo.
             * @memberof RPC
             * @classdesc Represents a PeerInfo.
             * @implements IPeerInfo
             * @constructor
             * @param {RPC.IPeerInfo=} [p] Properties to set
             */ function PeerInfo(p) {
                if (p) {
                    for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
                }
            }
            /**
             * PeerInfo peerID.
             * @member {Uint8Array|null|undefined} peerID
             * @memberof RPC.PeerInfo
             * @instance
             */ PeerInfo.prototype.peerID = null;
            /**
             * PeerInfo signedPeerRecord.
             * @member {Uint8Array|null|undefined} signedPeerRecord
             * @memberof RPC.PeerInfo
             * @instance
             */ PeerInfo.prototype.signedPeerRecord = null;
            // OneOf field names bound to virtual getters and setters
            var $oneOfFields;
            /**
             * PeerInfo _peerID.
             * @member {"peerID"|undefined} _peerID
             * @memberof RPC.PeerInfo
             * @instance
             */ Object.defineProperty(PeerInfo.prototype, "_peerID", {
                get: $util.oneOfGetter($oneOfFields = [
                    "peerID"
                ]),
                set: $util.oneOfSetter($oneOfFields)
            });
            /**
             * PeerInfo _signedPeerRecord.
             * @member {"signedPeerRecord"|undefined} _signedPeerRecord
             * @memberof RPC.PeerInfo
             * @instance
             */ Object.defineProperty(PeerInfo.prototype, "_signedPeerRecord", {
                get: $util.oneOfGetter($oneOfFields = [
                    "signedPeerRecord"
                ]),
                set: $util.oneOfSetter($oneOfFields)
            });
            /**
             * Encodes the specified PeerInfo message. Does not implicitly {@link RPC.PeerInfo.verify|verify} messages.
             * @function encode
             * @memberof RPC.PeerInfo
             * @static
             * @param {RPC.IPeerInfo} m PeerInfo message or plain object to encode
             * @param {$protobuf.Writer} [w] Writer to encode to
             * @returns {$protobuf.Writer} Writer
             */ PeerInfo.encode = function encode(m, w) {
                if (!w) w = $Writer.create();
                if (m.peerID != null && Object.hasOwnProperty.call(m, "peerID")) w.uint32(10).bytes(m.peerID);
                if (m.signedPeerRecord != null && Object.hasOwnProperty.call(m, "signedPeerRecord")) w.uint32(18).bytes(m.signedPeerRecord);
                return w;
            };
            /**
             * Decodes a PeerInfo message from the specified reader or buffer.
             * @function decode
             * @memberof RPC.PeerInfo
             * @static
             * @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
             * @param {number} [l] Message length if known beforehand
             * @returns {RPC.PeerInfo} PeerInfo
             * @throws {Error} If the payload is not a reader or valid buffer
             * @throws {$protobuf.util.ProtocolError} If required fields are missing
             */ PeerInfo.decode = function decode(r, l) {
                if (!(r instanceof $Reader)) r = $Reader.create(r);
                var c = l === undefined ? r.len : r.pos + l, m = new $root.RPC.PeerInfo();
                while(r.pos < c){
                    var t = r.uint32();
                    switch(t >>> 3){
                        case 1:
                            m.peerID = r.bytes();
                            break;
                        case 2:
                            m.signedPeerRecord = r.bytes();
                            break;
                        default:
                            r.skipType(t & 7);
                            break;
                    }
                }
                return m;
            };
            /**
             * Creates a PeerInfo message from a plain object. Also converts values to their respective internal types.
             * @function fromObject
             * @memberof RPC.PeerInfo
             * @static
             * @param {Object.<string,*>} d Plain object
             * @returns {RPC.PeerInfo} PeerInfo
             */ PeerInfo.fromObject = function fromObject(d) {
                if (d instanceof $root.RPC.PeerInfo) return d;
                var m = new $root.RPC.PeerInfo();
                if (d.peerID != null) {
                    if (typeof d.peerID === "string") $util.base64.decode(d.peerID, m.peerID = $util.newBuffer($util.base64.length(d.peerID)), 0);
                    else if (d.peerID.length) m.peerID = d.peerID;
                }
                if (d.signedPeerRecord != null) {
                    if (typeof d.signedPeerRecord === "string") $util.base64.decode(d.signedPeerRecord, m.signedPeerRecord = $util.newBuffer($util.base64.length(d.signedPeerRecord)), 0);
                    else if (d.signedPeerRecord.length) m.signedPeerRecord = d.signedPeerRecord;
                }
                return m;
            };
            /**
             * Creates a plain object from a PeerInfo message. Also converts values to other types if specified.
             * @function toObject
             * @memberof RPC.PeerInfo
             * @static
             * @param {RPC.PeerInfo} m PeerInfo
             * @param {$protobuf.IConversionOptions} [o] Conversion options
             * @returns {Object.<string,*>} Plain object
             */ PeerInfo.toObject = function toObject(m, o) {
                if (!o) o = {
                };
                var d = {
                };
                if (m.peerID != null && m.hasOwnProperty("peerID")) {
                    d.peerID = o.bytes === String ? $util.base64.encode(m.peerID, 0, m.peerID.length) : o.bytes === Array ? Array.prototype.slice.call(m.peerID) : m.peerID;
                    if (o.oneofs) d._peerID = "peerID";
                }
                if (m.signedPeerRecord != null && m.hasOwnProperty("signedPeerRecord")) {
                    d.signedPeerRecord = o.bytes === String ? $util.base64.encode(m.signedPeerRecord, 0, m.signedPeerRecord.length) : o.bytes === Array ? Array.prototype.slice.call(m.signedPeerRecord) : m.signedPeerRecord;
                    if (o.oneofs) d._signedPeerRecord = "signedPeerRecord";
                }
                return d;
            };
            /**
             * Converts this PeerInfo to JSON.
             * @function toJSON
             * @memberof RPC.PeerInfo
             * @instance
             * @returns {Object.<string,*>} JSON object
             */ PeerInfo.prototype.toJSON = function toJSON() {
                return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
            };
            return PeerInfo;
        })();
        return RPC;
    })();
    return $root;
});

},{"protobufjs/minimal":"9Jmso"}],"ijt8w":[function(require,module,exports) {
"use strict";
var __createBinding = this && this.__createBinding || (Object.create ? function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    Object.defineProperty(o, k2, {
        enumerable: true,
        get: function() {
            return m[k];
        }
    });
} : function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
});
var __setModuleDefault = this && this.__setModuleDefault || (Object.create ? function(o, v) {
    Object.defineProperty(o, "default", {
        enumerable: true,
        value: v
    });
} : function(o, v) {
    o["default"] = v;
});
var __importStar = this && this.__importStar || function(mod) {
    if (mod && mod.__esModule) return mod;
    var result = {
    };
    if (mod != null) {
        for(var k in mod)if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    }
    __setModuleDefault(result, mod);
    return result;
};
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.Heartbeat = void 0;
const constants = __importStar(require("./constants"));
const get_gossip_peers_1 = require("./get-gossip-peers");
const utils_1 = require("./utils");
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
class Heartbeat {
    /**
     * @param {Object} gossipsub
     * @constructor
     */ constructor(gossipsub){
        this.gossipsub = gossipsub;
    }
    start() {
        if (this._heartbeatTimer) return;
        const heartbeat = this._heartbeat.bind(this);
        const timeout = setTimeout(()=>{
            heartbeat();
            this._heartbeatTimer.runPeriodically(heartbeat, this.gossipsub._options.heartbeatInterval);
        }, constants.GossipsubHeartbeatInitialDelay);
        this._heartbeatTimer = {
            _intervalId: undefined,
            runPeriodically: (fn, period)=>{
                this._heartbeatTimer._intervalId = setInterval(fn, period);
            },
            cancel: ()=>{
                clearTimeout(timeout);
                clearInterval(this._heartbeatTimer._intervalId);
            }
        };
    }
    /**
     * Unmounts the gossipsub protocol and shuts down every connection
     * @override
     * @returns {void}
     */ stop() {
        if (!this._heartbeatTimer) return;
        this._heartbeatTimer.cancel();
        this._heartbeatTimer = null;
    }
    /**
     * Maintains the mesh and fanout maps in gossipsub.
     *
     * @returns {void}
     */ _heartbeat() {
        const { D , Dlo , Dhi , Dscore , Dout , fanoutTTL  } = this.gossipsub._options;
        this.gossipsub.heartbeatTicks++;
        // cache scores throught the heartbeat
        const scores = new Map();
        const getScore = (id)=>{
            let s = scores.get(id);
            if (s === undefined) {
                s = this.gossipsub.score.score(id);
                scores.set(id, s);
            }
            return s;
        };
        // peer id => topic[]
        const tograft = new Map();
        // peer id => topic[]
        const toprune = new Map();
        // peer id => don't px
        const noPX = new Map();
        // clean up expired backoffs
        this.gossipsub._clearBackoff();
        // clean up peerhave/iasked counters
        this.gossipsub.peerhave.clear();
        this.gossipsub.iasked.clear();
        // apply IWANT request penalties
        this.gossipsub._applyIwantPenalties();
        // ensure direct peers are connected
        this.gossipsub._directConnect();
        // maintain the mesh for topics we have joined
        this.gossipsub.mesh.forEach((peers, topic)=>{
            // prune/graft helper functions (defined per topic)
            const prunePeer = (id)=>{
                this.gossipsub.log('HEARTBEAT: Remove mesh link to %s in %s', id, topic);
                // update peer score
                this.gossipsub.score.prune(id, topic);
                // add prune backoff record
                this.gossipsub._addBackoff(id, topic);
                // remove peer from mesh
                peers.delete(id);
                // add to toprune
                const topics = toprune.get(id);
                if (!topics) toprune.set(id, [
                    topic
                ]);
                else topics.push(topic);
            };
            const graftPeer = (id)=>{
                this.gossipsub.log('HEARTBEAT: Add mesh link to %s in %s', id, topic);
                // update peer score
                this.gossipsub.score.graft(id, topic);
                // add peer to mesh
                peers.add(id);
                // add to tograft
                const topics = tograft.get(id);
                if (!topics) tograft.set(id, [
                    topic
                ]);
                else topics.push(topic);
            };
            // drop all peers with negative score, without PX
            peers.forEach((id)=>{
                const score = getScore(id);
                if (score < 0) {
                    this.gossipsub.log('HEARTBEAT: Prune peer %s with negative score: score=%d, topic=%s', id, score, topic);
                    prunePeer(id);
                    noPX.set(id, true);
                }
            });
            // do we have enough peers?
            if (peers.size < Dlo) {
                const backoff = this.gossipsub.backoff.get(topic);
                const ineed = D - peers.size;
                const peersSet = get_gossip_peers_1.getGossipPeers(this.gossipsub, topic, ineed, (id)=>{
                    // filter out mesh peers, direct peers, peers we are backing off, peers with negative score
                    return !peers.has(id) && !this.gossipsub.direct.has(id) && (!backoff || !backoff.has(id)) && getScore(id) >= 0;
                });
                peersSet.forEach(graftPeer);
            }
            // do we have to many peers?
            if (peers.size > Dhi) {
                let peersArray = Array.from(peers);
                // sort by score
                peersArray.sort((a, b)=>getScore(b) - getScore(a)
                );
                // We keep the first D_score peers by score and the remaining up to D randomly
                // under the constraint that we keep D_out peers in the mesh (if we have that many)
                peersArray = peersArray.slice(0, Dscore).concat(utils_1.shuffle(peersArray.slice(Dscore)));
                // count the outbound peers we are keeping
                let outbound = 0;
                peersArray.slice(0, D).forEach((p)=>{
                    if (this.gossipsub.outbound.get(p)) outbound++;
                });
                // if it's less than D_out, bubble up some outbound peers from the random selection
                if (outbound < Dout) {
                    const rotate = (i)=>{
                        // rotate the peersArray to the right and put the ith peer in the front
                        const p = peersArray[i];
                        for(let j = i; j > 0; j--)peersArray[j] = peersArray[j - 1];
                        peersArray[0] = p;
                    };
                    // first bubble up all outbound peers already in the selection to the front
                    if (outbound > 0) {
                        let ihave = outbound;
                        for(let i = 1; i < D && ihave > 0; i++)if (this.gossipsub.outbound.get(peersArray[i])) {
                            rotate(i);
                            ihave--;
                        }
                    }
                    // now bubble up enough outbound peers outside the selection to the front
                    let ineed = D - outbound;
                    for(let i1 = D; i1 < peersArray.length && ineed > 0; i1++)if (this.gossipsub.outbound.get(peersArray[i1])) {
                        rotate(i1);
                        ineed--;
                    }
                }
                // prune the excess peers
                peersArray.slice(D).forEach(prunePeer);
            }
            // do we have enough outbound peers?
            if (peers.size >= Dlo) {
                // count the outbound peers we have
                let outbound = 0;
                peers.forEach((p)=>{
                    if (this.gossipsub.outbound.get(p)) outbound++;
                });
                // if it's less than D_out, select some peers with outbound connections and graft them
                if (outbound < Dout) {
                    const ineed = Dout - outbound;
                    const backoff = this.gossipsub.backoff.get(topic);
                    get_gossip_peers_1.getGossipPeers(this.gossipsub, topic, ineed, (id)=>{
                        // filter our current mesh peers, direct peers, peers we are backing off, peers with negative score
                        return !peers.has(id) && !this.gossipsub.direct.has(id) && (!backoff || !backoff.has(id)) && getScore(id) >= 0;
                    }).forEach(graftPeer);
                }
            }
            // should we try to improve the mesh with opportunistic grafting?
            if (this.gossipsub.heartbeatTicks % constants.GossipsubOpportunisticGraftTicks === 0 && peers.size > 1) {
                // Opportunistic grafting works as follows: we check the median score of peers in the
                // mesh; if this score is below the opportunisticGraftThreshold, we select a few peers at
                // random with score over the median.
                // The intention is to (slowly) improve an underperforming mesh by introducing good
                // scoring peers that may have been gossiping at us. This allows us to get out of sticky
                // situations where we are stuck with poor peers and also recover from churn of good peers.
                // now compute the median peer score in the mesh
                const peersList = Array.from(peers).sort((a, b)=>getScore(a) - getScore(b)
                );
                const medianIndex = Math.floor(peers.size / 2);
                const medianScore = getScore(peersList[medianIndex]);
                // if the median score is below the threshold, select a better peer (if any) and GRAFT
                if (medianScore < this.gossipsub._options.scoreThresholds.opportunisticGraftThreshold) {
                    const backoff = this.gossipsub.backoff.get(topic);
                    const peersToGraft = get_gossip_peers_1.getGossipPeers(this.gossipsub, topic, constants.GossipsubOpportunisticGraftPeers, (id)=>{
                        // filter out current mesh peers, direct peers, peers we are backing off, peers below or at threshold
                        return peers.has(id) && !this.gossipsub.direct.has(id) && (!backoff || !backoff.has(id)) && getScore(id) > medianScore;
                    });
                    peersToGraft.forEach((id)=>{
                        this.gossipsub.log('HEARTBEAT: Opportunistically graft peer %s on topic %s', id, topic);
                        graftPeer(id);
                    });
                }
            }
            // 2nd arg are mesh peers excluded from gossip. We have already pushed
            // messages to them, so its redundant to gossip IHAVEs.
            this.gossipsub._emitGossip(topic, peers);
        });
        // expire fanout for topics we haven't published to in a while
        const now = this.gossipsub._now();
        this.gossipsub.lastpub.forEach((lastpb, topic)=>{
            if (lastpb + fanoutTTL < now) {
                this.gossipsub.fanout.delete(topic);
                this.gossipsub.lastpub.delete(topic);
            }
        });
        // maintain our fanout for topics we are publishing but we have not joined
        this.gossipsub.fanout.forEach((fanoutPeers, topic)=>{
            // checks whether our peers are still in the topic and have a score above the publish threshold
            const topicPeers = this.gossipsub.topics.get(topic);
            fanoutPeers.forEach((id)=>{
                if (!topicPeers.has(id) || getScore(id) < this.gossipsub._options.scoreThresholds.publishThreshold) fanoutPeers.delete(id);
            });
            // do we need more peers?
            if (fanoutPeers.size < D) {
                const ineed = D - fanoutPeers.size;
                const peersSet = get_gossip_peers_1.getGossipPeers(this.gossipsub, topic, ineed, (id)=>{
                    // filter out existing fanout peers, direct peers, and peers with score above the publish threshold
                    return !fanoutPeers.has(id) && !this.gossipsub.direct.has(id) && getScore(id) >= this.gossipsub._options.scoreThresholds.publishThreshold;
                });
                peersSet.forEach((id)=>{
                    fanoutPeers.add(id);
                });
            }
            // 2nd arg are fanout peers excluded from gossip.
            // We have already pushed messages to them, so its redundant to gossip IHAVEs
            this.gossipsub._emitGossip(topic, fanoutPeers);
        });
        // send coalesced GRAFT/PRUNE messages (will piggyback gossip)
        this.gossipsub._sendGraftPrune(tograft, toprune, noPX);
        // flush pending gossip that wasn't piggybacked above
        this.gossipsub._flush();
        // advance the message history window
        this.gossipsub.messageCache.shift();
        this.gossipsub.emit('gossipsub:heartbeat');
    }
}
exports.Heartbeat = Heartbeat;

},{"./constants":"dwqwi","./get-gossip-peers":"8LLZe","./utils":"j1LCn"}],"8LLZe":[function(require,module,exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.getGossipPeers = void 0;
const utils_1 = require("./utils");
/**
 * Given a topic, returns up to count peers subscribed to that topic
 * that pass an optional filter function
 *
 * @param {Gossipsub} router
 * @param {String} topic
 * @param {Number} count
 * @param {Function} [filter] a function to filter acceptable peers
 * @returns {Set<string>}
 *
 */ function getGossipPeers(router, topic, count, filter = ()=>true
) {
    const peersInTopic = router.topics.get(topic);
    if (!peersInTopic) return new Set();
    // Adds all peers using our protocol
    // that also pass the filter function
    let peers = [];
    peersInTopic.forEach((id)=>{
        const peerStreams = router.peers.get(id);
        if (!peerStreams) return;
        if (utils_1.hasGossipProtocol(peerStreams.protocol) && filter(id)) peers.push(id);
    });
    // Pseudo-randomly shuffles peers
    peers = utils_1.shuffle(peers);
    if (count > 0 && peers.length > count) peers = peers.slice(0, count);
    return new Set(peers);
}
exports.getGossipPeers = getGossipPeers;

},{"./utils":"j1LCn"}],"iqXcJ":[function(require,module,exports) {
"use strict";
var __createBinding = this && this.__createBinding || (Object.create ? function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    Object.defineProperty(o, k2, {
        enumerable: true,
        get: function() {
            return m[k];
        }
    });
} : function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
});
var __exportStar = this && this.__exportStar || function(m, exports) {
    for(var p in m)if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", {
    value: true
});
__exportStar(require("./peer-score-params"), exports);
__exportStar(require("./peer-score-thresholds"), exports);
__exportStar(require("./peer-score"), exports);

},{"./peer-score-params":"44RQl","./peer-score-thresholds":"b9O9M","./peer-score":"f6Etm"}],"44RQl":[function(require,module,exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.validateTopicScoreParams = exports.validatePeerScoreParams = exports.createTopicScoreParams = exports.createPeerScoreParams = exports.defaultTopicScoreParams = exports.defaultPeerScoreParams = void 0;
const constants_1 = require("./constants");
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const errcode = require("err-code");
exports.defaultPeerScoreParams = {
    topics: {
    },
    topicScoreCap: 10,
    appSpecificScore: ()=>0
    ,
    appSpecificWeight: 10,
    IPColocationFactorWeight: -5,
    IPColocationFactorThreshold: 10,
    IPColocationFactorWhitelist: new Set(),
    behaviourPenaltyWeight: -10,
    behaviourPenaltyDecay: 0.2,
    decayInterval: 1000,
    decayToZero: 0.1,
    retainScore: 3600000
};
exports.defaultTopicScoreParams = {
    topicWeight: 0.5,
    timeInMeshWeight: 1,
    timeInMeshQuantum: 1,
    timeInMeshCap: 3600,
    firstMessageDeliveriesWeight: 1,
    firstMessageDeliveriesDecay: 0.5,
    firstMessageDeliveriesCap: 2000,
    meshMessageDeliveriesWeight: -1,
    meshMessageDeliveriesDecay: 0.5,
    meshMessageDeliveriesCap: 100,
    meshMessageDeliveriesThreshold: 20,
    meshMessageDeliveriesWindow: 10,
    meshMessageDeliveriesActivation: 5000,
    meshFailurePenaltyWeight: -1,
    meshFailurePenaltyDecay: 0.5,
    invalidMessageDeliveriesWeight: -1,
    invalidMessageDeliveriesDecay: 0.3
};
function createPeerScoreParams(p = {
}) {
    return Object.assign(Object.assign(Object.assign({
    }, exports.defaultPeerScoreParams), p), {
        topics: p.topics ? Object.entries(p.topics).reduce((topics, [topic, topicScoreParams])=>{
            topics[topic] = createTopicScoreParams(topicScoreParams);
            return topics;
        }, {
        }) : {
        }
    });
}
exports.createPeerScoreParams = createPeerScoreParams;
function createTopicScoreParams(p = {
}) {
    return Object.assign(Object.assign({
    }, exports.defaultTopicScoreParams), p);
}
exports.createTopicScoreParams = createTopicScoreParams;
// peer score parameter validation
function validatePeerScoreParams(p) {
    for (const [topic, params] of Object.entries(p.topics))try {
        validateTopicScoreParams(params);
    } catch (e) {
        throw errcode(new Error(`invalid score parameters for topic ${topic}: ${e.message}`), constants_1.ERR_INVALID_PEER_SCORE_PARAMS);
    }
    // check that the topic score is 0 or something positive
    if (p.topicScoreCap < 0) throw errcode(new Error('invalid topic score cap; must be positive (or 0 for no cap)'), constants_1.ERR_INVALID_PEER_SCORE_PARAMS);
    // check that we have an app specific score; the weight can be anything (but expected positive)
    if (p.appSpecificScore === null || p.appSpecificScore === undefined) throw errcode(new Error('missing application specific score function'), constants_1.ERR_INVALID_PEER_SCORE_PARAMS);
    // check the IP colocation factor
    if (p.IPColocationFactorWeight > 0) throw errcode(new Error('invalid IPColocationFactorWeight; must be negative (or 0 to disable)'), constants_1.ERR_INVALID_PEER_SCORE_PARAMS);
    if (p.IPColocationFactorWeight !== 0 && p.IPColocationFactorThreshold < 1) throw errcode(new Error('invalid IPColocationFactorThreshold; must be at least 1'), constants_1.ERR_INVALID_PEER_SCORE_PARAMS);
    // check the behaviour penalty
    if (p.behaviourPenaltyWeight > 0) throw errcode(new Error('invalid BehaviourPenaltyWeight; must be negative (or 0 to disable)'), constants_1.ERR_INVALID_PEER_SCORE_PARAMS);
    if (p.behaviourPenaltyWeight !== 0 && (p.behaviourPenaltyDecay <= 0 || p.behaviourPenaltyDecay >= 1)) throw errcode(new Error('invalid BehaviourPenaltyDecay; must be between 0 and 1'), constants_1.ERR_INVALID_PEER_SCORE_PARAMS);
    // check the decay parameters
    if (p.decayInterval < 1000) throw errcode(new Error('invalid DecayInterval; must be at least 1s'), constants_1.ERR_INVALID_PEER_SCORE_PARAMS);
    if (p.decayToZero <= 0 || p.decayToZero >= 1) throw errcode(new Error('invalid DecayToZero; must be between 0 and 1'), constants_1.ERR_INVALID_PEER_SCORE_PARAMS);
// no need to check the score retention; a value of 0 means that we don't retain scores
}
exports.validatePeerScoreParams = validatePeerScoreParams;
function validateTopicScoreParams(p) {
    // make sure we have a sane topic weight
    if (p.topicWeight < 0) throw errcode(new Error('invalid topic weight; must be >= 0'), constants_1.ERR_INVALID_PEER_SCORE_PARAMS);
    // check P1
    if (p.timeInMeshQuantum === 0) throw errcode(new Error('invalid TimeInMeshQuantum; must be non zero'), constants_1.ERR_INVALID_PEER_SCORE_PARAMS);
    if (p.timeInMeshWeight < 0) throw errcode(new Error('invalid TimeInMeshWeight; must be positive (or 0 to disable)'), constants_1.ERR_INVALID_PEER_SCORE_PARAMS);
    if (p.timeInMeshWeight !== 0 && p.timeInMeshQuantum <= 0) throw errcode(new Error('invalid TimeInMeshQuantum; must be positive'), constants_1.ERR_INVALID_PEER_SCORE_PARAMS);
    if (p.timeInMeshWeight !== 0 && p.timeInMeshCap <= 0) throw errcode(new Error('invalid TimeInMeshCap; must be positive'), constants_1.ERR_INVALID_PEER_SCORE_PARAMS);
    // check P2
    if (p.firstMessageDeliveriesWeight < 0) throw errcode(new Error('invallid FirstMessageDeliveriesWeight; must be positive (or 0 to disable)'), constants_1.ERR_INVALID_PEER_SCORE_PARAMS);
    if (p.firstMessageDeliveriesWeight !== 0 && (p.firstMessageDeliveriesDecay <= 0 || p.firstMessageDeliveriesDecay >= 1)) throw errcode(new Error('invalid FirstMessageDeliveriesDecay; must be between 0 and 1'), constants_1.ERR_INVALID_PEER_SCORE_PARAMS);
    if (p.firstMessageDeliveriesWeight !== 0 && p.firstMessageDeliveriesCap <= 0) throw errcode(new Error('invalid FirstMessageDeliveriesCap; must be positive'), constants_1.ERR_INVALID_PEER_SCORE_PARAMS);
    // check P3
    if (p.meshMessageDeliveriesWeight > 0) throw errcode(new Error('invalid MeshMessageDeliveriesWeight; must be negative (or 0 to disable)'), constants_1.ERR_INVALID_PEER_SCORE_PARAMS);
    if (p.meshMessageDeliveriesWeight !== 0 && (p.meshMessageDeliveriesDecay <= 0 || p.meshMessageDeliveriesDecay >= 1)) throw errcode(new Error('invalid MeshMessageDeliveriesDecay; must be between 0 and 1'), constants_1.ERR_INVALID_PEER_SCORE_PARAMS);
    if (p.meshMessageDeliveriesWeight !== 0 && p.meshMessageDeliveriesCap <= 0) throw errcode(new Error('invalid MeshMessageDeliveriesCap; must be positive'), constants_1.ERR_INVALID_PEER_SCORE_PARAMS);
    if (p.meshMessageDeliveriesWeight !== 0 && p.meshMessageDeliveriesThreshold <= 0) throw errcode(new Error('invalid MeshMessageDeliveriesThreshold; must be positive'), constants_1.ERR_INVALID_PEER_SCORE_PARAMS);
    if (p.meshMessageDeliveriesWindow < 0) throw errcode(new Error('invalid MeshMessageDeliveriesWindow; must be non-negative'), constants_1.ERR_INVALID_PEER_SCORE_PARAMS);
    if (p.meshMessageDeliveriesWeight !== 0 && p.meshMessageDeliveriesActivation < 1000) throw errcode(new Error('invalid MeshMessageDeliveriesActivation; must be at least 1s'), constants_1.ERR_INVALID_PEER_SCORE_PARAMS);
    // check P3b
    if (p.meshFailurePenaltyWeight > 0) throw errcode(new Error('invalid MeshFailurePenaltyWeight; must be negative (or 0 to disable)'), constants_1.ERR_INVALID_PEER_SCORE_PARAMS);
    if (p.meshFailurePenaltyWeight !== 0 && (p.meshFailurePenaltyDecay <= 0 || p.meshFailurePenaltyDecay >= 1)) throw errcode(new Error('invalid MeshFailurePenaltyDecay; must be between 0 and 1'), constants_1.ERR_INVALID_PEER_SCORE_PARAMS);
    // check P4
    if (p.invalidMessageDeliveriesWeight > 0) throw errcode(new Error('invalid InvalidMessageDeliveriesWeight; must be negative (or 0 to disable)'), constants_1.ERR_INVALID_PEER_SCORE_PARAMS);
    if (p.invalidMessageDeliveriesDecay <= 0 || p.invalidMessageDeliveriesDecay >= 1) throw errcode(new Error('invalid InvalidMessageDeliveriesDecay; must be between 0 and 1'), constants_1.ERR_INVALID_PEER_SCORE_PARAMS);
}
exports.validateTopicScoreParams = validateTopicScoreParams;

},{"./constants":"1mqKK","err-code":"eQvyh"}],"1mqKK":[function(require,module,exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.ERR_INVALID_PEER_SCORE_THRESHOLDS = exports.ERR_INVALID_PEER_SCORE_PARAMS = void 0;
exports.ERR_INVALID_PEER_SCORE_PARAMS = 'ERR_INVALID_PEER_SCORE_PARAMS';
exports.ERR_INVALID_PEER_SCORE_THRESHOLDS = 'ERR_INVALID_PEER_SCORE_THRESHOLDS';

},{}],"b9O9M":[function(require,module,exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.validatePeerScoreThresholds = exports.createPeerScoreThresholds = exports.defaultPeerScoreThresholds = void 0;
const constants_1 = require("./constants");
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const errcode = require("err-code");
exports.defaultPeerScoreThresholds = {
    gossipThreshold: -10,
    publishThreshold: -50,
    graylistThreshold: -80,
    acceptPXThreshold: 10,
    opportunisticGraftThreshold: 20
};
function createPeerScoreThresholds(p = {
}) {
    return Object.assign(Object.assign({
    }, exports.defaultPeerScoreThresholds), p);
}
exports.createPeerScoreThresholds = createPeerScoreThresholds;
function validatePeerScoreThresholds(p) {
    if (p.gossipThreshold > 0) throw errcode(new Error('invalid gossip threshold; it must be <= 0'), constants_1.ERR_INVALID_PEER_SCORE_THRESHOLDS);
    if (p.publishThreshold > 0 || p.publishThreshold > p.gossipThreshold) throw errcode(new Error('invalid publish threshold; it must be <= 0 and <= gossip threshold'), constants_1.ERR_INVALID_PEER_SCORE_THRESHOLDS);
    if (p.graylistThreshold > 0 || p.graylistThreshold > p.publishThreshold) throw errcode(new Error('invalid graylist threshold; it must be <= 0 and <= publish threshold'), constants_1.ERR_INVALID_PEER_SCORE_THRESHOLDS);
    if (p.acceptPXThreshold < 0) throw errcode(new Error('invalid accept PX threshold; it must be >= 0'), constants_1.ERR_INVALID_PEER_SCORE_THRESHOLDS);
    if (p.opportunisticGraftThreshold < 0) throw errcode(new Error('invalid opportunistic grafting threshold; it must be >= 0'), constants_1.ERR_INVALID_PEER_SCORE_THRESHOLDS);
}
exports.validatePeerScoreThresholds = validatePeerScoreThresholds;

},{"./constants":"1mqKK","err-code":"eQvyh"}],"f6Etm":[function(require,module,exports) {
"use strict";
var __awaiter = this && this.__awaiter || function(thisArg, _arguments, P, generator) {
    function adopt(value) {
        return value instanceof P ? value : new P(function(resolve) {
            resolve(value);
        });
    }
    return new (P || (P = Promise))(function(resolve, reject) {
        function fulfilled(value) {
            try {
                step(generator.next(value));
            } catch (e) {
                reject(e);
            }
        }
        function rejected(value) {
            try {
                step(generator["throw"](value));
            } catch (e) {
                reject(e);
            }
        }
        function step(result) {
            result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
        }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __importDefault = this && this.__importDefault || function(mod) {
    return mod && mod.__esModule ? mod : {
        "default": mod
    };
};
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.PeerScore = void 0;
const peer_score_params_1 = require("./peer-score-params");
const peer_stats_1 = require("./peer-stats");
const compute_score_1 = require("./compute-score");
const message_deliveries_1 = require("./message-deliveries");
const constants_1 = require("../constants");
const peer_id_1 = __importDefault(require("peer-id"));
const debug = require("debug");
const pubsubErrors = require("libp2p-interfaces/src/pubsub/errors");
const { ERR_INVALID_SIGNATURE , ERR_MISSING_SIGNATURE  } = pubsubErrors.codes;
const log = debug('libp2p:gossipsub:score');
class PeerScore {
    constructor(params, connectionManager, msgId){
        peer_score_params_1.validatePeerScoreParams(params);
        this.params = params;
        this._connectionManager = connectionManager;
        this.peerStats = new Map();
        this.peerIPs = new Map();
        this.deliveryRecords = new message_deliveries_1.MessageDeliveries();
        this.msgId = msgId;
    }
    /**
     * Start PeerScore instance
     * @returns {void}
     */ start() {
        if (this._backgroundInterval) {
            log('Peer score already running');
            return;
        }
        this._backgroundInterval = setInterval(()=>this.background()
        , this.params.decayInterval);
        log('started');
    }
    /**
     * Stop PeerScore instance
     * @returns {void}
     */ stop() {
        if (!this._backgroundInterval) {
            log('Peer score already stopped');
            return;
        }
        clearInterval(this._backgroundInterval);
        delete this._backgroundInterval;
        this.peerIPs.clear();
        this.peerStats.clear();
        this.deliveryRecords.clear();
        log('stopped');
    }
    /**
     * Periodic maintenance
     * @returns {void}
     */ background() {
        this._refreshScores();
        this._updateIPs();
        this.deliveryRecords.gc();
    }
    /**
     * Decays scores, and purges score records for disconnected peers once their expiry has elapsed.
     * @returns {void}
     */ _refreshScores() {
        const now = Date.now();
        const decayToZero = this.params.decayToZero;
        this.peerStats.forEach((pstats, id)=>{
            if (!pstats.connected) {
                // has the retention perious expired?
                if (now > pstats.expire) {
                    // yes, throw it away (but clean up the IP tracking first)
                    this._removeIPs(id, pstats.ips);
                    this.peerStats.delete(id);
                }
                // we don't decay retained scores, as the peer is not active.
                // this way the peer cannot reset a negative score by simply disconnecting and reconnecting,
                // unless the retention period has ellapsed.
                // similarly, a well behaved peer does not lose its score by getting disconnected.
                return;
            }
            Object.entries(pstats.topics).forEach(([topic, tstats])=>{
                const tparams = this.params.topics[topic];
                if (!tparams) // we are not scoring this topic
                // should be unreachable, we only add scored topics to pstats
                return;
                // decay counters
                tstats.firstMessageDeliveries *= tparams.firstMessageDeliveriesDecay;
                if (tstats.firstMessageDeliveries < decayToZero) tstats.firstMessageDeliveries = 0;
                tstats.meshMessageDeliveries *= tparams.meshMessageDeliveriesDecay;
                if (tstats.meshMessageDeliveries < decayToZero) tstats.meshMessageDeliveries = 0;
                tstats.meshFailurePenalty *= tparams.meshFailurePenaltyDecay;
                if (tstats.meshFailurePenalty < decayToZero) tstats.meshFailurePenalty = 0;
                tstats.invalidMessageDeliveries *= tparams.invalidMessageDeliveriesDecay;
                if (tstats.invalidMessageDeliveries < decayToZero) tstats.invalidMessageDeliveries = 0;
                // update mesh time and activate mesh message delivery parameter if need be
                if (tstats.inMesh) {
                    tstats.meshTime = now - tstats.graftTime;
                    if (tstats.meshTime > tparams.meshMessageDeliveriesActivation) tstats.meshMessageDeliveriesActive = true;
                }
            });
            // decay P7 counter
            pstats.behaviourPenalty *= this.params.behaviourPenaltyDecay;
            if (pstats.behaviourPenalty < decayToZero) pstats.behaviourPenalty = 0;
        });
    }
    /**
     * Return the score for a peer
     * @param {string} id
     * @returns {Number}
     */ score(id6) {
        const pstats = this.peerStats.get(id6);
        if (!pstats) return 0;
        return compute_score_1.computeScore(id6, pstats, this.params, this.peerIPs);
    }
    /**
     * Apply a behavioural penalty to a peer
     * @param {string} id
     * @param {Number} penalty
     * @returns {void}
     */ addPenalty(id1, penalty) {
        const pstats = this.peerStats.get(id1);
        if (!pstats) return;
        pstats.behaviourPenalty += penalty;
    }
    /**
     * @param {string} id
     * @returns {void}
     */ addPeer(id2) {
        // create peer stats (not including topic stats for each topic to be scored)
        // topic stats will be added as needed
        const pstats = peer_stats_1.createPeerStats({
            connected: true
        });
        this.peerStats.set(id2, pstats);
        // get + update peer IPs
        const ips = this._getIPs(id2);
        this._setIPs(id2, ips, pstats.ips);
        pstats.ips = ips;
    }
    /**
     * @param {string} id
     * @returns {void}
     */ removePeer(id3) {
        const pstats = this.peerStats.get(id3);
        if (!pstats) return;
        // decide whether to retain the score; this currently only retains non-positive scores
        // to dissuade attacks on the score function.
        if (this.score(id3) > 0) {
            this._removeIPs(id3, pstats.ips);
            this.peerStats.delete(id3);
            return;
        }
        // furthermore, when we decide to retain the score, the firstMessageDelivery counters are
        // reset to 0 and mesh delivery penalties applied.
        Object.entries(pstats.topics).forEach(([topic, tstats])=>{
            tstats.firstMessageDeliveries = 0;
            const threshold = this.params.topics[topic].meshMessageDeliveriesThreshold;
            if (tstats.inMesh && tstats.meshMessageDeliveriesActive && tstats.meshMessageDeliveries < threshold) {
                const deficit = threshold - tstats.meshMessageDeliveries;
                tstats.meshFailurePenalty += deficit * deficit;
            }
            tstats.inMesh = false;
        });
        pstats.connected = false;
        pstats.expire = Date.now() + this.params.retainScore;
    }
    /**
     * @param {string} id
     * @param {String} topic
     * @returns {void}
     */ graft(id4, topic2) {
        const pstats = this.peerStats.get(id4);
        if (!pstats) return;
        const tstats = peer_stats_1.ensureTopicStats(topic2, pstats, this.params);
        if (!tstats) return;
        tstats.inMesh = true;
        tstats.graftTime = Date.now();
        tstats.meshTime = 0;
        tstats.meshMessageDeliveriesActive = false;
    }
    /**
     * @param {string} id
     * @param {string} topic
     * @returns {void}
     */ prune(id5, topic1) {
        const pstats = this.peerStats.get(id5);
        if (!pstats) return;
        const tstats = peer_stats_1.ensureTopicStats(topic1, pstats, this.params);
        if (!tstats) return;
        // sticky mesh delivery rate failure penalty
        const threshold = this.params.topics[topic1].meshMessageDeliveriesThreshold;
        if (tstats.meshMessageDeliveriesActive && tstats.meshMessageDeliveries < threshold) {
            const deficit = threshold - tstats.meshMessageDeliveries;
            tstats.meshFailurePenalty += deficit * deficit;
        }
        tstats.inMesh = false;
    }
    /**
     * @param {InMessage} message
     * @returns {Promise<void>}
     */ validateMessage(message) {
        return __awaiter(this, void 0, void 0, function*() {
            this.deliveryRecords.ensureRecord((yield this.msgId(message)));
        });
    }
    /**
     * @param {InMessage} message
     * @returns {Promise<void>}
     */ deliverMessage(message1) {
        return __awaiter(this, void 0, void 0, function*() {
            const id = message1.receivedFrom;
            this._markFirstMessageDelivery(id, message1);
            const drec = this.deliveryRecords.ensureRecord((yield this.msgId(message1)));
            const now = Date.now();
            // defensive check that this is the first delivery trace -- delivery status should be unknown
            if (drec.status !== message_deliveries_1.DeliveryRecordStatus.unknown) {
                log('unexpected delivery: message from %s was first seen %s ago and has delivery status %d', id, now - drec.firstSeen, message_deliveries_1.DeliveryRecordStatus[drec.status]);
                return;
            }
            // mark the message as valid and reward mesh peers that have already forwarded it to us
            drec.status = message_deliveries_1.DeliveryRecordStatus.valid;
            drec.validated = now;
            drec.peers.forEach((p)=>{
                // this check is to make sure a peer can't send us a message twice and get a double count
                // if it is a first delivery.
                if (p !== id) this._markDuplicateMessageDelivery(p, message1);
            });
        });
    }
    /**
     * @param {InMessage} message
     * @param {string} reason
     * @returns {Promise<void>}
     */ rejectMessage(message2, reason) {
        return __awaiter(this, void 0, void 0, function*() {
            const id = message2.receivedFrom;
            switch(reason){
                case ERR_MISSING_SIGNATURE:
                case ERR_INVALID_SIGNATURE:
                    this._markInvalidMessageDelivery(id, message2);
                    return;
            }
            const drec = this.deliveryRecords.ensureRecord((yield this.msgId(message2)));
            // defensive check that this is the first rejection -- delivery status should be unknown
            if (drec.status !== message_deliveries_1.DeliveryRecordStatus.unknown) {
                log('unexpected rejection: message from %s was first seen %s ago and has delivery status %d', id, Date.now() - drec.firstSeen, message_deliveries_1.DeliveryRecordStatus[drec.status]);
                return;
            }
            switch(reason){
                case constants_1.ERR_TOPIC_VALIDATOR_IGNORE:
                    // we were explicitly instructed by the validator to ignore the message but not penalize the peer
                    drec.status = message_deliveries_1.DeliveryRecordStatus.ignored;
                    return;
            }
            // mark the message as invalid and penalize peers that have already forwarded it.
            drec.status = message_deliveries_1.DeliveryRecordStatus.invalid;
            this._markInvalidMessageDelivery(id, message2);
            drec.peers.forEach((p)=>{
                this._markInvalidMessageDelivery(p, message2);
            });
        });
    }
    /**
     * @param {InMessage} message
     * @returns {Promise<void>}
     */ duplicateMessage(message3) {
        return __awaiter(this, void 0, void 0, function*() {
            const id = message3.receivedFrom;
            const drec = this.deliveryRecords.ensureRecord((yield this.msgId(message3)));
            if (drec.peers.has(id)) // we have already seen this duplicate
            return;
            switch(drec.status){
                case message_deliveries_1.DeliveryRecordStatus.unknown:
                    // the message is being validated; track the peer delivery and wait for
                    // the Deliver/Reject/Ignore notification.
                    drec.peers.add(id);
                    break;
                case message_deliveries_1.DeliveryRecordStatus.valid:
                    // mark the peer delivery time to only count a duplicate delivery once.
                    drec.peers.add(id);
                    this._markDuplicateMessageDelivery(id, message3, drec.validated);
                    break;
                case message_deliveries_1.DeliveryRecordStatus.invalid:
                    // we no longer track delivery time
                    this._markInvalidMessageDelivery(id, message3);
                    break;
            }
        });
    }
    /**
     * Increments the "invalid message deliveries" counter for all scored topics the message is published in.
     * @param {string} id
     * @param {InMessage} message
     * @returns {void}
     */ _markInvalidMessageDelivery(id12, message4) {
        const pstats = this.peerStats.get(id12);
        if (!pstats) return;
        message4.topicIDs.forEach((topic)=>{
            const tstats = peer_stats_1.ensureTopicStats(topic, pstats, this.params);
            if (!tstats) return;
            tstats.invalidMessageDeliveries += 1;
        });
    }
    /**
     * Increments the "first message deliveries" counter for all scored topics the message is published in,
     * as well as the "mesh message deliveries" counter, if the peer is in the mesh for the topic.
     * @param {string} id
     * @param {InMessage} message
     * @returns {void}
     */ _markFirstMessageDelivery(id7, message5) {
        const pstats = this.peerStats.get(id7);
        if (!pstats) return;
        message5.topicIDs.forEach((topic)=>{
            const tstats = peer_stats_1.ensureTopicStats(topic, pstats, this.params);
            if (!tstats) return;
            let cap = this.params.topics[topic].firstMessageDeliveriesCap;
            tstats.firstMessageDeliveries += 1;
            if (tstats.firstMessageDeliveries > cap) tstats.firstMessageDeliveries = cap;
            if (!tstats.inMesh) return;
            cap = this.params.topics[topic].meshMessageDeliveriesCap;
            tstats.meshMessageDeliveries += 1;
            if (tstats.meshMessageDeliveries > cap) tstats.meshMessageDeliveries = cap;
        });
    }
    /**
     * Increments the "mesh message deliveries" counter for messages we've seen before,
     * as long the message was received within the P3 window.
     * @param {string} id
     * @param {InMessage} message
     * @param {number} validatedTime
     * @returns {void}
     */ _markDuplicateMessageDelivery(id8, message6, validatedTime = 0) {
        const pstats = this.peerStats.get(id8);
        if (!pstats) return;
        const now = validatedTime ? Date.now() : 0;
        message6.topicIDs.forEach((topic)=>{
            const tstats = peer_stats_1.ensureTopicStats(topic, pstats, this.params);
            if (!tstats) return;
            if (!tstats.inMesh) return;
            const tparams = this.params.topics[topic];
            // check against the mesh delivery window -- if the validated time is passed as 0, then
            // the message was received before we finished validation and thus falls within the mesh
            // delivery window.
            if (validatedTime && now > validatedTime + tparams.meshMessageDeliveriesWindow) return;
            const cap = tparams.meshMessageDeliveriesCap;
            tstats.meshMessageDeliveries += 1;
            if (tstats.meshMessageDeliveries > cap) tstats.meshMessageDeliveries = cap;
        });
    }
    /**
     * Gets the current IPs for a peer.
     * @param {string} id
     * @returns {Array<string>}
     */ _getIPs(id9) {
        return this._connectionManager.getAll(peer_id_1.default.createFromB58String(id9)).map((c)=>c.remoteAddr.toOptions().host
        );
    }
    /**
     * Adds tracking for the new IPs in the list, and removes tracking from the obsolete IPs.
     * @param {string} id
     * @param {Array<string>} newIPs
     * @param {Array<string>} oldIPs
     * @returns {void}
     */ _setIPs(id10, newIPs1, oldIPs) {
        // add the new IPs to the tracking
        // eslint-disable-next-line no-labels
        addNewIPs: for (const ip of newIPs1){
            // check if it is in the old ips list
            for (const xip of oldIPs){
                if (ip === xip) continue addNewIPs;
            }
            // no, it's a new one -- add it to the tracker
            let peers = this.peerIPs.get(ip);
            if (!peers) {
                peers = new Set();
                this.peerIPs.set(ip, peers);
            }
            peers.add(id10);
        }
        // remove the obsolete old IPs from the tracking
        // eslint-disable-next-line no-labels
        removeOldIPs: for (const ip1 of oldIPs){
            // check if it is in the new ips list
            for (const xip of newIPs1){
                if (ip1 === xip) continue removeOldIPs;
            }
            // no, its obselete -- remove it from the tracker
            const peers = this.peerIPs.get(ip1);
            if (!peers) continue;
            peers.delete(id10);
            if (!peers.size) this.peerIPs.delete(ip1);
        }
    }
    /**
     * Removes an IP list from the tracking list for a peer.
     * @param {string} id
     * @param {Array<string>} ips
     * @returns {void}
     */ _removeIPs(id11, ips) {
        ips.forEach((ip)=>{
            const peers = this.peerIPs.get(ip);
            if (!peers) return;
            peers.delete(id11);
            if (!peers.size) this.peerIPs.delete(ip);
        });
    }
    /**
     * Update all peer IPs to currently open connections
     * @returns {void}
     */ _updateIPs() {
        this.peerStats.forEach((pstats, id)=>{
            const newIPs = this._getIPs(id);
            this._setIPs(id, newIPs, pstats.ips);
            pstats.ips = newIPs;
        });
    }
}
exports.PeerScore = PeerScore;

},{"./peer-score-params":"44RQl","./peer-stats":"jmWLp","./compute-score":"e1TPW","./message-deliveries":"jVhKM","../constants":"dwqwi","peer-id":"4VGWt","debug":"lWlU4","libp2p-interfaces/src/pubsub/errors":"gGoLI"}],"jmWLp":[function(require,module,exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.ensureTopicStats = exports.createTopicStats = exports.createPeerStats = void 0;
function createPeerStats(ps = {
}) {
    return Object.assign(Object.assign({
        connected: false,
        expire: 0,
        ips: [],
        behaviourPenalty: 0
    }, ps), {
        topics: ps.topics ? Object.entries(ps.topics).reduce((topics, [topic, topicStats])=>{
            topics[topic] = createTopicStats(topicStats);
            return topics;
        }, {
        }) : {
        }
    });
}
exports.createPeerStats = createPeerStats;
function createTopicStats(ts = {
}) {
    return Object.assign({
        inMesh: false,
        graftTime: 0,
        meshTime: 0,
        firstMessageDeliveries: 0,
        meshMessageDeliveries: 0,
        meshMessageDeliveriesActive: false,
        meshFailurePenalty: 0,
        invalidMessageDeliveries: 0
    }, ts);
}
exports.createTopicStats = createTopicStats;
function ensureTopicStats(topic, ps, params) {
    let ts = ps.topics[topic];
    if (ts) return ts;
    if (!params.topics[topic]) return undefined;
    ps.topics[topic] = ts = createTopicStats();
    return ts;
}
exports.ensureTopicStats = ensureTopicStats;

},{}],"e1TPW":[function(require,module,exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.computeScore = void 0;
function computeScore(peer, pstats, params, peerIPs) {
    let score = 0;
    // topic stores
    Object.entries(pstats.topics).forEach(([topic, tstats])=>{
        // the topic parameters
        const topicParams = params.topics[topic];
        if (!topicParams) // we are not scoring this topic
        return;
        let topicScore = 0;
        // P1: time in Mesh
        if (tstats.inMesh) {
            let p1 = tstats.meshTime / topicParams.timeInMeshQuantum;
            if (p1 > topicParams.timeInMeshCap) p1 = topicParams.timeInMeshCap;
            topicScore += p1 * topicParams.timeInMeshWeight;
        }
        // P2: first message deliveries
        const p2 = tstats.firstMessageDeliveries;
        topicScore += p2 * topicParams.firstMessageDeliveriesWeight;
        // P3: mesh message deliveries
        if (tstats.meshMessageDeliveriesActive) {
            if (tstats.meshMessageDeliveries < topicParams.meshMessageDeliveriesThreshold) {
                const deficit = topicParams.meshMessageDeliveriesThreshold - tstats.meshMessageDeliveries;
                const p3 = deficit * deficit;
                topicScore += p3 * topicParams.meshMessageDeliveriesWeight;
            }
        }
        // P3b:
        // NOTE: the weight of P3b is negative (validated in validateTopicScoreParams) so this detracts
        const p3b = tstats.meshFailurePenalty;
        topicScore += p3b * topicParams.meshFailurePenaltyWeight;
        // P4: invalid messages
        // NOTE: the weight of P4 is negative (validated in validateTopicScoreParams) so this detracts
        const p4 = tstats.invalidMessageDeliveries * tstats.invalidMessageDeliveries;
        topicScore += p4 * topicParams.invalidMessageDeliveriesWeight;
        // update score, mixing with topic weight
        score += topicScore * topicParams.topicWeight;
    });
    // apply the topic score cap, if any
    if (params.topicScoreCap > 0 && score > params.topicScoreCap) score = params.topicScoreCap;
    // P5: application-specific score
    const p5 = params.appSpecificScore(peer);
    score += p5 * params.appSpecificWeight;
    // P6: IP colocation factor
    pstats.ips.forEach((ip)=>{
        if (params.IPColocationFactorWhitelist.has(ip)) return;
        // P6 has a cliff (IPColocationFactorThreshold)
        // It's only applied if at least that many peers are connected to us from that source IP addr.
        // It is quadratic, and the weight is negative (validated in validatePeerScoreParams)
        const peersInIP = peerIPs.get(ip);
        const numPeersInIP = peersInIP ? peersInIP.size : 0;
        if (numPeersInIP > params.IPColocationFactorThreshold) {
            const surplus = numPeersInIP - params.IPColocationFactorThreshold;
            const p6 = surplus * surplus;
            score += p6 * params.IPColocationFactorWeight;
        }
    });
    // P7: behavioural pattern penalty
    const p7 = pstats.behaviourPenalty * pstats.behaviourPenalty;
    score += p7 * params.behaviourPenaltyWeight;
    return score;
}
exports.computeScore = computeScore;

},{}],"jVhKM":[function(require,module,exports) {
"use strict";
var __importDefault = this && this.__importDefault || function(mod) {
    return mod && mod.__esModule ? mod : {
        "default": mod
    };
};
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.MessageDeliveries = exports.DeliveryRecordStatus = void 0;
const constants_1 = require("../constants");
const denque_1 = __importDefault(require("denque"));
const utils_1 = require("../utils");
var DeliveryRecordStatus1;
(function(DeliveryRecordStatus) {
    /**
     * we don't know (yet) if the message is valid
     */ DeliveryRecordStatus[DeliveryRecordStatus["unknown"] = 0] = "unknown";
    /**
     * we know the message is valid
     */ DeliveryRecordStatus[DeliveryRecordStatus["valid"] = 1] = "valid";
    /**
     * we know the message is invalid
     */ DeliveryRecordStatus[DeliveryRecordStatus["invalid"] = 2] = "invalid";
    /**
     * we were instructed by the validator to ignore the message
     */ DeliveryRecordStatus[DeliveryRecordStatus["ignored"] = 3] = "ignored";
})(DeliveryRecordStatus1 = exports.DeliveryRecordStatus || (exports.DeliveryRecordStatus = {
}));
/**
 * Map of message ID to DeliveryRecord
 *
 * Maintains an internal queue for efficient gc of old messages
 */ class MessageDeliveries {
    constructor(){
        this.records = new Map();
        this.queue = new denque_1.default();
    }
    ensureRecord(msgId) {
        const msgIdStr = utils_1.messageIdToString(msgId);
        let drec = this.records.get(msgIdStr);
        if (drec) return drec;
        // record doesn't exist yet
        // create record
        drec = {
            status: DeliveryRecordStatus1.unknown,
            firstSeen: Date.now(),
            validated: 0,
            peers: new Set()
        };
        this.records.set(msgIdStr, drec);
        // and add msgId to the queue
        const entry = {
            msgId: msgIdStr,
            expire: Date.now() + constants_1.TimeCacheDuration
        };
        this.queue.push(entry);
        return drec;
    }
    gc() {
        const now = Date.now();
        // queue is sorted by expiry time
        // remove expired messages, remove from queue until first un-expired message found
        let head = this.queue.peekFront();
        while(head && head.expire < now){
            this.records.delete(head.msgId);
            this.queue.shift();
            head = this.queue.peekFront();
        }
    }
    clear() {
        this.records.clear();
        this.queue.clear();
    }
}
exports.MessageDeliveries = MessageDeliveries;

},{"../constants":"dwqwi","denque":"3pu2Q","../utils":"j1LCn"}],"3pu2Q":[function(require,module,exports) {
'use strict';
/**
 * Custom implementation of a double ended queue.
 */ function Denque(array, options) {
    var options = options || {
    };
    this._head = 0;
    this._tail = 0;
    this._capacity = options.capacity;
    this._capacityMask = 3;
    this._list = new Array(4);
    if (Array.isArray(array)) this._fromArray(array);
}
/**
 * -------------
 *  PUBLIC API
 * -------------
 */ /**
 * Returns the item at the specified index from the list.
 * 0 is the first element, 1 is the second, and so on...
 * Elements at negative values are that many from the end: -1 is one before the end
 * (the last element), -2 is two before the end (one before last), etc.
 * @param index
 * @returns {*}
 */ Denque.prototype.peekAt = function peekAt(index) {
    var i = index;
    // expect a number or return undefined
    if (i !== (i | 0)) return void 0;
    var len = this.size();
    if (i >= len || i < -len) return undefined;
    if (i < 0) i += len;
    i = this._head + i & this._capacityMask;
    return this._list[i];
};
/**
 * Alias for peekAt()
 * @param i
 * @returns {*}
 */ Denque.prototype.get = function get(i) {
    return this.peekAt(i);
};
/**
 * Returns the first item in the list without removing it.
 * @returns {*}
 */ Denque.prototype.peek = function peek() {
    if (this._head === this._tail) return undefined;
    return this._list[this._head];
};
/**
 * Alias for peek()
 * @returns {*}
 */ Denque.prototype.peekFront = function peekFront() {
    return this.peek();
};
/**
 * Returns the item that is at the back of the queue without removing it.
 * Uses peekAt(-1)
 */ Denque.prototype.peekBack = function peekBack() {
    return this.peekAt(-1);
};
/**
 * Returns the current length of the queue
 * @return {Number}
 */ Object.defineProperty(Denque.prototype, 'length', {
    get: function length() {
        return this.size();
    }
});
/**
 * Return the number of items on the list, or 0 if empty.
 * @returns {number}
 */ Denque.prototype.size = function size() {
    if (this._head === this._tail) return 0;
    if (this._head < this._tail) return this._tail - this._head;
    else return this._capacityMask + 1 - (this._head - this._tail);
};
/**
 * Add an item at the beginning of the list.
 * @param item
 */ Denque.prototype.unshift = function unshift(item) {
    if (item === undefined) return this.size();
    var len = this._list.length;
    this._head = this._head - 1 + len & this._capacityMask;
    this._list[this._head] = item;
    if (this._tail === this._head) this._growArray();
    if (this._capacity && this.size() > this._capacity) this.pop();
    if (this._head < this._tail) return this._tail - this._head;
    else return this._capacityMask + 1 - (this._head - this._tail);
};
/**
 * Remove and return the first item on the list,
 * Returns undefined if the list is empty.
 * @returns {*}
 */ Denque.prototype.shift = function shift() {
    var head = this._head;
    if (head === this._tail) return undefined;
    var item = this._list[head];
    this._list[head] = undefined;
    this._head = head + 1 & this._capacityMask;
    if (head < 2 && this._tail > 10000 && this._tail <= this._list.length >>> 2) this._shrinkArray();
    return item;
};
/**
 * Add an item to the bottom of the list.
 * @param item
 */ Denque.prototype.push = function push(item) {
    if (item === undefined) return this.size();
    var tail = this._tail;
    this._list[tail] = item;
    this._tail = tail + 1 & this._capacityMask;
    if (this._tail === this._head) this._growArray();
    if (this._capacity && this.size() > this._capacity) this.shift();
    if (this._head < this._tail) return this._tail - this._head;
    else return this._capacityMask + 1 - (this._head - this._tail);
};
/**
 * Remove and return the last item on the list.
 * Returns undefined if the list is empty.
 * @returns {*}
 */ Denque.prototype.pop = function pop() {
    var tail = this._tail;
    if (tail === this._head) return undefined;
    var len = this._list.length;
    this._tail = tail - 1 + len & this._capacityMask;
    var item = this._list[this._tail];
    this._list[this._tail] = undefined;
    if (this._head < 2 && tail > 10000 && tail <= len >>> 2) this._shrinkArray();
    return item;
};
/**
 * Remove and return the item at the specified index from the list.
 * Returns undefined if the list is empty.
 * @param index
 * @returns {*}
 */ Denque.prototype.removeOne = function removeOne(index) {
    var i = index;
    // expect a number or return undefined
    if (i !== (i | 0)) return void 0;
    if (this._head === this._tail) return void 0;
    var size = this.size();
    var len = this._list.length;
    if (i >= size || i < -size) return void 0;
    if (i < 0) i += size;
    i = this._head + i & this._capacityMask;
    var item = this._list[i];
    var k;
    if (index < size / 2) {
        for(k = index; k > 0; k--)this._list[i] = this._list[i = i - 1 + len & this._capacityMask];
        this._list[i] = void 0;
        this._head = this._head + 1 + len & this._capacityMask;
    } else {
        for(k = size - 1 - index; k > 0; k--)this._list[i] = this._list[i = i + 1 + len & this._capacityMask];
        this._list[i] = void 0;
        this._tail = this._tail - 1 + len & this._capacityMask;
    }
    return item;
};
/**
 * Remove number of items from the specified index from the list.
 * Returns array of removed items.
 * Returns undefined if the list is empty.
 * @param index
 * @param count
 * @returns {array}
 */ Denque.prototype.remove = function remove(index, count) {
    var i = index;
    var removed;
    var del_count = count;
    // expect a number or return undefined
    if (i !== (i | 0)) return void 0;
    if (this._head === this._tail) return void 0;
    var size = this.size();
    var len = this._list.length;
    if (i >= size || i < -size || count < 1) return void 0;
    if (i < 0) i += size;
    if (count === 1 || !count) {
        removed = new Array(1);
        removed[0] = this.removeOne(i);
        return removed;
    }
    if (i === 0 && i + count >= size) {
        removed = this.toArray();
        this.clear();
        return removed;
    }
    if (i + count > size) count = size - i;
    var k;
    removed = new Array(count);
    for(k = 0; k < count; k++)removed[k] = this._list[this._head + i + k & this._capacityMask];
    i = this._head + i & this._capacityMask;
    if (index + count === size) {
        this._tail = this._tail - count + len & this._capacityMask;
        for(k = count; k > 0; k--)this._list[i = i + 1 + len & this._capacityMask] = void 0;
        return removed;
    }
    if (index === 0) {
        this._head = this._head + count + len & this._capacityMask;
        for(k = count - 1; k > 0; k--)this._list[i = i + 1 + len & this._capacityMask] = void 0;
        return removed;
    }
    if (i < size / 2) {
        this._head = this._head + index + count + len & this._capacityMask;
        for(k = index; k > 0; k--)this.unshift(this._list[i = i - 1 + len & this._capacityMask]);
        i = this._head - 1 + len & this._capacityMask;
        while(del_count > 0){
            this._list[i = i - 1 + len & this._capacityMask] = void 0;
            del_count--;
        }
        if (index < 0) this._tail = i;
    } else {
        this._tail = i;
        i = i + count + len & this._capacityMask;
        for(k = size - (count + index); k > 0; k--)this.push(this._list[i++]);
        i = this._tail;
        while(del_count > 0){
            this._list[i = i + 1 + len & this._capacityMask] = void 0;
            del_count--;
        }
    }
    if (this._head < 2 && this._tail > 10000 && this._tail <= len >>> 2) this._shrinkArray();
    return removed;
};
/**
 * Native splice implementation.
 * Remove number of items from the specified index from the list and/or add new elements.
 * Returns array of removed items or empty array if count == 0.
 * Returns undefined if the list is empty.
 *
 * @param index
 * @param count
 * @param {...*} [elements]
 * @returns {array}
 */ Denque.prototype.splice = function splice(index, count) {
    var i = index;
    // expect a number or return undefined
    if (i !== (i | 0)) return void 0;
    var size = this.size();
    if (i < 0) i += size;
    if (i > size) return void 0;
    if (arguments.length > 2) {
        var k;
        var temp;
        var removed;
        var arg_len = arguments.length;
        var len = this._list.length;
        var arguments_index = 2;
        if (!size || i < size / 2) {
            temp = new Array(i);
            for(k = 0; k < i; k++)temp[k] = this._list[this._head + k & this._capacityMask];
            if (count === 0) {
                removed = [];
                if (i > 0) this._head = this._head + i + len & this._capacityMask;
            } else {
                removed = this.remove(i, count);
                this._head = this._head + i + len & this._capacityMask;
            }
            while(arg_len > arguments_index)this.unshift(arguments[--arg_len]);
            for(k = i; k > 0; k--)this.unshift(temp[k - 1]);
        } else {
            temp = new Array(size - (i + count));
            var leng = temp.length;
            for(k = 0; k < leng; k++)temp[k] = this._list[this._head + i + count + k & this._capacityMask];
            if (count === 0) {
                removed = [];
                if (i != size) this._tail = this._head + i + len & this._capacityMask;
            } else {
                removed = this.remove(i, count);
                this._tail = this._tail - leng + len & this._capacityMask;
            }
            while(arguments_index < arg_len)this.push(arguments[arguments_index++]);
            for(k = 0; k < leng; k++)this.push(temp[k]);
        }
        return removed;
    } else return this.remove(i, count);
};
/**
 * Soft clear - does not reset capacity.
 */ Denque.prototype.clear = function clear() {
    this._head = 0;
    this._tail = 0;
};
/**
 * Returns true or false whether the list is empty.
 * @returns {boolean}
 */ Denque.prototype.isEmpty = function isEmpty() {
    return this._head === this._tail;
};
/**
 * Returns an array of all queue items.
 * @returns {Array}
 */ Denque.prototype.toArray = function toArray() {
    return this._copyArray(false);
};
/**
 * -------------
 *   INTERNALS
 * -------------
 */ /**
 * Fills the queue with items from an array
 * For use in the constructor
 * @param array
 * @private
 */ Denque.prototype._fromArray = function _fromArray(array) {
    for(var i = 0; i < array.length; i++)this.push(array[i]);
};
/**
 *
 * @param fullCopy
 * @returns {Array}
 * @private
 */ Denque.prototype._copyArray = function _copyArray(fullCopy) {
    var newArray = [];
    var list = this._list;
    var len = list.length;
    var i;
    if (fullCopy || this._head > this._tail) {
        for(i = this._head; i < len; i++)newArray.push(list[i]);
        for(i = 0; i < this._tail; i++)newArray.push(list[i]);
    } else for(i = this._head; i < this._tail; i++)newArray.push(list[i]);
    return newArray;
};
/**
 * Grows the internal list array.
 * @private
 */ Denque.prototype._growArray = function _growArray() {
    if (this._head) {
        // copy existing data, head to end, then beginning to tail.
        this._list = this._copyArray(true);
        this._head = 0;
    }
    // head is at 0 and array is now full, safe to extend
    this._tail = this._list.length;
    this._list.length <<= 1;
    this._capacityMask = this._capacityMask << 1 | 1;
};
/**
 * Shrinks the internal list array.
 * @private
 */ Denque.prototype._shrinkArray = function _shrinkArray() {
    this._list.length >>>= 1;
    this._capacityMask >>>= 1;
};
module.exports = Denque;

},{}],"lSw9z":[function(require,module,exports) {
"use strict";
var __awaiter = this && this.__awaiter || function(thisArg, _arguments, P, generator) {
    function adopt(value) {
        return value instanceof P ? value : new P(function(resolve) {
            resolve(value);
        });
    }
    return new (P || (P = Promise))(function(resolve, reject) {
        function fulfilled(value) {
            try {
                step(generator.next(value));
            } catch (e) {
                reject(e);
            }
        }
        function rejected(value) {
            try {
                step(generator["throw"](value));
            } catch (e) {
                reject(e);
            }
        }
        function step(result) {
            result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
        }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.IWantTracer = void 0;
const constants_1 = require("./constants");
const utils_1 = require("./utils");
const pubsubErrors = require("libp2p-interfaces/src/pubsub/errors");
const { ERR_INVALID_SIGNATURE , ERR_MISSING_SIGNATURE  } = pubsubErrors.codes;
/**
 * IWantTracer is an internal tracer that tracks IWANT requests in order to penalize
 * peers who don't follow up on IWANT requests after an IHAVE advertisement.
 * The tracking of promises is probabilistic to avoid using too much memory.
 *
 * Note: Do not confuse these 'promises' with JS Promise objects.
 * These 'promises' are merely expectations of a peer's behavior.
 */ class IWantTracer {
    constructor(getMsgId){
        this.getMsgId = getMsgId;
        this.promises = new Map();
    }
    /**
     * Track a promise to deliver a message from a list of msgIDs we are requesting
     * @param {string} p peer id
     * @param {string[]} msgIds
     * @returns {void}
     */ addPromise(p1, msgIds) {
        // pick msgId randomly from the list
        const ix = Math.floor(Math.random() * msgIds.length);
        const msgId = msgIds[ix];
        const msgIdStr = utils_1.messageIdToString(msgId);
        let peers = this.promises.get(msgIdStr);
        if (!peers) {
            peers = new Map();
            this.promises.set(msgIdStr, peers);
        }
        if (!peers.has(p1)) peers.set(p1, Date.now() + constants_1.GossipsubIWantFollowupTime);
    }
    /**
     * Returns the number of broken promises for each peer who didn't follow up on an IWANT request.
     * @returns {Map<string, number>}
     */ getBrokenPromises() {
        const now = Date.now();
        const result = new Map();
        this.promises.forEach((peers, msgId)=>{
            peers.forEach((expire, p)=>{
                // the promise has been broken
                if (expire < now) {
                    // add 1 to result
                    result.set(p, (result.get(p) || 0) + 1);
                    // delete from tracked promises
                    peers.delete(p);
                }
            });
            // clean up empty promises for a msgId
            if (!peers.size) this.promises.delete(msgId);
        });
        return result;
    }
    /**
     * Someone delivered a message, stop tracking promises for it
     * @param {InMessage} msg
     * @returns {Promise<void>}
     */ deliverMessage(msg) {
        return __awaiter(this, void 0, void 0, function*() {
            const msgId = yield this.getMsgId(msg);
            const msgIdStr = utils_1.messageIdToString(msgId);
            this.promises.delete(msgIdStr);
        });
    }
    /**
     * A message got rejected, so we can stop tracking promises and let the score penalty apply from invalid message delivery,
     * unless its an obviously invalid message.
     * @param {InMessage} msg
     * @param {string} reason
     * @returns {Promise<void>}
     */ rejectMessage(msg1, reason) {
        return __awaiter(this, void 0, void 0, function*() {
            switch(reason){
                case ERR_INVALID_SIGNATURE:
                case ERR_MISSING_SIGNATURE:
                    return;
            }
            const msgId = yield this.getMsgId(msg1);
            const msgIdStr = utils_1.messageIdToString(msgId);
            this.promises.delete(msgIdStr);
        });
    }
    clear() {
        this.promises.clear();
    }
}
exports.IWantTracer = IWantTracer;

},{"./constants":"dwqwi","./utils":"j1LCn","libp2p-interfaces/src/pubsub/errors":"gGoLI"}],"2bWKq":[function(require,module,exports) {
'use strict';
const throttle = require('lodash.throttle');
exports = module.exports = TimeCache;
function TimeCache(options) {
    if (!(this instanceof TimeCache)) return new TimeCache(options);
    options = options || {
    };
    const validity1 = options.validity || 30 // seconds
    ;
    const entries = new Map();
    const sweep = throttle(()=>{
        entries.forEach((entry, key)=>{
            const v = entry.validity || validity1;
            const delta = getTimeElapsed(entry.timestamp);
            if (delta > v) entries.delete(key);
        });
    }, 200);
    this.put = (key, value, validity)=>{
        if (!this.has(key)) entries.set(key, {
            value: value,
            timestamp: new Date(),
            validity: validity
        });
        sweep();
    };
    this.get = (key)=>{
        if (entries.has(key)) return entries.get(key).value;
        else throw new Error('key does not exist');
    };
    this.has = (key)=>{
        return entries.has(key);
    };
}
function getTimeElapsed(prevTime) {
    const currentTime = new Date();
    const a = currentTime.getTime() - prevTime.getTime();
    return Math.floor(a / 1000);
}

},{"lodash.throttle":"4tFBc"}],"4tFBc":[function(require,module,exports) {
var global = arguments[3];
/**
 * lodash (Custom Build) <https://lodash.com/>
 * Build: `lodash modularize exports="npm" -o ./`
 * Copyright jQuery Foundation and other contributors <https://jquery.org/>
 * Released under MIT license <https://lodash.com/license>
 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
 */ /** Used as the `TypeError` message for "Functions" methods. */ var FUNC_ERROR_TEXT = 'Expected a function';
/** Used as references for various `Number` constants. */ var NAN = 0 / 0;
/** `Object#toString` result references. */ var symbolTag = '[object Symbol]';
/** Used to match leading and trailing whitespace. */ var reTrim = /^\s+|\s+$/g;
/** Used to detect bad signed hexadecimal string values. */ var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
/** Used to detect binary string values. */ var reIsBinary = /^0b[01]+$/i;
/** Used to detect octal string values. */ var reIsOctal = /^0o[0-7]+$/i;
/** Built-in method references without a dependency on `root`. */ var freeParseInt = parseInt;
/** Detect free variable `global` from Node.js. */ var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
/** Detect free variable `self`. */ var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
/** Used as a reference to the global object. */ var root = freeGlobal || freeSelf || Function('return this')();
/** Used for built-in method references. */ var objectProto = Object.prototype;
/**
 * Used to resolve the
 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
 * of values.
 */ var objectToString = objectProto.toString;
/* Built-in method references for those with the same name as other `lodash` methods. */ var nativeMax = Math.max, nativeMin = Math.min;
/**
 * Gets the timestamp of the number of milliseconds that have elapsed since
 * the Unix epoch (1 January 1970 00:00:00 UTC).
 *
 * @static
 * @memberOf _
 * @since 2.4.0
 * @category Date
 * @returns {number} Returns the timestamp.
 * @example
 *
 * _.defer(function(stamp) {
 *   console.log(_.now() - stamp);
 * }, _.now());
 * // => Logs the number of milliseconds it took for the deferred invocation.
 */ var now = function() {
    return root.Date.now();
};
/**
 * Creates a debounced function that delays invoking `func` until after `wait`
 * milliseconds have elapsed since the last time the debounced function was
 * invoked. The debounced function comes with a `cancel` method to cancel
 * delayed `func` invocations and a `flush` method to immediately invoke them.
 * Provide `options` to indicate whether `func` should be invoked on the
 * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
 * with the last arguments provided to the debounced function. Subsequent
 * calls to the debounced function return the result of the last `func`
 * invocation.
 *
 * **Note:** If `leading` and `trailing` options are `true`, `func` is
 * invoked on the trailing edge of the timeout only if the debounced function
 * is invoked more than once during the `wait` timeout.
 *
 * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
 * until to the next tick, similar to `setTimeout` with a timeout of `0`.
 *
 * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
 * for details over the differences between `_.debounce` and `_.throttle`.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Function
 * @param {Function} func The function to debounce.
 * @param {number} [wait=0] The number of milliseconds to delay.
 * @param {Object} [options={}] The options object.
 * @param {boolean} [options.leading=false]
 *  Specify invoking on the leading edge of the timeout.
 * @param {number} [options.maxWait]
 *  The maximum time `func` is allowed to be delayed before it's invoked.
 * @param {boolean} [options.trailing=true]
 *  Specify invoking on the trailing edge of the timeout.
 * @returns {Function} Returns the new debounced function.
 * @example
 *
 * // Avoid costly calculations while the window size is in flux.
 * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
 *
 * // Invoke `sendMail` when clicked, debouncing subsequent calls.
 * jQuery(element).on('click', _.debounce(sendMail, 300, {
 *   'leading': true,
 *   'trailing': false
 * }));
 *
 * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
 * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
 * var source = new EventSource('/stream');
 * jQuery(source).on('message', debounced);
 *
 * // Cancel the trailing debounced invocation.
 * jQuery(window).on('popstate', debounced.cancel);
 */ function debounce(func, wait, options) {
    var lastArgs, lastThis, maxWait, result1, timerId, lastCallTime, lastInvokeTime = 0, leading = false, maxing = false, trailing = true;
    if (typeof func != 'function') throw new TypeError(FUNC_ERROR_TEXT);
    wait = toNumber(wait) || 0;
    if (isObject(options)) {
        leading = !!options.leading;
        maxing = 'maxWait' in options;
        maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
        trailing = 'trailing' in options ? !!options.trailing : trailing;
    }
    function invokeFunc(time) {
        var args = lastArgs, thisArg = lastThis;
        lastArgs = lastThis = undefined;
        lastInvokeTime = time;
        result1 = func.apply(thisArg, args);
        return result1;
    }
    function leadingEdge(time) {
        // Reset any `maxWait` timer.
        lastInvokeTime = time;
        // Start the timer for the trailing edge.
        timerId = setTimeout(timerExpired, wait);
        // Invoke the leading edge.
        return leading ? invokeFunc(time) : result1;
    }
    function remainingWait(time) {
        var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime, result = wait - timeSinceLastCall;
        return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
    }
    function shouldInvoke(time) {
        var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime;
        // Either this is the first call, activity has stopped and we're at the
        // trailing edge, the system time has gone backwards and we're treating
        // it as the trailing edge, or we've hit the `maxWait` limit.
        return lastCallTime === undefined || timeSinceLastCall >= wait || timeSinceLastCall < 0 || maxing && timeSinceLastInvoke >= maxWait;
    }
    function timerExpired() {
        var time = now();
        if (shouldInvoke(time)) return trailingEdge(time);
        // Restart the timer.
        timerId = setTimeout(timerExpired, remainingWait(time));
    }
    function trailingEdge(time) {
        timerId = undefined;
        // Only invoke if we have `lastArgs` which means `func` has been
        // debounced at least once.
        if (trailing && lastArgs) return invokeFunc(time);
        lastArgs = lastThis = undefined;
        return result1;
    }
    function cancel() {
        if (timerId !== undefined) clearTimeout(timerId);
        lastInvokeTime = 0;
        lastArgs = lastCallTime = lastThis = timerId = undefined;
    }
    function flush() {
        return timerId === undefined ? result1 : trailingEdge(now());
    }
    function debounced() {
        var time = now(), isInvoking = shouldInvoke(time);
        lastArgs = arguments;
        lastThis = this;
        lastCallTime = time;
        if (isInvoking) {
            if (timerId === undefined) return leadingEdge(lastCallTime);
            if (maxing) {
                // Handle invocations in a tight loop.
                timerId = setTimeout(timerExpired, wait);
                return invokeFunc(lastCallTime);
            }
        }
        if (timerId === undefined) timerId = setTimeout(timerExpired, wait);
        return result1;
    }
    debounced.cancel = cancel;
    debounced.flush = flush;
    return debounced;
}
/**
 * Creates a throttled function that only invokes `func` at most once per
 * every `wait` milliseconds. The throttled function comes with a `cancel`
 * method to cancel delayed `func` invocations and a `flush` method to
 * immediately invoke them. Provide `options` to indicate whether `func`
 * should be invoked on the leading and/or trailing edge of the `wait`
 * timeout. The `func` is invoked with the last arguments provided to the
 * throttled function. Subsequent calls to the throttled function return the
 * result of the last `func` invocation.
 *
 * **Note:** If `leading` and `trailing` options are `true`, `func` is
 * invoked on the trailing edge of the timeout only if the throttled function
 * is invoked more than once during the `wait` timeout.
 *
 * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
 * until to the next tick, similar to `setTimeout` with a timeout of `0`.
 *
 * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
 * for details over the differences between `_.throttle` and `_.debounce`.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Function
 * @param {Function} func The function to throttle.
 * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
 * @param {Object} [options={}] The options object.
 * @param {boolean} [options.leading=true]
 *  Specify invoking on the leading edge of the timeout.
 * @param {boolean} [options.trailing=true]
 *  Specify invoking on the trailing edge of the timeout.
 * @returns {Function} Returns the new throttled function.
 * @example
 *
 * // Avoid excessively updating the position while scrolling.
 * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
 *
 * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
 * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
 * jQuery(element).on('click', throttled);
 *
 * // Cancel the trailing throttled invocation.
 * jQuery(window).on('popstate', throttled.cancel);
 */ function throttle(func, wait, options) {
    var leading = true, trailing = true;
    if (typeof func != 'function') throw new TypeError(FUNC_ERROR_TEXT);
    if (isObject(options)) {
        leading = 'leading' in options ? !!options.leading : leading;
        trailing = 'trailing' in options ? !!options.trailing : trailing;
    }
    return debounce(func, wait, {
        'leading': leading,
        'maxWait': wait,
        'trailing': trailing
    });
}
/**
 * Checks if `value` is the
 * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
 * @example
 *
 * _.isObject({});
 * // => true
 *
 * _.isObject([1, 2, 3]);
 * // => true
 *
 * _.isObject(_.noop);
 * // => true
 *
 * _.isObject(null);
 * // => false
 */ function isObject(value) {
    var type = typeof value;
    return !!value && (type == 'object' || type == 'function');
}
/**
 * Checks if `value` is object-like. A value is object-like if it's not `null`
 * and has a `typeof` result of "object".
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
 * @example
 *
 * _.isObjectLike({});
 * // => true
 *
 * _.isObjectLike([1, 2, 3]);
 * // => true
 *
 * _.isObjectLike(_.noop);
 * // => false
 *
 * _.isObjectLike(null);
 * // => false
 */ function isObjectLike(value) {
    return !!value && typeof value == 'object';
}
/**
 * Checks if `value` is classified as a `Symbol` primitive or object.
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
 * @example
 *
 * _.isSymbol(Symbol.iterator);
 * // => true
 *
 * _.isSymbol('abc');
 * // => false
 */ function isSymbol(value) {
    return typeof value == 'symbol' || isObjectLike(value) && objectToString.call(value) == symbolTag;
}
/**
 * Converts `value` to a number.
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to process.
 * @returns {number} Returns the number.
 * @example
 *
 * _.toNumber(3.2);
 * // => 3.2
 *
 * _.toNumber(Number.MIN_VALUE);
 * // => 5e-324
 *
 * _.toNumber(Infinity);
 * // => Infinity
 *
 * _.toNumber('3.2');
 * // => 3.2
 */ function toNumber(value) {
    if (typeof value == 'number') return value;
    if (isSymbol(value)) return NAN;
    if (isObject(value)) {
        var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
        value = isObject(other) ? other + '' : other;
    }
    if (typeof value != 'string') return value === 0 ? value : +value;
    value = value.replace(reTrim, '');
    var isBinary = reIsBinary.test(value);
    return isBinary || reIsOctal.test(value) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : reIsBadHex.test(value) ? NAN : +value;
}
module.exports = throttle;

},{}],"dFiHn":[function(require,module,exports) {
'use strict';
const errCode = require('err-code');
const { concat: uint8arraysConcat  } = require('uint8arrays/concat');
const { fromString: uint8arraysFromString  } = require('uint8arrays/from-string');
// @ts-ignore libp2p-crypto does not support types
const cryptoKeys = require('libp2p-crypto/src/keys');
const PeerId = require('peer-id');
const varint = require('varint');
const { equals: uint8arraysEquals  } = require('uint8arrays/equals');
const { codes  } = require('../../errors');
const { Envelope: Protobuf  } = require('./envelope');
/**
 * @typedef {import('libp2p-interfaces/src/record/types').Record} Record
 */ class Envelope {
    /**
   * The Envelope is responsible for keeping an arbitrary signed record
   * by a libp2p peer.
   *
   * @class
   * @param {object} params
   * @param {PeerId} params.peerId
   * @param {Uint8Array} params.payloadType
   * @param {Uint8Array} params.payload - marshaled record
   * @param {Uint8Array} params.signature - signature of the domain string :: type hint :: payload.
   */ constructor({ peerId: peerId1 , payloadType: payloadType1 , payload: payload1 , signature: signature1  }){
        this.peerId = peerId1;
        this.payloadType = payloadType1;
        this.payload = payload1;
        this.signature = signature1;
        // Cache
        this._marshal = undefined;
    }
    /**
   * Marshal the envelope content.
   *
   * @returns {Uint8Array}
   */ marshal() {
        if (this._marshal) return this._marshal;
        const publicKey = cryptoKeys.marshalPublicKey(this.peerId.pubKey);
        this._marshal = Protobuf.encode({
            publicKey: publicKey,
            payloadType: this.payloadType,
            payload: this.payload,
            signature: this.signature
        }).finish();
        return this._marshal;
    }
    /**
   * Verifies if the other Envelope is identical to this one.
   *
   * @param {Envelope} other
   * @returns {boolean}
   */ equals(other) {
        return uint8arraysEquals(this.peerId.pubKey.bytes, other.peerId.pubKey.bytes) && uint8arraysEquals(this.payloadType, other.payloadType) && uint8arraysEquals(this.payload, other.payload) && uint8arraysEquals(this.signature, other.signature);
    }
    /**
   * Validate envelope data signature for the given domain.
   *
   * @param {string} domain
   * @returns {Promise<boolean>}
   */ validate(domain1) {
        const signData = formatSignaturePayload(domain1, this.payloadType, this.payload);
        return this.peerId.pubKey.verify(signData, this.signature);
    }
}
/**
 * Helper function that prepares a Uint8Array to sign or verify a signature.
 *
 * @param {string} domain
 * @param {Uint8Array} payloadType
 * @param {Uint8Array} payload
 * @returns {Uint8Array}
 */ const formatSignaturePayload = (domain, payloadType, payload)=>{
    // When signing, a peer will prepare a Uint8Array by concatenating the following:
    // - The length of the domain separation string string in bytes
    // - The domain separation string, encoded as UTF-8
    // - The length of the payload_type field in bytes
    // - The value of the payload_type field
    // - The length of the payload field in bytes
    // - The value of the payload field
    const domainUint8Array = uint8arraysFromString(domain);
    const domainLength = varint.encode(domainUint8Array.byteLength);
    const payloadTypeLength = varint.encode(payloadType.length);
    const payloadLength = varint.encode(payload.length);
    return uint8arraysConcat([
        new Uint8Array(domainLength),
        domainUint8Array,
        new Uint8Array(payloadTypeLength),
        payloadType,
        new Uint8Array(payloadLength),
        payload
    ]);
};
/**
 * Unmarshal a serialized Envelope protobuf message.
 *
 * @param {Uint8Array} data
 * @returns {Promise<Envelope>}
 */ Envelope.createFromProtobuf = async (data)=>{
    const envelopeData = Protobuf.decode(data);
    const peerId = await PeerId.createFromPubKey(envelopeData.publicKey);
    return new Envelope({
        peerId,
        payloadType: envelopeData.payloadType,
        payload: envelopeData.payload,
        signature: envelopeData.signature
    });
};
/**
 * Seal marshals the given Record, places the marshaled bytes inside an Envelope
 * and signs it with the given peerId's private key.
 *
 * @async
 * @param {Record} record
 * @param {PeerId} peerId
 * @returns {Promise<Envelope>}
 */ Envelope.seal = async (record, peerId)=>{
    const domain = record.domain;
    const payloadType = record.codec;
    const payload = record.marshal();
    const signData = formatSignaturePayload(domain, payloadType, payload);
    const signature = await peerId.privKey.sign(signData);
    return new Envelope({
        peerId,
        payloadType,
        payload,
        signature
    });
};
/**
 * Open and certify a given marshalled envelope.
 * Data is unmarshalled and the signature validated for the given domain.
 *
 * @param {Uint8Array} data
 * @param {string} domain
 * @returns {Promise<Envelope>}
 */ Envelope.openAndCertify = async (data, domain)=>{
    const envelope = await Envelope.createFromProtobuf(data);
    const valid = await envelope.validate(domain);
    if (!valid) throw errCode(new Error('envelope signature is not valid for the given domain'), codes.ERR_SIGNATURE_NOT_VALID);
    return envelope;
};
module.exports = Envelope;

},{"err-code":"eQvyh","uint8arrays/concat":"fLIrL","uint8arrays/from-string":"lo45E","libp2p-crypto/src/keys":"Ore66","peer-id":"4VGWt","varint":"l84uL","uint8arrays/equals":"fjLeN","../../errors":"dO31S","./envelope":"19k9T"}],"dO31S":[function(require,module,exports) {
'use strict';
exports.messages = {
    NOT_STARTED_YET: 'The libp2p node is not started yet',
    DHT_DISABLED: 'DHT is not available',
    CONN_ENCRYPTION_REQUIRED: 'At least one connection encryption module is required'
};
exports.codes = {
    DHT_DISABLED: 'ERR_DHT_DISABLED',
    PUBSUB_NOT_STARTED: 'ERR_PUBSUB_NOT_STARTED',
    DHT_NOT_STARTED: 'ERR_DHT_NOT_STARTED',
    CONN_ENCRYPTION_REQUIRED: 'ERR_CONN_ENCRYPTION_REQUIRED',
    ERR_INVALID_PROTOCOLS_FOR_STREAM: 'ERR_INVALID_PROTOCOLS_FOR_STREAM',
    ERR_CONNECTION_ENDED: 'ERR_CONNECTION_ENDED',
    ERR_CONNECTION_FAILED: 'ERR_CONNECTION_FAILED',
    ERR_NODE_NOT_STARTED: 'ERR_NODE_NOT_STARTED',
    ERR_ALREADY_ABORTED: 'ERR_ALREADY_ABORTED',
    ERR_TOO_MANY_ADDRESSES: 'ERR_TOO_MANY_ADDRESSES',
    ERR_NO_VALID_ADDRESSES: 'ERR_NO_VALID_ADDRESSES',
    ERR_RELAYED_DIAL: 'ERR_RELAYED_DIAL',
    ERR_DIALED_SELF: 'ERR_DIALED_SELF',
    ERR_DISCOVERED_SELF: 'ERR_DISCOVERED_SELF',
    ERR_DUPLICATE_TRANSPORT: 'ERR_DUPLICATE_TRANSPORT',
    ERR_ENCRYPTION_FAILED: 'ERR_ENCRYPTION_FAILED',
    ERR_HOP_REQUEST_FAILED: 'ERR_HOP_REQUEST_FAILED',
    ERR_INVALID_KEY: 'ERR_INVALID_KEY',
    ERR_INVALID_MESSAGE: 'ERR_INVALID_MESSAGE',
    ERR_INVALID_PARAMETERS: 'ERR_INVALID_PARAMETERS',
    ERR_INVALID_PEER: 'ERR_INVALID_PEER',
    ERR_MUXER_UNAVAILABLE: 'ERR_MUXER_UNAVAILABLE',
    ERR_TIMEOUT: 'ERR_TIMEOUT',
    ERR_TRANSPORT_UNAVAILABLE: 'ERR_TRANSPORT_UNAVAILABLE',
    ERR_TRANSPORT_DIAL_FAILED: 'ERR_TRANSPORT_DIAL_FAILED',
    ERR_UNSUPPORTED_PROTOCOL: 'ERR_UNSUPPORTED_PROTOCOL',
    ERR_INVALID_MULTIADDR: 'ERR_INVALID_MULTIADDR',
    ERR_SIGNATURE_NOT_VALID: 'ERR_SIGNATURE_NOT_VALID'
};

},{}],"19k9T":[function(require,module,exports) {
/*eslint-disable*/ "use strict";
var $protobuf = require("protobufjs/minimal");
// Common aliases
var $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util;
// Exported root namespace
var $root = $protobuf.roots["libp2p-envelope"] || ($protobuf.roots["libp2p-envelope"] = {
});
$root.Envelope = (function() {
    /**
     * Properties of an Envelope.
     * @exports IEnvelope
     * @interface IEnvelope
     * @property {Uint8Array|null} [publicKey] Envelope publicKey
     * @property {Uint8Array|null} [payloadType] Envelope payloadType
     * @property {Uint8Array|null} [payload] Envelope payload
     * @property {Uint8Array|null} [signature] Envelope signature
     */ /**
     * Constructs a new Envelope.
     * @exports Envelope
     * @classdesc Represents an Envelope.
     * @implements IEnvelope
     * @constructor
     * @param {IEnvelope=} [p] Properties to set
     */ function Envelope(p) {
        if (p) {
            for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
        }
    }
    /**
     * Envelope publicKey.
     * @member {Uint8Array} publicKey
     * @memberof Envelope
     * @instance
     */ Envelope.prototype.publicKey = $util.newBuffer([]);
    /**
     * Envelope payloadType.
     * @member {Uint8Array} payloadType
     * @memberof Envelope
     * @instance
     */ Envelope.prototype.payloadType = $util.newBuffer([]);
    /**
     * Envelope payload.
     * @member {Uint8Array} payload
     * @memberof Envelope
     * @instance
     */ Envelope.prototype.payload = $util.newBuffer([]);
    /**
     * Envelope signature.
     * @member {Uint8Array} signature
     * @memberof Envelope
     * @instance
     */ Envelope.prototype.signature = $util.newBuffer([]);
    /**
     * Encodes the specified Envelope message. Does not implicitly {@link Envelope.verify|verify} messages.
     * @function encode
     * @memberof Envelope
     * @static
     * @param {IEnvelope} m Envelope message or plain object to encode
     * @param {$protobuf.Writer} [w] Writer to encode to
     * @returns {$protobuf.Writer} Writer
     */ Envelope.encode = function encode(m, w) {
        if (!w) w = $Writer.create();
        if (m.publicKey != null && Object.hasOwnProperty.call(m, "publicKey")) w.uint32(10).bytes(m.publicKey);
        if (m.payloadType != null && Object.hasOwnProperty.call(m, "payloadType")) w.uint32(18).bytes(m.payloadType);
        if (m.payload != null && Object.hasOwnProperty.call(m, "payload")) w.uint32(26).bytes(m.payload);
        if (m.signature != null && Object.hasOwnProperty.call(m, "signature")) w.uint32(42).bytes(m.signature);
        return w;
    };
    /**
     * Decodes an Envelope message from the specified reader or buffer.
     * @function decode
     * @memberof Envelope
     * @static
     * @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
     * @param {number} [l] Message length if known beforehand
     * @returns {Envelope} Envelope
     * @throws {Error} If the payload is not a reader or valid buffer
     * @throws {$protobuf.util.ProtocolError} If required fields are missing
     */ Envelope.decode = function decode(r, l) {
        if (!(r instanceof $Reader)) r = $Reader.create(r);
        var c = l === undefined ? r.len : r.pos + l, m = new $root.Envelope();
        while(r.pos < c){
            var t = r.uint32();
            switch(t >>> 3){
                case 1:
                    m.publicKey = r.bytes();
                    break;
                case 2:
                    m.payloadType = r.bytes();
                    break;
                case 3:
                    m.payload = r.bytes();
                    break;
                case 5:
                    m.signature = r.bytes();
                    break;
                default:
                    r.skipType(t & 7);
                    break;
            }
        }
        return m;
    };
    /**
     * Creates an Envelope message from a plain object. Also converts values to their respective internal types.
     * @function fromObject
     * @memberof Envelope
     * @static
     * @param {Object.<string,*>} d Plain object
     * @returns {Envelope} Envelope
     */ Envelope.fromObject = function fromObject(d) {
        if (d instanceof $root.Envelope) return d;
        var m = new $root.Envelope();
        if (d.publicKey != null) {
            if (typeof d.publicKey === "string") $util.base64.decode(d.publicKey, m.publicKey = $util.newBuffer($util.base64.length(d.publicKey)), 0);
            else if (d.publicKey.length) m.publicKey = d.publicKey;
        }
        if (d.payloadType != null) {
            if (typeof d.payloadType === "string") $util.base64.decode(d.payloadType, m.payloadType = $util.newBuffer($util.base64.length(d.payloadType)), 0);
            else if (d.payloadType.length) m.payloadType = d.payloadType;
        }
        if (d.payload != null) {
            if (typeof d.payload === "string") $util.base64.decode(d.payload, m.payload = $util.newBuffer($util.base64.length(d.payload)), 0);
            else if (d.payload.length) m.payload = d.payload;
        }
        if (d.signature != null) {
            if (typeof d.signature === "string") $util.base64.decode(d.signature, m.signature = $util.newBuffer($util.base64.length(d.signature)), 0);
            else if (d.signature.length) m.signature = d.signature;
        }
        return m;
    };
    /**
     * Creates a plain object from an Envelope message. Also converts values to other types if specified.
     * @function toObject
     * @memberof Envelope
     * @static
     * @param {Envelope} m Envelope
     * @param {$protobuf.IConversionOptions} [o] Conversion options
     * @returns {Object.<string,*>} Plain object
     */ Envelope.toObject = function toObject(m, o) {
        if (!o) o = {
        };
        var d = {
        };
        if (o.defaults) {
            if (o.bytes === String) d.publicKey = "";
            else {
                d.publicKey = [];
                if (o.bytes !== Array) d.publicKey = $util.newBuffer(d.publicKey);
            }
            if (o.bytes === String) d.payloadType = "";
            else {
                d.payloadType = [];
                if (o.bytes !== Array) d.payloadType = $util.newBuffer(d.payloadType);
            }
            if (o.bytes === String) d.payload = "";
            else {
                d.payload = [];
                if (o.bytes !== Array) d.payload = $util.newBuffer(d.payload);
            }
            if (o.bytes === String) d.signature = "";
            else {
                d.signature = [];
                if (o.bytes !== Array) d.signature = $util.newBuffer(d.signature);
            }
        }
        if (m.publicKey != null && m.hasOwnProperty("publicKey")) d.publicKey = o.bytes === String ? $util.base64.encode(m.publicKey, 0, m.publicKey.length) : o.bytes === Array ? Array.prototype.slice.call(m.publicKey) : m.publicKey;
        if (m.payloadType != null && m.hasOwnProperty("payloadType")) d.payloadType = o.bytes === String ? $util.base64.encode(m.payloadType, 0, m.payloadType.length) : o.bytes === Array ? Array.prototype.slice.call(m.payloadType) : m.payloadType;
        if (m.payload != null && m.hasOwnProperty("payload")) d.payload = o.bytes === String ? $util.base64.encode(m.payload, 0, m.payload.length) : o.bytes === Array ? Array.prototype.slice.call(m.payload) : m.payload;
        if (m.signature != null && m.hasOwnProperty("signature")) d.signature = o.bytes === String ? $util.base64.encode(m.signature, 0, m.signature.length) : o.bytes === Array ? Array.prototype.slice.call(m.signature) : m.signature;
        return d;
    };
    /**
     * Converts this Envelope to JSON.
     * @function toJSON
     * @memberof Envelope
     * @instance
     * @returns {Object.<string,*>} JSON object
     */ Envelope.prototype.toJSON = function toJSON() {
        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
    };
    return Envelope;
})();
module.exports = $root;

},{"protobufjs/minimal":"9Jmso"}],"3cVss":[function(require,module,exports) {
'use strict';
const PeerId = require('peer-id');
const { base58btc  } = require('multiformats/bases/base58');
const { default: PQueue  } = require('p-queue');
const defer = require('p-defer');
const debug = require('debug');
const log = debug('libp2p-delegated-peer-routing');
log.error = debug('libp2p-delegated-peer-routing:error');
const DEFAULT_TIMEOUT = 30000 // 30 second default
;
const CONCURRENT_HTTP_REQUESTS = 4;
class DelegatedPeerRouting {
    /**
   * Create a new DelegatedPeerRouting instance.
   *
   * @param {object} client - an instance of the ipfs-http-client module
   */ constructor(client){
        if (client == null) throw new Error('missing ipfs http client');
        this._client = client;
        // limit concurrency to avoid request flood in web browser
        // https://github.com/libp2p/js-libp2p-delegated-content-routing/issues/12
        this._httpQueue = new PQueue({
            concurrency: CONCURRENT_HTTP_REQUESTS
        });
        const { protocol , host , port  } = client.getEndpointConfig();
        log(`enabled DelegatedPeerRouting via ${protocol}://${host}:${port}`);
    }
    /**
   * Attempts to find the given peer
   *
   * @param {PeerID} id
   * @param {object} options
   * @param {number} options.timeout - How long the query can take. Defaults to 30 seconds
   * @returns {Promise<{ id: PeerId, multiaddrs: Multiaddr[] }>}
   */ async findPeer(id, options = {
    }) {
        let idStr = id;
        if (PeerId.isPeerId(idStr)) idStr = id.toB58String();
        log('findPeer starts: ' + id);
        options.timeout = options.timeout || DEFAULT_TIMEOUT;
        try {
            return await this._httpQueue.add(async ()=>{
                const { addrs  } = await this._client.dht.findPeer(idStr, {
                    timeout: options.timeout
                });
                return {
                    id,
                    multiaddrs: addrs
                };
            });
        } catch (err) {
            if (err.message.includes('not found')) return undefined;
            throw err;
        } finally{
            log('findPeer finished: ' + id);
        }
    }
    /**
   * Attempt to find the closest peers on the network to the given key
   *
   * @param {Uint8Array} key - A CID like key
   * @param {object} [options]
   * @param {number} [options.timeout=30e3] - How long the query can take.
   * @returns {AsyncIterable<{ id: PeerId, multiaddrs: Multiaddr[] }>}
   */ async *getClosestPeers(key, options1 = {
    }) {
        const keyStr = base58btc.encode(key).substring(1);
        log('getClosestPeers starts:', keyStr);
        options1.timeout = options1.timeout || DEFAULT_TIMEOUT;
        const onStart = defer();
        const onFinish = defer();
        this._httpQueue.add(()=>{
            onStart.resolve();
            return onFinish.promise;
        });
        try {
            await onStart.promise;
            const peers = new Map();
            for await (const result of this._client.dht.query(keyStr, {
                timeout: options1.timeout
            }))switch(result.type){
                case 1:
                    // Track the addresses, so we can yield them when done
                    result.responses.forEach((response)=>{
                        peers.set(response.id, {
                            id: PeerId.parse(response.id),
                            multiaddrs: response.addrs
                        });
                    });
                    break;
                case 2:
                    yield peers.get(result.id.string) || {
                        id: PeerId.createFromCID(result.id),
                        multiaddrs: []
                    };
                    break;
                default:
                    log('getClosestPeers unhandled response', result);
            }
        } catch (err) {
            log.error('getClosestPeers errored:', err);
            throw err;
        } finally{
            onFinish.resolve();
            log('getClosestPeers finished:', keyStr);
        }
    }
}
module.exports = DelegatedPeerRouting;

},{"peer-id":"4VGWt","multiformats/bases/base58":"6Rnqi","p-queue":"ccCVf","p-defer":"gZqcC","debug":"lWlU4"}],"4OlJb":[function(require,module,exports) {
'use strict';
const debug = require('debug');
const PeerId = require('peer-id');
const drain = require('it-drain');
const { default: PQueue  } = require('p-queue');
const defer = require('p-defer');
const log = debug('libp2p-delegated-content-routing');
log.error = debug('libp2p-delegated-content-routing:error');
const DEFAULT_TIMEOUT = 30000 // 30 second default
;
const CONCURRENT_HTTP_REQUESTS = 4;
/**
 * @typedef {import('peer-id').PeerID} PeerID
 * @typedef {import('cids').CID} CID
 * @typedef {import('multiaddr').Multiaddr} Multiaddr
 */ /**
 * An implementation of content routing, using a delegated peer.
 */ class DelegatedContentRouting {
    /**
   * Create a new DelegatedContentRouting instance.
   *
   * @param {PeerID} peerId - the id of the node that is using this routing.
   * @param {object} client - an instance of the ipfs-http-client module
   */ constructor(peerId, client){
        if (peerId == null) throw new Error('missing self peerId');
        if (client == null) throw new Error('missing ipfs http client');
        this._client = client;
        this.peerId = peerId;
        // limit concurrency to avoid request flood in web browser
        // https://github.com/libp2p/js-libp2p-delegated-content-routing/issues/12
        const concurrency = {
            concurrency: CONCURRENT_HTTP_REQUESTS
        };
        this._httpQueue = new PQueue(concurrency);
        // sometimes refs requests take long time, they need separate queue
        // to not suffocate regular business
        this._httpQueueRefs = new PQueue(Object.assign({
        }, concurrency, {
            concurrency: 2
        }));
        const { protocol , host , port  } = client.getEndpointConfig();
        log(`enabled DelegatedContentRouting via ${protocol}://${host}:${port}`);
    }
    /**
   * Search the dht for providers of the given CID.
   *
   * - call `findProviders` on the delegated node.
   *
   * @param {CID} key - The CID to find providers for
   * @param {object} options - Options
   * @param {number} options.timeout - How long the query can take. Defaults to 30 seconds
   * @param {number} options.numProviders - How many providers to find, defaults to 20
   * @returns {AsyncIterable<{ id: PeerId, multiaddrs: Multiaddr[] }>} - An async iterable of PeerId/Multiaddrs
   */ async *findProviders(key, options = {
    }) {
        log(`findProviders starts: ${key}`);
        options.timeout = options.timeout || DEFAULT_TIMEOUT;
        let providers = 0;
        const onStart = defer();
        const onFinish = defer();
        this._httpQueue.add(()=>{
            onStart.resolve();
            return onFinish.promise;
        });
        try {
            await onStart.promise;
            for await (const { id , addrs  } of this._client.dht.findProvs(key, {
                numProviders: options.numProviders,
                timeout: options.timeout
            })){
                yield {
                    id: PeerId.parse(id),
                    multiaddrs: addrs
                };
                providers++;
            }
        } catch (err) {
            log.error('findProviders errored:', err);
            throw err;
        } finally{
            onFinish.resolve();
            log(`findProviders finished: ${key} found ${providers} providers`);
        }
    }
    /**
   * Announce to the network that the delegated node can provide the given key.
   *
   * Currently this uses the following hack
   * - delegate is one of bootstrap nodes, so we are always connected to it
   * - call block stat on the delegated node, so it fetches the content
   * - call dht provide with the passed cid
   *
   * N.B. this must be called for every block in the dag you want provided otherwise
   * the delegate will only be able to supply the root block of the dag when asked
   * for the data by an interested peer.
   *
   * @param {CID} key - The delegate will publish a provider record for this CID
   * @returns {Promise<void>}
   */ async provide(key1) {
        log(`provide starts: ${key1}`);
        await this._httpQueueRefs.add(async ()=>{
            await this._client.block.stat(key1);
            await drain(this._client.dht.provide(key1));
        });
        log(`provide finished: ${key1}`);
    }
}
module.exports = DelegatedContentRouting;

},{"debug":"lWlU4","peer-id":"4VGWt","it-drain":"h63K2","p-queue":"ccCVf","p-defer":"gZqcC"}],"7FTpC":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var multibases = require('ipfs-core-utils/multibases');
var multicodecs = require('ipfs-core-utils/multicodecs');
var multihashes = require('ipfs-core-utils/multihashes');
var dagPB = require('@ipld/dag-pb');
var dagCBOR = require('@ipld/dag-cbor');
var identity = require('multiformats/hashes/identity');
var basics = require('multiformats/basics');
var index = require('./bitswap/index.js');
var index$1 = require('./block/index.js');
var index$2 = require('./bootstrap/index.js');
var index$3 = require('./config/index.js');
var index$4 = require('./dag/index.js');
var index$5 = require('./dht/index.js');
var index$6 = require('./diag/index.js');
var index$7 = require('./files/index.js');
var index$8 = require('./key/index.js');
var index$9 = require('./log/index.js');
var index$a = require('./name/index.js');
var index$b = require('./object/index.js');
var index$c = require('./pin/index.js');
var index$d = require('./pubsub/index.js');
var index$e = require('./refs/index.js');
var index$f = require('./repo/index.js');
var index$g = require('./stats/index.js');
var index$h = require('./swarm/index.js');
var add = require('./add.js');
var addAll = require('./add-all.js');
var cat = require('./cat.js');
var commands = require('./commands.js');
var dns = require('./dns.js');
var getEndpointConfig = require('./get-endpoint-config.js');
var get = require('./get.js');
var id1 = require('./id.js');
var isOnline = require('./is-online.js');
var ls = require('./ls.js');
var mount = require('./mount.js');
var ping = require('./ping.js');
var resolve = require('./resolve.js');
var start = require('./start.js');
var stop = require('./stop.js');
var version = require('./version.js');
var globSourceImport = require('ipfs-utils/src/files/glob-source.js');
var cid = require('multiformats/cid');
var multiaddr = require('multiaddr');
var urlSource_js = require('ipfs-utils/src/files/url-source.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n['default'] = e;
    return Object.freeze(n);
}
var dagPB__namespace = /*#__PURE__*/ _interopNamespace(dagPB);
var dagCBOR__namespace = /*#__PURE__*/ _interopNamespace(dagCBOR);
var globSourceImport__default = /*#__PURE__*/ _interopDefaultLegacy(globSourceImport);
var urlSource_js__default = /*#__PURE__*/ _interopDefaultLegacy(urlSource_js);
function create(options = {
}) {
    const id$1 = {
        name: identity.identity.name,
        code: identity.identity.code,
        encode: (id)=>id
        ,
        decode: (id)=>id
    };
    const multibaseCodecs = Object.values(basics.bases);
    (options.ipld && options.ipld.bases ? options.ipld.bases : []).forEach((base)=>multibaseCodecs.push(base)
    );
    const multibases$1 = new multibases.Multibases({
        bases: multibaseCodecs,
        loadBase: options.ipld && options.ipld.loadBase
    });
    const blockCodecs = Object.values(basics.codecs);
    [
        dagPB__namespace,
        dagCBOR__namespace,
        id$1
    ].concat(options.ipld && options.ipld.codecs || []).forEach((codec)=>blockCodecs.push(codec)
    );
    const multicodecs$1 = new multicodecs.Multicodecs({
        codecs: blockCodecs,
        loadCodec: options.ipld && options.ipld.loadCodec
    });
    const multihashHashers = Object.values(basics.hashes);
    (options.ipld && options.ipld.hashers ? options.ipld.hashers : []).forEach((hasher)=>multihashHashers.push(hasher)
    );
    const multihashes$1 = new multihashes.Multihashes({
        hashers: multihashHashers,
        loadHasher: options.ipld && options.ipld.loadHasher
    });
    const client = {
        add: add.createAdd(options),
        addAll: addAll.createAddAll(options),
        bitswap: index.createBitswap(options),
        block: index$1.createBlock(options),
        bootstrap: index$2.createBootstrap(options),
        cat: cat.createCat(options),
        commands: commands.createCommands(options),
        config: index$3.createConfig(options),
        dag: index$4.createDag(multicodecs$1, options),
        dht: index$5.createDht(options),
        diag: index$6.createDiag(options),
        dns: dns.createDns(options),
        files: index$7.createFiles(options),
        get: get.createGet(options),
        getEndpointConfig: getEndpointConfig.createGetEndpointConfig(options),
        id: id1.createId(options),
        isOnline: isOnline.createIsOnline(options),
        key: index$8.createKey(options),
        log: index$9.createLog(options),
        ls: ls.createLs(options),
        mount: mount.createMount(options),
        name: index$a.createName(options),
        object: index$b.createObject(multicodecs$1, options),
        pin: index$c.createPin(options),
        ping: ping.createPing(options),
        pubsub: index$d.createPubsub(options),
        refs: index$e.createRefs(options),
        repo: index$f.createRepo(options),
        resolve: resolve.createResolve(options),
        start: start.createStart(options),
        stats: index$g.createStats(options),
        stop: stop.createStop(options),
        swarm: index$h.createSwarm(options),
        version: version.createVersion(options),
        bases: multibases$1,
        codecs: multicodecs$1,
        hashers: multihashes$1
    };
    return client;
}
const globSource = globSourceImport__default['default'];
Object.defineProperty(exports, 'CID', {
    enumerable: true,
    get: function() {
        return cid.CID;
    }
});
Object.defineProperty(exports, 'multiaddr', {
    enumerable: true,
    get: function() {
        return multiaddr.Multiaddr;
    }
});
Object.defineProperty(exports, 'urlSource', {
    enumerable: true,
    get: function() {
        return urlSource_js__default['default'];
    }
});
exports.create = create;
exports.globSource = globSource;

},{"ipfs-core-utils/multibases":"a70gY","ipfs-core-utils/multicodecs":"hQFTl","ipfs-core-utils/multihashes":"9DlWG","@ipld/dag-pb":"e9gy2","@ipld/dag-cbor":"kSG7F","multiformats/hashes/identity":"7Cndu","multiformats/basics":"7w1HC","./bitswap/index.js":"8p50g","./block/index.js":"jy624","./bootstrap/index.js":"kv6eA","./config/index.js":"5zLry","./dag/index.js":"Q9mME","./dht/index.js":"aMbu1","./diag/index.js":"6Vojk","./files/index.js":"dk7I1","./key/index.js":"hw9f3","./log/index.js":"7Oym0","./name/index.js":"jUURl","./object/index.js":"gAOao","./pin/index.js":"dZ3F1","./pubsub/index.js":"cx44X","./refs/index.js":"5AJ5a","./repo/index.js":"iTArq","./stats/index.js":"jNimi","./swarm/index.js":"lvOze","./add.js":"gSIKT","./add-all.js":"6uXPs","./cat.js":"h2iQz","./commands.js":"1Y0eG","./dns.js":"aEE8e","./get-endpoint-config.js":"4iqJl","./get.js":"2d7NW","./id.js":"4v7TH","./is-online.js":"ilvG8","./ls.js":"hOWyo","./mount.js":"eeUuW","./ping.js":"93a94","./resolve.js":"kN9C4","./start.js":"9OnII","./stop.js":"cBDOX","./version.js":"9pYnJ","ipfs-utils/src/files/glob-source.js":"joWnX","multiformats/cid":"fJJnW","multiaddr":"kOPrF","ipfs-utils/src/files/url-source.js":"hdaYP"}],"a70gY":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
const LOAD_BASE = (name)=>Promise.reject(new Error(`No base found for "${name}"`))
;
class Multibases {
    constructor(options){
        this._basesByName = {
        };
        this._basesByPrefix = {
        };
        this._loadBase = options.loadBase || LOAD_BASE;
        for (const base of options.bases)this.addBase(base);
    }
    addBase(base) {
        if (this._basesByName[base.name] || this._basesByPrefix[base.prefix]) throw new Error(`Codec already exists for codec "${base.name}"`);
        this._basesByName[base.name] = base;
        this._basesByPrefix[base.prefix] = base;
    }
    removeBase(base1) {
        delete this._basesByName[base1.name];
        delete this._basesByPrefix[base1.prefix];
    }
    async getBase(nameOrPrefix) {
        if (this._basesByName[nameOrPrefix]) return this._basesByName[nameOrPrefix];
        if (this._basesByPrefix[nameOrPrefix]) return this._basesByPrefix[nameOrPrefix];
        const base = await this._loadBase(nameOrPrefix);
        if (this._basesByName[base.name] == null && this._basesByPrefix[base.prefix] == null) this.addBase(base);
        return base;
    }
    listBases() {
        return Object.values(this._basesByName);
    }
}
exports.Multibases = Multibases;

},{}],"hQFTl":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
const LOAD_CODEC = (codeOrName)=>Promise.reject(new Error(`No codec found for "${codeOrName}"`))
;
class Multicodecs {
    constructor(options){
        this._codecsByName = {
        };
        this._codecsByCode = {
        };
        this._loadCodec = options.loadCodec || LOAD_CODEC;
        for (const codec of options.codecs)this.addCodec(codec);
    }
    addCodec(codec) {
        if (this._codecsByName[codec.name] || this._codecsByCode[codec.code]) throw new Error(`Resolver already exists for codec "${codec.name}"`);
        this._codecsByName[codec.name] = codec;
        this._codecsByCode[codec.code] = codec;
    }
    removeCodec(codec1) {
        delete this._codecsByName[codec1.name];
        delete this._codecsByCode[codec1.code];
    }
    async getCodec(code) {
        const table = typeof code === 'string' ? this._codecsByName : this._codecsByCode;
        if (table[code]) return table[code];
        const codec = await this._loadCodec(code);
        if (table[code] == null) this.addCodec(codec);
        return codec;
    }
    listCodecs() {
        return Object.values(this._codecsByName);
    }
}
exports.Multicodecs = Multicodecs;

},{}],"9DlWG":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
const LOAD_HASHER = (codeOrName)=>Promise.reject(new Error(`No hasher found for "${codeOrName}"`))
;
class Multihashes {
    constructor(options){
        this._hashersByName = {
        };
        this._hashersByCode = {
        };
        this._loadHasher = options.loadHasher || LOAD_HASHER;
        for (const hasher of options.hashers)this.addHasher(hasher);
    }
    addHasher(hasher) {
        if (this._hashersByName[hasher.name] || this._hashersByCode[hasher.code]) throw new Error(`Resolver already exists for codec "${hasher.name}"`);
        this._hashersByName[hasher.name] = hasher;
        this._hashersByCode[hasher.code] = hasher;
    }
    removeHasher(hasher1) {
        delete this._hashersByName[hasher1.name];
        delete this._hashersByCode[hasher1.code];
    }
    async getHasher(code) {
        const table = typeof code === 'string' ? this._hashersByName : this._hashersByCode;
        if (table[code]) return table[code];
        const hasher = await this._loadHasher(code);
        if (table[code] == null) this.addHasher(hasher);
        return hasher;
    }
    listHashers() {
        return Object.values(this._hashersByName);
    }
}
exports.Multihashes = Multihashes;

},{}],"8p50g":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var wantlist = require('./wantlist.js');
var wantlistForPeer = require('./wantlist-for-peer.js');
var stat = require('./stat.js');
var unwant = require('./unwant.js');
function createBitswap(config) {
    return {
        wantlist: wantlist.createWantlist(config),
        wantlistForPeer: wantlistForPeer.createWantlistForPeer(config),
        unwant: unwant.createUnwant(config),
        stat: stat.createStat(config)
    };
}
exports.createBitswap = createBitswap;

},{"./wantlist.js":"1zaTt","./wantlist-for-peer.js":"kSldL","./stat.js":"jutRZ","./unwant.js":"3teSE"}],"1zaTt":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createWantlist = configure.configure((api)=>{
    async function wantlist(options = {
    }) {
        const res = await (await api.post('bitswap/wantlist', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams(options),
            headers: options.headers
        })).json();
        return (res.Keys || []).map((k)=>cid.CID.parse(k['/'])
        );
    }
    return wantlist;
});
exports.createWantlist = createWantlist;

},{"multiformats/cid":"fJJnW","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"eVYJh":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var core = require('./core.js');
const configure = (fn)=>{
    return (options)=>{
        return fn(new core.Client(options), options);
    };
};
exports.configure = configure;

},{"./core.js":"g5LBC"}],"g5LBC":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var multiaddr = require('multiaddr');
var env_js = require('ipfs-utils/src/env.js');
var parseDuration = require('parse-duration');
var debug = require('debug');
var HTTP = require('ipfs-utils/src/http.js');
var mergeOpts = require('merge-options');
var toUrlString = require('ipfs-core-utils/to-url-string');
var getAgent = require('ipfs-core-utils/agent');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var parseDuration__default = /*#__PURE__*/ _interopDefaultLegacy(parseDuration);
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
var HTTP__default = /*#__PURE__*/ _interopDefaultLegacy(HTTP);
var mergeOpts__default = /*#__PURE__*/ _interopDefaultLegacy(mergeOpts);
var getAgent__default = /*#__PURE__*/ _interopDefaultLegacy(getAgent);
const log = debug__default['default']('ipfs-http-client:lib:error-handler');
const merge = mergeOpts__default['default'].bind({
    ignoreUndefined: true
});
const DEFAULT_PROTOCOL = env_js.isBrowser || env_js.isWebWorker ? location.protocol : 'http';
const DEFAULT_HOST = env_js.isBrowser || env_js.isWebWorker ? location.hostname : 'localhost';
const DEFAULT_PORT = env_js.isBrowser || env_js.isWebWorker ? location.port : '5001';
const normalizeOptions = (options = {
})=>{
    let url;
    let opts = {
    };
    let agent;
    if (typeof options === 'string' || multiaddr.Multiaddr.isMultiaddr(options)) url = new URL(toUrlString.toUrlString(options));
    else if (options instanceof URL) url = options;
    else if (typeof options.url === 'string' || multiaddr.Multiaddr.isMultiaddr(options.url)) {
        url = new URL(toUrlString.toUrlString(options.url));
        opts = options;
    } else if (options.url instanceof URL) {
        url = options.url;
        opts = options;
    } else {
        opts = options || {
        };
        const protocol = (opts.protocol || DEFAULT_PROTOCOL).replace(':', '');
        const host = (opts.host || DEFAULT_HOST).split(':')[0];
        const port = opts.port || DEFAULT_PORT;
        url = new URL(`${protocol}://${host}:${port}`);
    }
    if (opts.apiPath) url.pathname = opts.apiPath;
    else if (url.pathname === '/' || url.pathname === undefined) url.pathname = 'api/v0';
    if (env_js.isNode) {
        const Agent = getAgent__default['default'](url);
        agent = opts.agent || new Agent({
            keepAlive: true,
            maxSockets: 6
        });
    }
    return {
        ...opts,
        host: url.host,
        protocol: url.protocol.replace(':', ''),
        port: Number(url.port),
        apiPath: url.pathname,
        url,
        agent
    };
};
const errorHandler = async (response)=>{
    let msg;
    try {
        if ((response.headers.get('Content-Type') || '').startsWith('application/json')) {
            const data = await response.json();
            log(data);
            msg = data.Message || data.message;
        } else msg = await response.text();
    } catch (err) {
        log('Failed to parse error response', err);
        msg = err.message;
    }
    let error = new HTTP__default['default'].HTTPError(response);
    if (msg) {
        if (msg.includes('deadline has elapsed')) error = new HTTP__default['default'].TimeoutError();
        if (msg && msg.includes('context deadline exceeded')) error = new HTTP__default['default'].TimeoutError();
    }
    if (msg && msg.includes('request timed out')) error = new HTTP__default['default'].TimeoutError();
    if (msg) error.message = msg;
    throw error;
};
const KEBAB_REGEX = /[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g;
const kebabCase = (str)=>{
    return str.replace(KEBAB_REGEX, function(match) {
        return '-' + match.toLowerCase();
    });
};
const parseTimeout = (value)=>{
    return typeof value === 'string' ? parseDuration__default['default'](value) : value;
};
class Client extends HTTP__default['default'] {
    constructor(options1 = {
    }){
        const opts = normalizeOptions(options1);
        super({
            timeout: parseTimeout(opts.timeout || 0) || undefined,
            headers: opts.headers,
            base: `${opts.url}`,
            handleError: errorHandler,
            transformSearchParams: (search)=>{
                const out = new URLSearchParams();
                for (const [key, value] of search){
                    if (value !== 'undefined' && value !== 'null' && key !== 'signal') out.append(kebabCase(key), value);
                    if (key === 'timeout' && !isNaN(value)) out.append(kebabCase(key), value);
                }
                return out;
            },
            agent: opts.agent
        });
        delete this.get;
        delete this.put;
        delete this.delete;
        delete this.options;
        const fetch = this.fetch;
        this.fetch = (resource, options = {
        })=>{
            if (typeof resource === 'string' && !resource.startsWith('/')) resource = `${opts.url}/${resource}`;
            return fetch.call(this, resource, merge(options, {
                method: 'POST'
            }));
        };
    }
}
const HTTPError = HTTP__default['default'].HTTPError;
exports.Client = Client;
exports.HTTPError = HTTPError;
exports.errorHandler = errorHandler;

},{"multiaddr":"kOPrF","ipfs-utils/src/env.js":"42nOp","parse-duration":"2Fbu7","debug":"lWlU4","ipfs-utils/src/http.js":"2w2r7","merge-options":"8VjFj","ipfs-core-utils/to-url-string":"e2Krm","ipfs-core-utils/agent":"cv5ud"}],"e2Krm":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var multiaddr = require('multiaddr');
var multiAddrToUri = require('multiaddr-to-uri');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var multiAddrToUri__default = /*#__PURE__*/ _interopDefaultLegacy(multiAddrToUri);
function toUrlString(url) {
    try {
        url = multiAddrToUri__default['default'](new multiaddr.Multiaddr(url));
    } catch (err) {
    }
    url = url.toString();
    return url;
}
exports.toUrlString = toUrlString;

},{"multiaddr":"kOPrF","multiaddr-to-uri":"94qb6"}],"cv5ud":[function(require,module,exports) {
'use strict';
var agent_browser = ()=>{
};
module.exports = agent_browser;

},{}],"5cN7U":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var modeToString = require('./mode-to-string.js');
var parseMtime = require('./parse-mtime.js');
function toUrlSearchParams({ arg: arg1 , searchParams , hashAlg , mtime , mode , ...options } = {
}) {
    if (searchParams) options = {
        ...options,
        ...searchParams
    };
    if (hashAlg) options.hash = hashAlg;
    if (mtime != null) {
        mtime = parseMtime.parseMtime(mtime);
        options.mtime = mtime.secs;
        options.mtimeNsecs = mtime.nsecs;
    }
    if (mode != null) options.mode = modeToString.modeToString(mode);
    if (options.timeout && !isNaN(options.timeout)) options.timeout = `${options.timeout}ms`;
    if (arg1 === undefined || arg1 === null) arg1 = [];
    else if (!Array.isArray(arg1)) arg1 = [
        arg1
    ];
    const urlSearchParams = new URLSearchParams(options);
    arg1.forEach((arg)=>urlSearchParams.append('arg', arg)
    );
    return urlSearchParams;
}
exports.toUrlSearchParams = toUrlSearchParams;

},{"./mode-to-string.js":"cpT7L","./parse-mtime.js":"529iQ"}],"cpT7L":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
function modeToString(mode) {
    if (mode == null) return undefined;
    if (typeof mode === 'string') return mode;
    return mode.toString(8).padStart(4, '0');
}
exports.modeToString = modeToString;

},{}],"529iQ":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var errCode = require('err-code');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
function parseMtime(input) {
    if (input == null) return undefined;
    let mtime;
    if (input.secs != null) mtime = {
        secs: input.secs,
        nsecs: input.nsecs
    };
    if (input.Seconds != null) mtime = {
        secs: input.Seconds,
        nsecs: input.FractionalNanoseconds
    };
    if (Array.isArray(input)) mtime = {
        secs: input[0],
        nsecs: input[1]
    };
    if (input instanceof Date) {
        const ms = input.getTime();
        const secs = Math.floor(ms / 1000);
        mtime = {
            secs: secs,
            nsecs: (ms - secs * 1000) * 1000
        };
    }
    if (!Object.prototype.hasOwnProperty.call(mtime, 'secs')) return undefined;
    if (mtime != null && mtime.nsecs != null && (mtime.nsecs < 0 || mtime.nsecs > 999999999)) throw errCode__default['default'](new Error('mtime-nsecs must be within the range [0,999999999]'), 'ERR_INVALID_MTIME_NSECS');
    return mtime;
}
exports.parseMtime = parseMtime;

},{"err-code":"eQvyh"}],"kSldL":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createWantlistForPeer = configure.configure((api)=>{
    async function wantlistForPeer(peerId, options = {
    }) {
        const res = await (await api.post('bitswap/wantlist', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                ...options,
                peer: peerId.toString()
            }),
            headers: options.headers
        })).json();
        return (res.Keys || []).map((k)=>cid.CID.parse(k['/'])
        );
    }
    return wantlistForPeer;
});
exports.createWantlistForPeer = createWantlistForPeer;

},{"multiformats/cid":"fJJnW","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"jutRZ":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createStat = configure.configure((api)=>{
    async function stat(options = {
    }) {
        const res = await api.post('bitswap/stat', {
            searchParams: toUrlSearchParams.toUrlSearchParams(options),
            signal: options.signal,
            headers: options.headers
        });
        return toCoreInterface(await res.json());
    }
    return stat;
});
function toCoreInterface(res) {
    return {
        provideBufLen: res.ProvideBufLen,
        wantlist: (res.Wantlist || []).map((k)=>cid.CID.parse(k['/'])
        ),
        peers: res.Peers || [],
        blocksReceived: BigInt(res.BlocksReceived),
        dataReceived: BigInt(res.DataReceived),
        blocksSent: BigInt(res.BlocksSent),
        dataSent: BigInt(res.DataSent),
        dupBlksReceived: BigInt(res.DupBlksReceived),
        dupDataReceived: BigInt(res.DupDataReceived)
    };
}
exports.createStat = createStat;

},{"multiformats/cid":"fJJnW","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"3teSE":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createUnwant = configure.configure((api)=>{
    async function unwant(cid, options = {
    }) {
        const res = await api.post('bitswap/unwant', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: cid.toString(),
                ...options
            }),
            headers: options.headers
        });
        return res.json();
    }
    return unwant;
});
exports.createUnwant = createUnwant;

},{"../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"jy624":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var get = require('./get.js');
var put = require('./put.js');
var rm = require('./rm.js');
var stat = require('./stat.js');
function createBlock(config) {
    return {
        get: get.createGet(config),
        put: put.createPut(config),
        rm: rm.createRm(config),
        stat: stat.createStat(config)
    };
}
exports.createBlock = createBlock;

},{"./get.js":"iARwf","./put.js":"66OYg","./rm.js":"1Zgkl","./stat.js":"cOGBc"}],"iARwf":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createGet = configure.configure((api)=>{
    async function get(cid, options = {
    }) {
        const res = await api.post('block/get', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: cid.toString(),
                ...options
            }),
            headers: options.headers
        });
        return new Uint8Array(await res.arrayBuffer());
    }
    return get;
});
exports.createGet = createGet;

},{"../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"66OYg":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
var multipartRequest = require('ipfs-core-utils/multipart-request');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
var abortSignal = require('../lib/abort-signal.js');
var nativeAbortController = require('native-abort-controller');
const createPut = configure.configure((api)=>{
    async function put(data, options = {
    }) {
        const controller = new nativeAbortController.AbortController();
        const signal = abortSignal.abortSignal(controller.signal, options.signal);
        let res;
        try {
            const response = await api.post('block/put', {
                signal: signal,
                searchParams: toUrlSearchParams.toUrlSearchParams(options),
                ...await multipartRequest.multipartRequest(data, controller, options.headers)
            });
            res = await response.json();
        } catch (err) {
            if (options.format === 'dag-pb') return put(data, {
                ...options,
                format: 'protobuf'
            });
            else if (options.format === 'dag-cbor') return put(data, {
                ...options,
                format: 'cbor'
            });
            throw err;
        }
        return cid.CID.parse(res.Key);
    }
    return put;
});
exports.createPut = createPut;

},{"multiformats/cid":"fJJnW","ipfs-core-utils/multipart-request":"byZwt","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U","../lib/abort-signal.js":"eZ7xd","native-abort-controller":"9z1Uk"}],"byZwt":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var normaliseInput_browser = require('./files/normalise-input.browser.js');
var modeToString = require('./mode-to-string.js');
async function multipartRequest(source, abortController, headers = {
}) {
    const parts = [];
    const formData = new FormData();
    let index = 0;
    let total = 0;
    for await (const { content , path , mode , mtime  } of normaliseInput_browser.normaliseInput(source)){
        let fileSuffix = '';
        const type = content ? 'file' : 'dir';
        if (index > 0) fileSuffix = `-${index}`;
        let fieldName = type + fileSuffix;
        const qs = [];
        if (mode !== null && mode !== undefined) qs.push(`mode=${modeToString.modeToString(mode)}`);
        if (mtime != null) {
            const { secs , nsecs  } = mtime;
            qs.push(`mtime=${secs}`);
            if (nsecs != null) qs.push(`mtime-nsecs=${nsecs}`);
        }
        if (qs.length) fieldName = `${fieldName}?${qs.join('&')}`;
        if (content) {
            formData.set(fieldName, content, path != null ? encodeURIComponent(path) : undefined);
            const end = total + content.size;
            parts.push({
                name: path,
                start: total,
                end
            });
            total = end;
        } else if (path != null) formData.set(fieldName, new File([
            ''
        ], encodeURIComponent(path), {
            type: 'application/x-directory'
        }));
        else throw new Error('path or content or both must be set');
        index++;
    }
    return {
        total,
        parts,
        headers,
        body: formData
    };
}
exports.multipartRequest = multipartRequest;

},{"./files/normalise-input.browser.js":"30RcX","./mode-to-string.js":"ir3Vw"}],"30RcX":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var normaliseContent_browser = require('./normalise-content.browser.js');
var normalise = require('./normalise.js');
function normaliseInput(input) {
    return normalise.normalise(input, normaliseContent_browser.normaliseContent);
}
exports.normaliseInput = normaliseInput;

},{"./normalise-content.browser.js":"gbq7i","./normalise.js":"1enfJ"}],"gbq7i":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var errCode = require('err-code');
var itPeekable = require('it-peekable');
var browserStreamToIt = require('browser-readablestream-to-it');
var all = require('it-all');
var utils = require('./utils.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
var itPeekable__default = /*#__PURE__*/ _interopDefaultLegacy(itPeekable);
var browserStreamToIt__default = /*#__PURE__*/ _interopDefaultLegacy(browserStreamToIt);
var all__default = /*#__PURE__*/ _interopDefaultLegacy(all);
async function normaliseContent(input) {
    if (utils.isBytes(input)) return new Blob([
        input
    ]);
    if (typeof input === 'string' || input instanceof String) return new Blob([
        input.toString()
    ]);
    if (utils.isBlob(input)) return input;
    if (utils.isReadableStream(input)) input = browserStreamToIt__default['default'](input);
    if (Symbol.iterator in input || Symbol.asyncIterator in input) {
        const peekable = itPeekable__default['default'](input);
        const { value , done  } = await peekable.peek();
        if (done) return itToBlob(peekable);
        peekable.push(value);
        if (Number.isInteger(value)) return new Blob([
            Uint8Array.from(await all__default['default'](peekable))
        ]);
        if (utils.isBytes(value) || typeof value === 'string' || value instanceof String) return itToBlob(peekable);
    }
    throw errCode__default['default'](new Error(`Unexpected input: ${input}`), 'ERR_UNEXPECTED_INPUT');
}
async function itToBlob(stream) {
    const parts = [];
    for await (const chunk of stream)parts.push(chunk);
    return new Blob(parts);
}
exports.normaliseContent = normaliseContent;

},{"err-code":"eQvyh","it-peekable":"kGyHM","browser-readablestream-to-it":"86Z8e","it-all":"hynpN","./utils.js":"c7UnV"}],"ir3Vw":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
function modeToString(mode) {
    if (mode == null) return undefined;
    if (typeof mode === 'string') return mode;
    return mode.toString(8).padStart(4, '0');
}
exports.modeToString = modeToString;

},{}],"eZ7xd":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var anySignal = require('any-signal');
function filter(signals) {
    return signals.filter(Boolean);
}
function abortSignal(...signals) {
    return anySignal.anySignal(filter(signals));
}
exports.abortSignal = abortSignal;

},{"any-signal":"1586s"}],"1Zgkl":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid1 = require('multiformats/cid');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createRm = configure.configure((api)=>{
    async function* rm(cid2, options = {
    }) {
        if (!Array.isArray(cid2)) cid2 = [
            cid2
        ];
        const res = await api.post('block/rm', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: cid2.map((cid)=>cid.toString()
                ),
                'stream-channels': true,
                ...options
            }),
            headers: options.headers
        });
        for await (const removed of res.ndjson())yield toCoreInterface(removed);
    }
    return rm;
});
function toCoreInterface(removed) {
    const out = {
        cid: cid1.CID.parse(removed.Hash)
    };
    if (removed.Error) out.error = new Error(removed.Error);
    return out;
}
exports.createRm = createRm;

},{"multiformats/cid":"fJJnW","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"cOGBc":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createStat = configure.configure((api)=>{
    async function stat(cid$1, options = {
    }) {
        const res = await api.post('block/stat', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: cid$1.toString(),
                ...options
            }),
            headers: options.headers
        });
        const data = await res.json();
        return {
            cid: cid.CID.parse(data.Key),
            size: data.Size
        };
    }
    return stat;
});
exports.createStat = createStat;

},{"multiformats/cid":"fJJnW","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"kv6eA":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var add = require('./add.js');
var clear = require('./clear.js');
var list = require('./list.js');
var reset = require('./reset.js');
var rm = require('./rm.js');
function createBootstrap(config) {
    return {
        add: add.createAdd(config),
        clear: clear.createClear(config),
        list: list.createList(config),
        reset: reset.createReset(config),
        rm: rm.createRm(config)
    };
}
exports.createBootstrap = createBootstrap;

},{"./add.js":"6sknJ","./clear.js":"hOUJa","./list.js":"1Xof9","./reset.js":"7vGMb","./rm.js":"knOeE"}],"6sknJ":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
var multiaddr = require('multiaddr');
const createAdd = configure.configure((api)=>{
    async function add(addr, options = {
    }) {
        const res = await api.post('bootstrap/add', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: addr,
                ...options
            }),
            headers: options.headers
        });
        const { Peers  } = await res.json();
        return {
            Peers: Peers.map((ma)=>new multiaddr.Multiaddr(ma)
            )
        };
    }
    return add;
});
exports.createAdd = createAdd;

},{"../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U","multiaddr":"kOPrF"}],"hOUJa":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
var multiaddr = require('multiaddr');
const createClear = configure.configure((api)=>{
    async function clear(options = {
    }) {
        const res = await api.post('bootstrap/rm', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                ...options,
                all: true
            }),
            headers: options.headers
        });
        const { Peers  } = await res.json();
        return {
            Peers: Peers.map((ma)=>new multiaddr.Multiaddr(ma)
            )
        };
    }
    return clear;
});
exports.createClear = createClear;

},{"../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U","multiaddr":"kOPrF"}],"1Xof9":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
var multiaddr = require('multiaddr');
const createList = configure.configure((api)=>{
    async function list(options = {
    }) {
        const res = await api.post('bootstrap/list', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams(options),
            headers: options.headers
        });
        const { Peers  } = await res.json();
        return {
            Peers: Peers.map((ma)=>new multiaddr.Multiaddr(ma)
            )
        };
    }
    return list;
});
exports.createList = createList;

},{"../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U","multiaddr":"kOPrF"}],"7vGMb":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
var multiaddr = require('multiaddr');
const createReset = configure.configure((api)=>{
    async function reset(options = {
    }) {
        const res = await api.post('bootstrap/add', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                ...options,
                default: true
            }),
            headers: options.headers
        });
        const { Peers  } = await res.json();
        return {
            Peers: Peers.map((ma)=>new multiaddr.Multiaddr(ma)
            )
        };
    }
    return reset;
});
exports.createReset = createReset;

},{"../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U","multiaddr":"kOPrF"}],"knOeE":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
var multiaddr = require('multiaddr');
const createRm = configure.configure((api)=>{
    async function rm(addr, options = {
    }) {
        const res = await api.post('bootstrap/rm', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: addr,
                ...options
            }),
            headers: options.headers
        });
        const { Peers  } = await res.json();
        return {
            Peers: Peers.map((ma)=>new multiaddr.Multiaddr(ma)
            )
        };
    }
    return rm;
});
exports.createRm = createRm;

},{"../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U","multiaddr":"kOPrF"}],"5zLry":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var index = require('./profiles/index.js');
var get = require('./get.js');
var getAll = require('./get-all.js');
var replace = require('./replace.js');
var set = require('./set.js');
function createConfig(config) {
    return {
        getAll: getAll.createGetAll(config),
        get: get.createGet(config),
        set: set.createSet(config),
        replace: replace.createReplace(config),
        profiles: index.createProfiles(config)
    };
}
exports.createConfig = createConfig;

},{"./profiles/index.js":"itVGR","./get.js":"c3Ms3","./get-all.js":"gA3RB","./replace.js":"fssu8","./set.js":"b8JTs"}],"itVGR":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var apply = require('./apply.js');
var list = require('./list.js');
function createProfiles(config) {
    return {
        apply: apply.createApply(config),
        list: list.createList(config)
    };
}
exports.createProfiles = createProfiles;

},{"./apply.js":"1BE5f","./list.js":"kXl1t"}],"1BE5f":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../../lib/configure.js');
var toUrlSearchParams = require('../../lib/to-url-search-params.js');
const createApply = configure.configure((api)=>{
    async function apply(profile, options = {
    }) {
        const res = await api.post('config/profile/apply', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: profile,
                ...options
            }),
            headers: options.headers
        });
        const data = await res.json();
        return {
            original: data.OldCfg,
            updated: data.NewCfg
        };
    }
    return apply;
});
exports.createApply = createApply;

},{"../../lib/configure.js":"eVYJh","../../lib/to-url-search-params.js":"5cN7U"}],"kXl1t":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var objectToCamel = require('../../lib/object-to-camel.js');
var configure = require('../../lib/configure.js');
var toUrlSearchParams = require('../../lib/to-url-search-params.js');
const createList = configure.configure((api)=>{
    async function list(options = {
    }) {
        const res = await api.post('config/profile/list', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams(options),
            headers: options.headers
        });
        const data = await res.json();
        return data.map((profile)=>objectToCamel.objectToCamel(profile)
        );
    }
    return list;
});
exports.createList = createList;

},{"../../lib/object-to-camel.js":"5IyF9","../../lib/configure.js":"eVYJh","../../lib/to-url-search-params.js":"5cN7U"}],"5IyF9":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
function objectToCamel(obj) {
    if (obj == null) return obj;
    const caps = /^[A-Z]+$/;
    const output = {
    };
    return Object.keys(obj).reduce((camelObj, k)=>{
        if (caps.test(k)) camelObj[k.toLowerCase()] = obj[k];
        else if (caps.test(k[0])) camelObj[k[0].toLowerCase() + k.slice(1)] = obj[k];
        else camelObj[k] = obj[k];
        return camelObj;
    }, output);
}
exports.objectToCamel = objectToCamel;

},{}],"c3Ms3":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createGet = configure.configure((api)=>{
    const get = async (key, options = {
    })=>{
        if (!key) throw new Error('key argument is required');
        const res = await api.post('config', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: key,
                ...options
            }),
            headers: options.headers
        });
        const data = await res.json();
        return data.Value;
    };
    return get;
});
exports.createGet = createGet;

},{"../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"gA3RB":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createGetAll = configure.configure((api)=>{
    const getAll = async (options = {
    })=>{
        const res = await api.post('config/show', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                ...options
            }),
            headers: options.headers
        });
        const data = await res.json();
        return data;
    };
    return getAll;
});
exports.createGetAll = createGetAll;

},{"../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"fssu8":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var fromString = require('uint8arrays/from-string');
var multipartRequest = require('ipfs-core-utils/multipart-request');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
var abortSignal = require('../lib/abort-signal.js');
var nativeAbortController = require('native-abort-controller');
const createReplace = configure.configure((api)=>{
    const replace = async (config, options = {
    })=>{
        const controller = new nativeAbortController.AbortController();
        const signal = abortSignal.abortSignal(controller.signal, options.signal);
        const res = await api.post('config/replace', {
            signal,
            searchParams: toUrlSearchParams.toUrlSearchParams(options),
            ...await multipartRequest.multipartRequest(fromString.fromString(JSON.stringify(config)), controller, options.headers)
        });
        await res.text();
    };
    return replace;
});
exports.createReplace = createReplace;

},{"uint8arrays/from-string":"lo45E","ipfs-core-utils/multipart-request":"byZwt","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U","../lib/abort-signal.js":"eZ7xd","native-abort-controller":"9z1Uk"}],"b8JTs":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createSet = configure.configure((api)=>{
    const set = async (key, value, options = {
    })=>{
        if (typeof key !== 'string') throw new Error('Invalid key type');
        const params = {
            ...options,
            ...encodeParam(key, value)
        };
        const res = await api.post('config', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams(params),
            headers: options.headers
        });
        await res.text();
    };
    return set;
});
const encodeParam = (key, value)=>{
    switch(typeof value){
        case 'boolean':
            return {
                arg: [
                    key,
                    value.toString()
                ],
                bool: true
            };
        case 'string':
            return {
                arg: [
                    key,
                    value
                ]
            };
        default:
            return {
                arg: [
                    key,
                    JSON.stringify(value)
                ],
                json: true
            };
    }
};
exports.createSet = createSet;

},{"../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"Q9mME":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var _export = require('./export.js');
var get = require('./get.js');
var _import = require('./import.js');
var put = require('./put.js');
var resolve = require('./resolve.js');
function createDag(codecs, config) {
    return {
        export: _export.createExport(config),
        get: get.createGet(codecs, config),
        import: _import.createImport(config),
        put: put.createPut(codecs, config),
        resolve: resolve.createResolve(config)
    };
}
exports.createDag = createDag;

},{"./export.js":"9X4j1","./get.js":"agGts","./import.js":"imbPu","./put.js":"4Ld0l","./resolve.js":"4sO6P"}],"9X4j1":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createExport = configure.configure((api)=>{
    async function* dagExport(root, options = {
    }) {
        const res = await api.post('dag/export', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: root.toString()
            }),
            headers: options.headers
        });
        yield* res.iterator();
    }
    return dagExport;
});
exports.createExport = createExport;

},{"../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"agGts":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var resolve = require('../lib/resolve.js');
var first = require('it-first');
var last = require('it-last');
var errCode = require('err-code');
var get = require('../block/get.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var first__default = /*#__PURE__*/ _interopDefaultLegacy(first);
var last__default = /*#__PURE__*/ _interopDefaultLegacy(last);
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
const createGet = (codecs, options1)=>{
    const fn = configure.configure((api, opts)=>{
        const getBlock = get.createGet(opts);
        const get$1 = async (cid, options = {
        })=>{
            if (options.path) {
                const entry = options.localResolve ? await first__default['default'](resolve.resolve(cid, options.path, codecs, getBlock, options)) : await last__default['default'](resolve.resolve(cid, options.path, codecs, getBlock, options));
                const result = entry;
                if (!result) throw errCode__default['default'](new Error('Not found'), 'ERR_NOT_FOUND');
                return result;
            }
            const codec = await codecs.getCodec(cid.code);
            const block = await getBlock(cid, options);
            const node = codec.decode(block);
            return {
                value: node,
                remainderPath: ''
            };
        };
        return get$1;
    });
    return fn(options1);
};
exports.createGet = createGet;

},{"../lib/configure.js":"eVYJh","../lib/resolve.js":"3yNuz","it-first":"imIGO","it-last":"7VTHF","err-code":"eQvyh","../block/get.js":"iARwf"}],"3yNuz":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid1 = require('multiformats/cid');
var errCode = require('err-code');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
async function* resolve(cid$1, path, codecs, getBlock, options) {
    const load = async (cid)=>{
        const codec = await codecs.getCodec(cid.code);
        const block = await getBlock(cid, options);
        return codec.decode(block);
    };
    const parts = path.split('/').filter(Boolean);
    let value = await load(cid$1);
    let lastCid = cid$1;
    if (!parts.length) yield {
        value,
        remainderPath: ''
    };
    while(parts.length){
        const key = parts.shift();
        if (!key) throw errCode__default['default'](new Error(`Could not resolve path "${path}"`), 'ERR_INVALID_PATH');
        if (Object.prototype.hasOwnProperty.call(value, key)) {
            value = value[key];
            yield {
                value,
                remainderPath: parts.join('/')
            };
        } else throw errCode__default['default'](new Error(`no link named "${key}" under ${lastCid}`), 'ERR_NO_LINK');
        const cid$1 = cid1.CID.asCID(value);
        if (cid$1) {
            lastCid = cid$1;
            value = await load(value);
        }
    }
}
exports.resolve = resolve;

},{"multiformats/cid":"fJJnW","err-code":"eQvyh"}],"imbPu":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
var abortSignal = require('../lib/abort-signal.js');
var multipartRequest = require('ipfs-core-utils/multipart-request');
var nativeAbortController = require('native-abort-controller');
var cid = require('multiformats/cid');
const createImport = configure.configure((api)=>{
    async function* dagImport(source, options = {
    }) {
        const controller = new nativeAbortController.AbortController();
        const signal = abortSignal.abortSignal(controller.signal, options.signal);
        const { headers , body  } = await multipartRequest.multipartRequest(source, controller, options.headers);
        const res = await api.post('dag/import', {
            signal,
            headers,
            body,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                'pin-roots': options.pinRoots
            })
        });
        for await (const { Root  } of res.ndjson())if (Root !== undefined) {
            const { Cid: { '/': Cid  } , PinErrorMsg  } = Root;
            yield {
                root: {
                    cid: cid.CID.parse(Cid),
                    pinErrorMsg: PinErrorMsg
                }
            };
        }
    }
    return dagImport;
});
exports.createImport = createImport;

},{"../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U","../lib/abort-signal.js":"eZ7xd","ipfs-core-utils/multipart-request":"byZwt","native-abort-controller":"9z1Uk","multiformats/cid":"fJJnW"}],"4Ld0l":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
var configure = require('../lib/configure.js');
var multipartRequest = require('ipfs-core-utils/multipart-request');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
var abortSignal = require('../lib/abort-signal.js');
var nativeAbortController = require('native-abort-controller');
const createPut = (codecs, options1)=>{
    const fn = configure.configure((api)=>{
        const put = async (dagNode, options = {
        })=>{
            const settings = {
                format: 'dag-cbor',
                hashAlg: 'sha2-256',
                inputEnc: 'raw',
                ...options
            };
            const codec = await codecs.getCodec(settings.format);
            const serialized = codec.encode(dagNode);
            const controller = new nativeAbortController.AbortController();
            const signal = abortSignal.abortSignal(controller.signal, settings.signal);
            const res = await api.post('dag/put', {
                timeout: settings.timeout,
                signal,
                searchParams: toUrlSearchParams.toUrlSearchParams(settings),
                ...await multipartRequest.multipartRequest(serialized, controller, settings.headers)
            });
            const data = await res.json();
            return cid.CID.parse(data.Cid['/']);
        };
        return put;
    });
    return fn(options1);
};
exports.createPut = createPut;

},{"multiformats/cid":"fJJnW","../lib/configure.js":"eVYJh","ipfs-core-utils/multipart-request":"byZwt","../lib/to-url-search-params.js":"5cN7U","../lib/abort-signal.js":"eZ7xd","native-abort-controller":"9z1Uk"}],"4sO6P":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createResolve = configure.configure((api)=>{
    const resolve = async (ipfsPath, options = {
    })=>{
        const res = await api.post('dag/resolve', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: `${ipfsPath}${options.path ? `/${options.path}`.replace(/\/[/]+/g, '/') : ''}`,
                ...options
            }),
            headers: options.headers
        });
        const data = await res.json();
        return {
            cid: cid.CID.parse(data.Cid['/']),
            remainderPath: data.RemPath
        };
    };
    return resolve;
});
exports.createResolve = createResolve;

},{"multiformats/cid":"fJJnW","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"aMbu1":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var findPeer = require('./find-peer.js');
var findProvs = require('./find-provs.js');
var get = require('./get.js');
var provide = require('./provide.js');
var put = require('./put.js');
var query = require('./query.js');
function createDht(config) {
    return {
        findPeer: findPeer.createFindPeer(config),
        findProvs: findProvs.createFindProvs(config),
        get: get.createGet(config),
        provide: provide.createProvide(config),
        put: put.createPut(config),
        query: query.createQuery(config)
    };
}
exports.createDht = createDht;

},{"./find-peer.js":"8gYmZ","./find-provs.js":"eMhhf","./get.js":"36jil","./provide.js":"hSoDM","./put.js":"l6ZI8","./query.js":"gKP3N"}],"8gYmZ":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var multiaddr = require('multiaddr');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
var responseTypes = require('./response-types.js');
const createFindPeer = configure.configure((api)=>{
    async function findPeer(peerId, options = {
    }) {
        const res = await api.post('dht/findpeer', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: peerId,
                ...options
            }),
            headers: options.headers
        });
        for await (const data of res.ndjson())if (data.Type === responseTypes.FinalPeer && data.Responses) {
            const { ID , Addrs  } = data.Responses[0];
            return {
                id: ID,
                addrs: (Addrs || []).map((a)=>new multiaddr.Multiaddr(a)
                )
            };
        }
        throw new Error('not found');
    }
    return findPeer;
});
exports.createFindPeer = createFindPeer;

},{"multiaddr":"kOPrF","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U","./response-types.js":"bVjS1"}],"bVjS1":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
const SendingQuery = 0;
const PeerResponse = 1;
const FinalPeer = 2;
const QueryError = 3;
const Provider = 4;
const Value = 5;
const AddingPeer = 6;
const DialingPeer = 7;
exports.AddingPeer = AddingPeer;
exports.DialingPeer = DialingPeer;
exports.FinalPeer = FinalPeer;
exports.PeerResponse = PeerResponse;
exports.Provider = Provider;
exports.QueryError = QueryError;
exports.SendingQuery = SendingQuery;
exports.Value = Value;

},{}],"eMhhf":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var multiaddr = require('multiaddr');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
var responseTypes = require('./response-types.js');
const createFindProvs = configure.configure((api)=>{
    async function* findProvs(cid, options = {
    }) {
        const res = await api.post('dht/findprovs', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: cid.toString(),
                ...options
            }),
            headers: options.headers
        });
        for await (const message of res.ndjson()){
            if (message.Type === responseTypes.Provider && message.Responses) for (const { ID , Addrs  } of message.Responses)yield {
                id: ID,
                addrs: (Addrs || []).map((a)=>new multiaddr.Multiaddr(a)
                )
            };
        }
    }
    return findProvs;
});
exports.createFindProvs = createFindProvs;

},{"multiaddr":"kOPrF","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U","./response-types.js":"bVjS1"}],"36jil":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
var responseTypes = require('./response-types.js');
var fromString = require('uint8arrays/from-string');
var toString = require('uint8arrays/to-string');
const createGet = configure.configure((api)=>{
    async function get(key, options = {
    }) {
        const res = await api.post('dht/get', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: key instanceof Uint8Array ? toString.toString(key) : key,
                ...options
            }),
            headers: options.headers
        });
        for await (const message of res.ndjson()){
            if (message.Type === responseTypes.Value) return fromString.fromString(message.Extra, 'base64pad');
        }
        throw new Error('not found');
    }
    return get;
});
exports.createGet = createGet;

},{"../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U","./response-types.js":"bVjS1","uint8arrays/from-string":"lo45E","uint8arrays/to-string":"g3mCQ"}],"hSoDM":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var multiaddr = require('multiaddr');
var objectToCamel = require('../lib/object-to-camel.js');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createProvide = configure.configure((api)=>{
    async function* provide(cids, options = {
        recursive: false
    }) {
        const cidArr = Array.isArray(cids) ? cids : [
            cids
        ];
        const res = await api.post('dht/provide', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: cidArr.map((cid)=>cid.toString()
                ),
                ...options
            }),
            headers: options.headers
        });
        for await (let message of res.ndjson()){
            message = objectToCamel.objectToCamel(message);
            if (message.responses) message.responses = message.responses.map(({ ID , Addrs  })=>({
                    id: ID,
                    addrs: (Addrs || []).map((a)=>new multiaddr.Multiaddr(a)
                    )
                })
            );
            else message.responses = [];
            yield message;
        }
    }
    return provide;
});
exports.createProvide = createProvide;

},{"multiaddr":"kOPrF","../lib/object-to-camel.js":"5IyF9","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"l6ZI8":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var multiaddr = require('multiaddr');
var objectToCamel = require('../lib/object-to-camel.js');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
var multipartRequest = require('ipfs-core-utils/multipart-request');
var abortSignal = require('../lib/abort-signal.js');
var nativeAbortController = require('native-abort-controller');
var toString = require('uint8arrays/to-string');
const createPut = configure.configure((api)=>{
    async function* put(key, value, options = {
    }) {
        const controller = new nativeAbortController.AbortController();
        const signal = abortSignal.abortSignal(controller.signal, options.signal);
        const res = await api.post('dht/put', {
            signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: toString.toString(key),
                ...options
            }),
            ...await multipartRequest.multipartRequest(value, controller, options.headers)
        });
        for await (let message of res.ndjson()){
            message = objectToCamel.objectToCamel(message);
            if (message.responses) message.responses = message.responses.map(({ ID , Addrs  })=>({
                    id: ID,
                    addrs: (Addrs || []).map((a)=>new multiaddr.Multiaddr(a)
                    )
                })
            );
            yield message;
        }
    }
    return put;
});
exports.createPut = createPut;

},{"multiaddr":"kOPrF","../lib/object-to-camel.js":"5IyF9","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U","ipfs-core-utils/multipart-request":"byZwt","../lib/abort-signal.js":"eZ7xd","native-abort-controller":"9z1Uk","uint8arrays/to-string":"g3mCQ"}],"gKP3N":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var multiaddr = require('multiaddr');
var objectToCamel = require('../lib/object-to-camel.js');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createQuery = configure.configure((api)=>{
    async function* query(peerId, options = {
    }) {
        const res = await api.post('dht/query', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: peerId.toString(),
                ...options
            }),
            headers: options.headers
        });
        for await (let message of res.ndjson()){
            message = objectToCamel.objectToCamel(message);
            message.responses = (message.responses || []).map(({ ID , Addrs  })=>({
                    id: ID,
                    addrs: (Addrs || []).map((a)=>new multiaddr.Multiaddr(a)
                    )
                })
            );
            yield message;
        }
    }
    return query;
});
exports.createQuery = createQuery;

},{"multiaddr":"kOPrF","../lib/object-to-camel.js":"5IyF9","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"6Vojk":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cmds = require('./cmds.js');
var net = require('./net.js');
var sys = require('./sys.js');
function createDiag(config) {
    return {
        cmds: cmds.createCmds(config),
        net: net.createNet(config),
        sys: sys.createSys(config)
    };
}
exports.createDiag = createDiag;

},{"./cmds.js":"1B6bq","./net.js":"ixcuh","./sys.js":"7w2v0"}],"1B6bq":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createCmds = configure.configure((api)=>{
    async function cmds(options = {
    }) {
        const res = await api.post('diag/cmds', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams(options),
            headers: options.headers
        });
        return res.json();
    }
    return cmds;
});
exports.createCmds = createCmds;

},{"../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"ixcuh":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createNet = configure.configure((api)=>{
    async function net(options = {
    }) {
        const res = await api.post('diag/net', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams(options),
            headers: options.headers
        });
        return res.json();
    }
    return net;
});
exports.createNet = createNet;

},{"../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"7w2v0":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createSys = configure.configure((api)=>{
    async function sys(options = {
    }) {
        const res = await api.post('diag/sys', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams(options),
            headers: options.headers
        });
        return res.json();
    }
    return sys;
});
exports.createSys = createSys;

},{"../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"dk7I1":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var chmod = require('./chmod.js');
var cp = require('./cp.js');
var flush = require('./flush.js');
var ls = require('./ls.js');
var mkdir = require('./mkdir.js');
var mv = require('./mv.js');
var read = require('./read.js');
var rm = require('./rm.js');
var stat = require('./stat.js');
var touch = require('./touch.js');
var write = require('./write.js');
function createFiles(config) {
    return {
        chmod: chmod.createChmod(config),
        cp: cp.createCp(config),
        flush: flush.createFlush(config),
        ls: ls.createLs(config),
        mkdir: mkdir.createMkdir(config),
        mv: mv.createMv(config),
        read: read.createRead(config),
        rm: rm.createRm(config),
        stat: stat.createStat(config),
        touch: touch.createTouch(config),
        write: write.createWrite(config)
    };
}
exports.createFiles = createFiles;

},{"./chmod.js":"f6AxT","./cp.js":"jme3p","./flush.js":"loV7o","./ls.js":"aTbc9","./mkdir.js":"lY8eb","./mv.js":"12rlD","./read.js":"kH0xC","./rm.js":"cYA1K","./stat.js":"5sduk","./touch.js":"j8bP3","./write.js":"cpCSW"}],"f6AxT":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createChmod = configure.configure((api)=>{
    async function chmod(path, mode, options = {
    }) {
        const res = await api.post('files/chmod', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: path,
                mode,
                ...options
            }),
            headers: options.headers
        });
        await res.text();
    }
    return chmod;
});
exports.createChmod = createChmod;

},{"../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"jme3p":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createCp = configure.configure((api)=>{
    async function cp(sources, destination, options = {
    }) {
        const sourceArr = Array.isArray(sources) ? sources : [
            sources
        ];
        const res = await api.post('files/cp', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: sourceArr.concat(destination).map((src)=>cid.CID.asCID(src) ? `/ipfs/${src}` : src
                ),
                ...options
            }),
            headers: options.headers
        });
        await res.text();
    }
    return cp;
});
exports.createCp = createCp;

},{"multiformats/cid":"fJJnW","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"loV7o":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createFlush = configure.configure((api)=>{
    async function flush(path, options = {
    }) {
        if (!path || typeof path !== 'string') throw new Error('ipfs.files.flush requires a path');
        const res = await api.post('files/flush', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: path,
                ...options
            }),
            headers: options.headers
        });
        const data = await res.json();
        return cid.CID.parse(data.Cid);
    }
    return flush;
});
exports.createFlush = createFlush;

},{"multiformats/cid":"fJJnW","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"aTbc9":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
var objectToCamelWithMetadata = require('../lib/object-to-camel-with-metadata.js');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createLs = configure.configure((api)=>{
    async function* ls(path, options = {
    }) {
        if (!path) throw new Error('ipfs.files.ls requires a path');
        const res = await api.post('files/ls', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: cid.CID.asCID(path) ? `/ipfs/${path}` : path,
                long: true,
                ...options,
                stream: true
            }),
            headers: options.headers
        });
        for await (const result of res.ndjson()){
            if ('Entries' in result) for (const entry of result.Entries || [])yield toCoreInterface(objectToCamelWithMetadata.objectToCamelWithMetadata(entry));
            else yield toCoreInterface(objectToCamelWithMetadata.objectToCamelWithMetadata(result));
        }
    }
    return ls;
});
function toCoreInterface(entry) {
    if (entry.hash) entry.cid = cid.CID.parse(entry.hash);
    delete entry.hash;
    entry.type = entry.type === 1 ? 'directory' : 'file';
    return entry;
}
exports.createLs = createLs;

},{"multiformats/cid":"fJJnW","../lib/object-to-camel-with-metadata.js":"efZrW","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"efZrW":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var objectToCamel = require('./object-to-camel.js');
function objectToCamelWithMetadata(entry) {
    const file = objectToCamel.objectToCamel(entry);
    if (Object.prototype.hasOwnProperty.call(file, 'mode')) file.mode = parseInt(file.mode, 8);
    if (Object.prototype.hasOwnProperty.call(file, 'mtime')) {
        file.mtime = {
            secs: file.mtime,
            nsecs: file.mtimeNsecs || 0
        };
        delete file.mtimeNsecs;
    }
    return file;
}
exports.objectToCamelWithMetadata = objectToCamelWithMetadata;

},{"./object-to-camel.js":"5IyF9"}],"lY8eb":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createMkdir = configure.configure((api)=>{
    async function mkdir(path, options = {
    }) {
        const res = await api.post('files/mkdir', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: path,
                ...options
            }),
            headers: options.headers
        });
        await res.text();
    }
    return mkdir;
});
exports.createMkdir = createMkdir;

},{"../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"12rlD":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createMv = configure.configure((api)=>{
    async function mv(sources, destination, options = {
    }) {
        if (!Array.isArray(sources)) sources = [
            sources
        ];
        const res = await api.post('files/mv', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: sources.concat(destination),
                ...options
            }),
            headers: options.headers
        });
        await res.text();
    }
    return mv;
});
exports.createMv = createMv;

},{"../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"kH0xC":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
var toIterable = require('stream-to-it/source.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var toIterable__default = /*#__PURE__*/ _interopDefaultLegacy(toIterable);
const createRead = configure.configure((api)=>{
    async function* read(path, options = {
    }) {
        const res = await api.post('files/read', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: path,
                count: options.length,
                ...options
            }),
            headers: options.headers
        });
        yield* toIterable__default['default'](res.body);
    }
    return read;
});
exports.createRead = createRead;

},{"../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U","stream-to-it/source.js":"aJitJ"}],"aJitJ":[function(require,module,exports) {
module.exports = (readable)=>{
    // Node.js stream
    if (readable[Symbol.asyncIterator]) return readable;
    // Browser ReadableStream
    if (readable.getReader) return (async function*() {
        const reader = readable.getReader();
        try {
            while(true){
                const { done , value  } = await reader.read();
                if (done) return;
                yield value;
            }
        } finally{
            reader.releaseLock();
        }
    })();
    throw new Error('unknown stream');
};

},{}],"cYA1K":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createRm = configure.configure((api)=>{
    async function rm(path, options = {
    }) {
        const res = await api.post('files/rm', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: path,
                ...options
            }),
            headers: options.headers
        });
        await res.text();
    }
    return rm;
});
exports.createRm = createRm;

},{"../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"5sduk":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
var objectToCamelWithMetadata = require('../lib/object-to-camel-with-metadata.js');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createStat = configure.configure((api)=>{
    async function stat(path, options = {
    }) {
        const res = await api.post('files/stat', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: path,
                ...options
            }),
            headers: options.headers
        });
        const data = await res.json();
        data.WithLocality = data.WithLocality || false;
        return toCoreInterface(objectToCamelWithMetadata.objectToCamelWithMetadata(data));
    }
    return stat;
});
function toCoreInterface(entry) {
    entry.cid = cid.CID.parse(entry.hash);
    delete entry.hash;
    return entry;
}
exports.createStat = createStat;

},{"multiformats/cid":"fJJnW","../lib/object-to-camel-with-metadata.js":"efZrW","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"j8bP3":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createTouch = configure.configure((api)=>{
    async function touch(path, options = {
    }) {
        const res = await api.post('files/touch', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: path,
                ...options
            }),
            headers: options.headers
        });
        await res.text();
    }
    return touch;
});
exports.createTouch = createTouch;

},{"../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"cpCSW":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var modeToString = require('../lib/mode-to-string.js');
var parseMtime = require('../lib/parse-mtime.js');
var configure = require('../lib/configure.js');
var multipartRequest = require('ipfs-core-utils/multipart-request');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
var abortSignal = require('../lib/abort-signal.js');
var nativeAbortController = require('native-abort-controller');
const createWrite = configure.configure((api)=>{
    async function write(path, input, options = {
    }) {
        const controller = new nativeAbortController.AbortController();
        const signal = abortSignal.abortSignal(controller.signal, options.signal);
        const res = await api.post('files/write', {
            signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: path,
                streamChannels: true,
                count: options.length,
                ...options
            }),
            ...await multipartRequest.multipartRequest({
                content: input,
                path: 'arg',
                mode: modeToString.modeToString(options.mode),
                mtime: parseMtime.parseMtime(options.mtime)
            }, controller, options.headers)
        });
        await res.text();
    }
    return write;
});
exports.createWrite = createWrite;

},{"../lib/mode-to-string.js":"cpT7L","../lib/parse-mtime.js":"529iQ","../lib/configure.js":"eVYJh","ipfs-core-utils/multipart-request":"byZwt","../lib/to-url-search-params.js":"5cN7U","../lib/abort-signal.js":"eZ7xd","native-abort-controller":"9z1Uk"}],"hw9f3":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var _export = require('./export.js');
var gen = require('./gen.js');
var _import = require('./import.js');
var info = require('./info.js');
var list = require('./list.js');
var rename = require('./rename.js');
var rm = require('./rm.js');
function createKey(config) {
    return {
        export: _export.createExport(config),
        gen: gen.createGen(config),
        import: _import.createImport(config),
        info: info.createInfo(config),
        list: list.createList(config),
        rename: rename.createRename(config),
        rm: rm.createRm(config)
    };
}
exports.createKey = createKey;

},{"./export.js":"5ehPn","./gen.js":"kL9nT","./import.js":"hxiQH","./info.js":"isD4g","./list.js":"421Hg","./rename.js":"b54Jn","./rm.js":"3ORcg"}],"5ehPn":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var errCode = require('err-code');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
const createExport = configure.configure((api)=>{
    const exportKey = async (name, password, options = {
    })=>{
        throw errCode__default['default'](new Error('Not implemented'), 'ERR_NOT_IMPLEMENTED');
    };
    return exportKey;
});
exports.createExport = createExport;

},{"../lib/configure.js":"eVYJh","err-code":"eQvyh"}],"kL9nT":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var objectToCamel = require('../lib/object-to-camel.js');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createGen = configure.configure((api)=>{
    async function gen(name, options = {
        type: 'rsa',
        size: 2048
    }) {
        const res = await api.post('key/gen', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: name,
                ...options
            }),
            headers: options.headers
        });
        const data = await res.json();
        return objectToCamel.objectToCamel(data);
    }
    return gen;
});
exports.createGen = createGen;

},{"../lib/object-to-camel.js":"5IyF9","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"hxiQH":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var objectToCamel = require('../lib/object-to-camel.js');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createImport = configure.configure((api)=>{
    async function importKey(name, pem, password, options = {
    }) {
        const res = await api.post('key/import', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: name,
                pem,
                password,
                ...options
            }),
            headers: options.headers
        });
        const data = await res.json();
        return objectToCamel.objectToCamel(data);
    }
    return importKey;
});
exports.createImport = createImport;

},{"../lib/object-to-camel.js":"5IyF9","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"isD4g":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var errCode = require('err-code');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
const createInfo = configure.configure((api)=>{
    const info = async (name, options = {
    })=>{
        throw errCode__default['default'](new Error('Not implemented'), 'ERR_NOT_IMPLEMENTED');
    };
    return info;
});
exports.createInfo = createInfo;

},{"../lib/configure.js":"eVYJh","err-code":"eQvyh"}],"421Hg":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var objectToCamel = require('../lib/object-to-camel.js');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createList = configure.configure((api)=>{
    async function list(options = {
    }) {
        const res = await api.post('key/list', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams(options),
            headers: options.headers
        });
        const data = await res.json();
        return (data.Keys || []).map((k)=>objectToCamel.objectToCamel(k)
        );
    }
    return list;
});
exports.createList = createList;

},{"../lib/object-to-camel.js":"5IyF9","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"b54Jn":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var objectToCamel = require('../lib/object-to-camel.js');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createRename = configure.configure((api)=>{
    async function rename(oldName, newName, options = {
    }) {
        const res = await api.post('key/rename', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: [
                    oldName,
                    newName
                ],
                ...options
            }),
            headers: options.headers
        });
        return objectToCamel.objectToCamel(await res.json());
    }
    return rename;
});
exports.createRename = createRename;

},{"../lib/object-to-camel.js":"5IyF9","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"3ORcg":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var objectToCamel = require('../lib/object-to-camel.js');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createRm = configure.configure((api)=>{
    async function rm(name, options = {
    }) {
        const res = await api.post('key/rm', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: name,
                ...options
            }),
            headers: options.headers
        });
        const data = await res.json();
        return objectToCamel.objectToCamel(data.Keys[0]);
    }
    return rm;
});
exports.createRm = createRm;

},{"../lib/object-to-camel.js":"5IyF9","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"7Oym0":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var level = require('./level.js');
var ls = require('./ls.js');
var tail = require('./tail.js');
function createLog(config) {
    return {
        level: level.createLevel(config),
        ls: ls.createLs(config),
        tail: tail.createTail(config)
    };
}
exports.createLog = createLog;

},{"./level.js":"Bp4Xr","./ls.js":"eEKLF","./tail.js":"hhSAk"}],"Bp4Xr":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var objectToCamel = require('../lib/object-to-camel.js');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createLevel = configure.configure((api)=>{
    async function level1(subsystem, level, options = {
    }) {
        const res = await api.post('log/level', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: [
                    subsystem,
                    level
                ],
                ...options
            }),
            headers: options.headers
        });
        return objectToCamel.objectToCamel(await res.json());
    }
    return level1;
});
exports.createLevel = createLevel;

},{"../lib/object-to-camel.js":"5IyF9","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"eEKLF":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createLs = configure.configure((api)=>{
    async function ls(options = {
    }) {
        const res = await api.post('log/ls', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams(options),
            headers: options.headers
        });
        const data = await res.json();
        return data.Strings;
    }
    return ls;
});
exports.createLs = createLs;

},{"../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"hhSAk":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createTail = configure.configure((api)=>{
    async function* tail(options = {
    }) {
        const res = await api.post('log/tail', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams(options),
            headers: options.headers
        });
        yield* res.ndjson();
    }
    return tail;
});
exports.createTail = createTail;

},{"../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"jUURl":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var publish = require('./publish.js');
var resolve = require('./resolve.js');
var index = require('./pubsub/index.js');
function createName(config) {
    return {
        publish: publish.createPublish(config),
        resolve: resolve.createResolve(config),
        pubsub: index.createPubsub(config)
    };
}
exports.createName = createName;

},{"./publish.js":"dmrXL","./resolve.js":"7g6Ba","./pubsub/index.js":"eb1Kd"}],"dmrXL":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var objectToCamel = require('../lib/object-to-camel.js');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createPublish = configure.configure((api)=>{
    async function publish(path, options = {
    }) {
        const res = await api.post('name/publish', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: `${path}`,
                ...options
            }),
            headers: options.headers
        });
        return objectToCamel.objectToCamel(await res.json());
    }
    return publish;
});
exports.createPublish = createPublish;

},{"../lib/object-to-camel.js":"5IyF9","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"7g6Ba":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createResolve = configure.configure((api)=>{
    async function* resolve(path, options = {
    }) {
        const res = await api.post('name/resolve', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: path,
                stream: true,
                ...options
            }),
            headers: options.headers
        });
        for await (const result of res.ndjson())yield result.Path;
    }
    return resolve;
});
exports.createResolve = createResolve;

},{"../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"eb1Kd":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cancel = require('./cancel.js');
var state = require('./state.js');
var subs = require('./subs.js');
function createPubsub(config) {
    return {
        cancel: cancel.createCancel(config),
        state: state.createState(config),
        subs: subs.createSubs(config)
    };
}
exports.createPubsub = createPubsub;

},{"./cancel.js":"927Z4","./state.js":"5u6qS","./subs.js":"9ZLxN"}],"927Z4":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var objectToCamel = require('../../lib/object-to-camel.js');
var configure = require('../../lib/configure.js');
var toUrlSearchParams = require('../../lib/to-url-search-params.js');
const createCancel = configure.configure((api)=>{
    async function cancel(name, options = {
    }) {
        const res = await api.post('name/pubsub/cancel', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: name,
                ...options
            }),
            headers: options.headers
        });
        return objectToCamel.objectToCamel(await res.json());
    }
    return cancel;
});
exports.createCancel = createCancel;

},{"../../lib/object-to-camel.js":"5IyF9","../../lib/configure.js":"eVYJh","../../lib/to-url-search-params.js":"5cN7U"}],"5u6qS":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var objectToCamel = require('../../lib/object-to-camel.js');
var configure = require('../../lib/configure.js');
var toUrlSearchParams = require('../../lib/to-url-search-params.js');
const createState = configure.configure((api)=>{
    async function state(options = {
    }) {
        const res = await api.post('name/pubsub/state', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams(options),
            headers: options.headers
        });
        return objectToCamel.objectToCamel(await res.json());
    }
    return state;
});
exports.createState = createState;

},{"../../lib/object-to-camel.js":"5IyF9","../../lib/configure.js":"eVYJh","../../lib/to-url-search-params.js":"5cN7U"}],"9ZLxN":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../../lib/configure.js');
var toUrlSearchParams = require('../../lib/to-url-search-params.js');
const createSubs = configure.configure((api)=>{
    async function subs(options = {
    }) {
        const res = await api.post('name/pubsub/subs', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams(options),
            headers: options.headers
        });
        const data = await res.json();
        return data.Strings || [];
    }
    return subs;
});
exports.createSubs = createSubs;

},{"../../lib/configure.js":"eVYJh","../../lib/to-url-search-params.js":"5cN7U"}],"gAOao":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var data = require('./data.js');
var get = require('./get.js');
var links = require('./links.js');
var _new = require('./new.js');
var put = require('./put.js');
var stat = require('./stat.js');
var index = require('./patch/index.js');
function createObject(codecs, config) {
    return {
        data: data.createData(config),
        get: get.createGet(config),
        links: links.createLinks(config),
        new: _new.createNew(config),
        put: put.createPut(codecs, config),
        stat: stat.createStat(config),
        patch: index.createPatch(config)
    };
}
exports.createObject = createObject;

},{"./data.js":"7fhvW","./get.js":"4Q5Ay","./links.js":"jhkDs","./new.js":"5gRUw","./put.js":"gWSYA","./stat.js":"b0sQB","./patch/index.js":"lSIBS"}],"7fhvW":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createData = configure.configure((api)=>{
    async function data1(cid$1, options = {
    }) {
        const res = await api.post('object/data', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: `${cid$1 instanceof Uint8Array ? cid.CID.decode(cid$1) : cid$1}`,
                ...options
            }),
            headers: options.headers
        });
        const data = await res.arrayBuffer();
        return new Uint8Array(data, 0, data.byteLength);
    }
    return data1;
});
exports.createData = createData;

},{"multiformats/cid":"fJJnW","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"4Q5Ay":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
var fromString = require('uint8arrays/from-string');
const createGet = configure.configure((api)=>{
    async function get(cid$1, options = {
    }) {
        const res = await api.post('object/get', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: `${cid$1 instanceof Uint8Array ? cid.CID.decode(cid$1) : cid$1}`,
                dataEncoding: 'base64',
                ...options
            }),
            headers: options.headers
        });
        const data = await res.json();
        return {
            Data: fromString.fromString(data.Data, 'base64pad'),
            Links: (data.Links || []).map((link)=>({
                    Name: link.Name,
                    Hash: cid.CID.parse(link.Hash),
                    Tsize: link.Size
                })
            )
        };
    }
    return get;
});
exports.createGet = createGet;

},{"multiformats/cid":"fJJnW","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U","uint8arrays/from-string":"lo45E"}],"jhkDs":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createLinks = configure.configure((api)=>{
    async function links(cid$1, options = {
    }) {
        const res = await api.post('object/links', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: `${cid$1 instanceof Uint8Array ? cid.CID.decode(cid$1) : cid$1}`,
                ...options
            }),
            headers: options.headers
        });
        const data = await res.json();
        return (data.Links || []).map((l)=>({
                Name: l.Name,
                Tsize: l.Size,
                Hash: cid.CID.parse(l.Hash)
            })
        );
    }
    return links;
});
exports.createLinks = createLinks;

},{"multiformats/cid":"fJJnW","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"5gRUw":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createNew = configure.configure((api)=>{
    async function newObject(options = {
    }) {
        const res = await api.post('object/new', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: options.template,
                ...options
            }),
            headers: options.headers
        });
        const { Hash  } = await res.json();
        return cid.CID.parse(Hash);
    }
    return newObject;
});
exports.createNew = createNew;

},{"multiformats/cid":"fJJnW","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"gWSYA":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var put = require('../dag/put.js');
const createPut = (codecs, options1)=>{
    const fn = configure.configure((api)=>{
        const dagPut = put.createPut(codecs, options1);
        async function put$1(obj, options = {
        }) {
            return dagPut(obj, {
                ...options,
                format: 'dag-pb',
                hashAlg: 'sha2-256',
                version: 0
            });
        }
        return put$1;
    });
    return fn(options1);
};
exports.createPut = createPut;

},{"../lib/configure.js":"eVYJh","../dag/put.js":"4Ld0l"}],"b0sQB":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createStat = configure.configure((api)=>{
    async function stat(cid$1, options = {
    }) {
        const res = await api.post('object/stat', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: `${cid$1}`,
                ...options
            }),
            headers: options.headers
        });
        const output = await res.json();
        return {
            ...output,
            Hash: cid.CID.parse(output.Hash)
        };
    }
    return stat;
});
exports.createStat = createStat;

},{"multiformats/cid":"fJJnW","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"lSIBS":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var addLink = require('./add-link.js');
var appendData = require('./append-data.js');
var rmLink = require('./rm-link.js');
var setData = require('./set-data.js');
function createPatch(config) {
    return {
        addLink: addLink.createAddLink(config),
        appendData: appendData.createAppendData(config),
        rmLink: rmLink.createRmLink(config),
        setData: setData.createSetData(config)
    };
}
exports.createPatch = createPatch;

},{"./add-link.js":"lMWpD","./append-data.js":"ikpNk","./rm-link.js":"lC0ro","./set-data.js":"5yBNI"}],"lMWpD":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
var configure = require('../../lib/configure.js');
var toUrlSearchParams = require('../../lib/to-url-search-params.js');
const createAddLink = configure.configure((api)=>{
    async function addLink(cid$1, dLink, options = {
    }) {
        const res = await api.post('object/patch/add-link', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: [
                    `${cid$1}`,
                    dLink.Name || dLink.name || '',
                    (dLink.Hash || dLink.cid || '').toString() || null
                ],
                ...options
            }),
            headers: options.headers
        });
        const { Hash  } = await res.json();
        return cid.CID.parse(Hash);
    }
    return addLink;
});
exports.createAddLink = createAddLink;

},{"multiformats/cid":"fJJnW","../../lib/configure.js":"eVYJh","../../lib/to-url-search-params.js":"5cN7U"}],"ikpNk":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
var multipartRequest = require('ipfs-core-utils/multipart-request');
var configure = require('../../lib/configure.js');
var toUrlSearchParams = require('../../lib/to-url-search-params.js');
var abortSignal = require('../../lib/abort-signal.js');
var nativeAbortController = require('native-abort-controller');
const createAppendData = configure.configure((api)=>{
    async function appendData(cid$1, data, options = {
    }) {
        const controller = new nativeAbortController.AbortController();
        const signal = abortSignal.abortSignal(controller.signal, options.signal);
        const res = await api.post('object/patch/append-data', {
            signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: `${cid$1}`,
                ...options
            }),
            ...await multipartRequest.multipartRequest(data, controller, options.headers)
        });
        const { Hash  } = await res.json();
        return cid.CID.parse(Hash);
    }
    return appendData;
});
exports.createAppendData = createAppendData;

},{"multiformats/cid":"fJJnW","ipfs-core-utils/multipart-request":"byZwt","../../lib/configure.js":"eVYJh","../../lib/to-url-search-params.js":"5cN7U","../../lib/abort-signal.js":"eZ7xd","native-abort-controller":"9z1Uk"}],"lC0ro":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
var configure = require('../../lib/configure.js');
var toUrlSearchParams = require('../../lib/to-url-search-params.js');
const createRmLink = configure.configure((api)=>{
    async function rmLink(cid$1, dLink, options = {
    }) {
        const res = await api.post('object/patch/rm-link', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: [
                    `${cid$1}`,
                    dLink.Name || dLink.name || null
                ],
                ...options
            }),
            headers: options.headers
        });
        const { Hash  } = await res.json();
        return cid.CID.parse(Hash);
    }
    return rmLink;
});
exports.createRmLink = createRmLink;

},{"multiformats/cid":"fJJnW","../../lib/configure.js":"eVYJh","../../lib/to-url-search-params.js":"5cN7U"}],"5yBNI":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
var multipartRequest = require('ipfs-core-utils/multipart-request');
var configure = require('../../lib/configure.js');
var toUrlSearchParams = require('../../lib/to-url-search-params.js');
var abortSignal = require('../../lib/abort-signal.js');
var nativeAbortController = require('native-abort-controller');
const createSetData = configure.configure((api)=>{
    async function setData(cid$1, data, options = {
    }) {
        const controller = new nativeAbortController.AbortController();
        const signal = abortSignal.abortSignal(controller.signal, options.signal);
        const res = await api.post('object/patch/set-data', {
            signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: [
                    `${cid$1}`
                ],
                ...options
            }),
            ...await multipartRequest.multipartRequest(data, controller, options.headers)
        });
        const { Hash  } = await res.json();
        return cid.CID.parse(Hash);
    }
    return setData;
});
exports.createSetData = createSetData;

},{"multiformats/cid":"fJJnW","ipfs-core-utils/multipart-request":"byZwt","../../lib/configure.js":"eVYJh","../../lib/to-url-search-params.js":"5cN7U","../../lib/abort-signal.js":"eZ7xd","native-abort-controller":"9z1Uk"}],"dZ3F1":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var addAll = require('./add-all.js');
var add = require('./add.js');
var ls = require('./ls.js');
var rmAll = require('./rm-all.js');
var rm = require('./rm.js');
var index = require('./remote/index.js');
function createPin(config) {
    return {
        addAll: addAll.createAddAll(config),
        add: add.createAdd(config),
        ls: ls.createLs(config),
        rmAll: rmAll.createRmAll(config),
        rm: rm.createRm(config),
        remote: index.createRemote(config)
    };
}
exports.createPin = createPin;

},{"./add-all.js":"9dlG1","./add.js":"7bGhr","./ls.js":"9ikJG","./rm-all.js":"lAwfF","./rm.js":"epzU7","./remote/index.js":"hQxDT"}],"9dlG1":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
var configure = require('../lib/configure.js');
var normaliseInput = require('ipfs-core-utils/pins/normalise-input');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createAddAll = configure.configure((api)=>{
    async function* addAll(source, options = {
    }) {
        for await (const { path , recursive , metadata  } of normaliseInput.normaliseInput(source)){
            const res = await api.post('pin/add', {
                signal: options.signal,
                searchParams: toUrlSearchParams.toUrlSearchParams({
                    ...options,
                    arg: path,
                    recursive,
                    metadata: metadata ? JSON.stringify(metadata) : undefined,
                    stream: true
                }),
                headers: options.headers
            });
            for await (const pin of res.ndjson()){
                if (pin.Pins) {
                    for (const cid$1 of pin.Pins)yield cid.CID.parse(cid$1);
                    continue;
                }
                yield cid.CID.parse(pin);
            }
        }
    }
    return addAll;
});
exports.createAddAll = createAddAll;

},{"multiformats/cid":"fJJnW","../lib/configure.js":"eVYJh","ipfs-core-utils/pins/normalise-input":"azEwN","../lib/to-url-search-params.js":"5cN7U"}],"7bGhr":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var addAll = require('./add-all.js');
var last = require('it-last');
var configure = require('../lib/configure.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var last__default = /*#__PURE__*/ _interopDefaultLegacy(last);
function createAdd(config) {
    const all = addAll.createAddAll(config);
    return configure.configure(()=>{
        async function add(path, options = {
        }) {
            return last__default['default'](all([
                {
                    path,
                    ...options
                }
            ], options));
        }
        return add;
    })(config);
}
exports.createAdd = createAdd;

},{"./add-all.js":"9dlG1","it-last":"7VTHF","../lib/configure.js":"eVYJh"}],"9ikJG":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid1 = require('multiformats/cid');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
function toPin(type, cid$1, metadata) {
    const pin = {
        type,
        cid: cid1.CID.parse(cid$1)
    };
    if (metadata) pin.metadata = metadata;
    return pin;
}
const createLs = configure.configure((api)=>{
    async function* ls(options = {
    }) {
        let paths = [];
        if (options.paths) paths = Array.isArray(options.paths) ? options.paths : [
            options.paths
        ];
        const res = await api.post('pin/ls', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                ...options,
                arg: paths.map((path)=>`${path}`
                ),
                stream: true
            }),
            headers: options.headers
        });
        for await (const pin of res.ndjson()){
            if (pin.Keys) {
                for (const cid of Object.keys(pin.Keys))yield toPin(pin.Keys[cid].Type, cid, pin.Keys[cid].Metadata);
                return;
            }
            yield toPin(pin.Type, pin.Cid, pin.Metadata);
        }
    }
    return ls;
});
exports.createLs = createLs;

},{"multiformats/cid":"fJJnW","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"lAwfF":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
var configure = require('../lib/configure.js');
var normaliseInput = require('ipfs-core-utils/pins/normalise-input');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createRmAll = configure.configure((api)=>{
    async function* rmAll(source, options = {
    }) {
        for await (const { path , recursive  } of normaliseInput.normaliseInput(source)){
            const searchParams = new URLSearchParams(options.searchParams);
            searchParams.append('arg', `${path}`);
            if (recursive != null) searchParams.set('recursive', String(recursive));
            const res = await api.post('pin/rm', {
                signal: options.signal,
                headers: options.headers,
                searchParams: toUrlSearchParams.toUrlSearchParams({
                    ...options,
                    arg: `${path}`,
                    recursive
                })
            });
            for await (const pin of res.ndjson()){
                if (pin.Pins) {
                    yield* pin.Pins.map((cid$1)=>cid.CID.parse(cid$1)
                    );
                    continue;
                }
                yield cid.CID.parse(pin);
            }
        }
    }
    return rmAll;
});
exports.createRmAll = createRmAll;

},{"multiformats/cid":"fJJnW","../lib/configure.js":"eVYJh","ipfs-core-utils/pins/normalise-input":"azEwN","../lib/to-url-search-params.js":"5cN7U"}],"epzU7":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var rmAll = require('./rm-all.js');
var last = require('it-last');
var configure = require('../lib/configure.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var last__default = /*#__PURE__*/ _interopDefaultLegacy(last);
const createRm = (config)=>{
    const all = rmAll.createRmAll(config);
    return configure.configure(()=>{
        async function rm(path, options = {
        }) {
            return last__default['default'](all([
                {
                    path,
                    ...options
                }
            ], options));
        }
        return rm;
    })(config);
};
exports.createRm = createRm;

},{"./rm-all.js":"lAwfF","it-last":"7VTHF","../lib/configure.js":"eVYJh"}],"hQxDT":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var core = require('../../lib/core.js');
var add = require('./add.js');
var ls = require('./ls.js');
var rm = require('./rm.js');
var rmAll = require('./rm-all.js');
var index = require('./service/index.js');
function createRemote(config) {
    const client = new core.Client(config);
    return {
        add: add.createAdd(client),
        ls: ls.createLs(client),
        rm: rm.createRm(client),
        rmAll: rmAll.createRmAll(client),
        service: index.createService(config)
    };
}
exports.createRemote = createRemote;

},{"../../lib/core.js":"g5LBC","./add.js":"7QlE1","./ls.js":"ia2g5","./rm.js":"ezmds","./rm-all.js":"aSasu","./service/index.js":"aQURt"}],"7QlE1":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var utils = require('./utils.js');
function createAdd(client) {
    async function add(cid, { timeout , signal , headers , ...query }) {
        const response = await client.post('pin/remote/add', {
            timeout,
            signal,
            headers,
            searchParams: utils.encodeAddParams({
                cid,
                ...query
            })
        });
        return utils.decodePin(await response.json());
    }
    return add;
}
exports.createAdd = createAdd;

},{"./utils.js":"66KGT"}],"66KGT":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid1 = require('multiformats/cid');
var toUrlSearchParams = require('../../lib/to-url-search-params.js');
const decodePin = ({ Name: name , Status: status , Cid: cid$1  })=>{
    return {
        cid: cid1.CID.parse(cid$1),
        name,
        status
    };
};
const encodeService = (service)=>{
    if (typeof service === 'string' && service !== '') return service;
    else throw new TypeError('service name must be passed');
};
const encodeCID = (cid$1)=>{
    if (cid1.CID.asCID(cid$1)) return cid$1.toString();
    else throw new TypeError(`CID instance expected instead of ${typeof cid$1}`);
};
const encodeQuery = ({ service , cid , name , status , all  })=>{
    const query = toUrlSearchParams.toUrlSearchParams({
        service: encodeService(service),
        name,
        force: all ? true : undefined
    });
    if (cid) for (const value of cid)query.append('cid', encodeCID(value));
    if (status) for (const value1 of status)query.append('status', value1);
    return query;
};
const encodeAddParams = ({ cid , service , background , name , origins  })=>{
    const params = toUrlSearchParams.toUrlSearchParams({
        arg: encodeCID(cid),
        service: encodeService(service),
        name,
        background: background ? true : undefined
    });
    if (origins) for (const origin of origins)params.append('origin', origin.toString());
    return params;
};
exports.decodePin = decodePin;
exports.encodeAddParams = encodeAddParams;
exports.encodeCID = encodeCID;
exports.encodeQuery = encodeQuery;
exports.encodeService = encodeService;

},{"multiformats/cid":"fJJnW","../../lib/to-url-search-params.js":"5cN7U"}],"ia2g5":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var utils = require('./utils.js');
function createLs(client) {
    async function* ls({ timeout , signal , headers , ...query }) {
        const response = await client.post('pin/remote/ls', {
            timeout,
            signal,
            headers,
            searchParams: utils.encodeQuery(query)
        });
        for await (const pin of response.ndjson())yield utils.decodePin(pin);
    }
    return ls;
}
exports.createLs = createLs;

},{"./utils.js":"66KGT"}],"ezmds":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var utils = require('./utils.js');
function createRm(client) {
    async function rm({ timeout , signal , headers , ...query }) {
        await client.post('pin/remote/rm', {
            timeout,
            signal,
            headers,
            searchParams: utils.encodeQuery({
                ...query,
                all: false
            })
        });
    }
    return rm;
}
exports.createRm = createRm;

},{"./utils.js":"66KGT"}],"aSasu":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var utils = require('./utils.js');
function createRmAll(client) {
    async function rmAll({ timeout , signal , headers , ...query }) {
        await client.post('pin/remote/rm', {
            timeout,
            signal,
            headers,
            searchParams: utils.encodeQuery({
                ...query,
                all: true
            })
        });
    }
    return rmAll;
}
exports.createRmAll = createRmAll;

},{"./utils.js":"66KGT"}],"aQURt":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var core = require('../../../lib/core.js');
var add = require('./add.js');
var ls = require('./ls.js');
var rm = require('./rm.js');
function createService(config) {
    const client = new core.Client(config);
    return {
        add: add.createAdd(client),
        ls: ls.createLs(client),
        rm: rm.createRm(client)
    };
}
exports.createService = createService;

},{"../../../lib/core.js":"g5LBC","./add.js":"5SKUE","./ls.js":"b3Gos","./rm.js":"eARp3"}],"5SKUE":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var toUrlSearchParams = require('../../../lib/to-url-search-params.js');
var utils = require('./utils.js');
function createAdd(client) {
    async function add(name, options) {
        const { endpoint , key , headers , timeout , signal  } = options;
        await client.post('pin/remote/service/add', {
            timeout,
            signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: [
                    name,
                    utils.encodeEndpoint(endpoint),
                    key
                ]
            }),
            headers
        });
    }
    return add;
}
exports.createAdd = createAdd;

},{"../../../lib/to-url-search-params.js":"5cN7U","./utils.js":"4Y8fj"}],"4Y8fj":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
function encodeEndpoint(url) {
    const href = String(url);
    if (href === 'undefined') throw Error('endpoint is required');
    return href[href.length - 1] === '/' ? href.slice(0, -1) : href;
}
function decodeRemoteService(json) {
    return {
        service: json.Service,
        endpoint: new URL(json.ApiEndpoint),
        ...json.Stat && {
            stat: decodeStat(json.Stat)
        }
    };
}
function decodeStat(json) {
    switch(json.Status){
        case 'valid':
            {
                const { Pinning , Pinned , Queued , Failed  } = json.PinCount;
                return {
                    status: 'valid',
                    pinCount: {
                        queued: Queued,
                        pinning: Pinning,
                        pinned: Pinned,
                        failed: Failed
                    }
                };
            }
        case 'invalid':
            return {
                status: 'invalid'
            };
        default:
            return {
                status: json.Status
            };
    }
}
exports.decodeRemoteService = decodeRemoteService;
exports.decodeStat = decodeStat;
exports.encodeEndpoint = encodeEndpoint;

},{}],"b3Gos":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var toUrlSearchParams = require('../../../lib/to-url-search-params.js');
var utils = require('./utils.js');
function createLs(client) {
    async function ls(options = {
    }) {
        const { stat , headers , timeout , signal  } = options;
        const response = await client.post('pin/remote/service/ls', {
            timeout,
            signal,
            headers,
            searchParams: stat === true ? toUrlSearchParams.toUrlSearchParams({
                stat
            }) : undefined
        });
        const { RemoteServices  } = await response.json();
        return RemoteServices.map(utils.decodeRemoteService);
    }
    return ls;
}
exports.createLs = createLs;

},{"../../../lib/to-url-search-params.js":"5cN7U","./utils.js":"4Y8fj"}],"eARp3":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var toUrlSearchParams = require('../../../lib/to-url-search-params.js');
function createRm(client) {
    async function rm(name, options = {
    }) {
        await client.post('pin/remote/service/rm', {
            signal: options.signal,
            headers: options.headers,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: name
            })
        });
    }
    return rm;
}
exports.createRm = createRm;

},{"../../../lib/to-url-search-params.js":"5cN7U"}],"cx44X":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var ls = require('./ls.js');
var peers = require('./peers.js');
var publish = require('./publish.js');
var subscribe = require('./subscribe.js');
var unsubscribe = require('./unsubscribe.js');
var subscriptionTracker = require('./subscription-tracker.js');
function createPubsub(config) {
    const subscriptionTracker$1 = new subscriptionTracker.SubscriptionTracker();
    return {
        ls: ls.createLs(config),
        peers: peers.createPeers(config),
        publish: publish.createPublish(config),
        subscribe: subscribe.createSubscribe(config, subscriptionTracker$1),
        unsubscribe: unsubscribe.createUnsubscribe(config, subscriptionTracker$1)
    };
}
exports.createPubsub = createPubsub;

},{"./ls.js":"c5FtE","./peers.js":"bjTGt","./publish.js":"51tLG","./subscribe.js":"eyuga","./unsubscribe.js":"4X63Q","./subscription-tracker.js":"6vvg9"}],"c5FtE":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createLs = configure.configure((api)=>{
    async function ls(options = {
    }) {
        const { Strings  } = await (await api.post('pubsub/ls', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams(options),
            headers: options.headers
        })).json();
        return Strings || [];
    }
    return ls;
});
exports.createLs = createLs;

},{"../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"bjTGt":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createPeers = configure.configure((api)=>{
    async function peers(topic, options = {
    }) {
        const res = await api.post('pubsub/peers', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: topic,
                ...options
            }),
            headers: options.headers
        });
        const { Strings  } = await res.json();
        return Strings || [];
    }
    return peers;
});
exports.createPeers = createPeers;

},{"../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"51tLG":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
var multipartRequest = require('ipfs-core-utils/multipart-request');
var abortSignal = require('../lib/abort-signal.js');
var nativeAbortController = require('native-abort-controller');
const createPublish = configure.configure((api)=>{
    async function publish(topic, data, options = {
    }) {
        const searchParams = toUrlSearchParams.toUrlSearchParams({
            arg: topic,
            ...options
        });
        const controller = new nativeAbortController.AbortController();
        const signal = abortSignal.abortSignal(controller.signal, options.signal);
        const res = await api.post('pubsub/pub', {
            signal,
            searchParams,
            ...await multipartRequest.multipartRequest(data, controller, options.headers)
        });
        await res.text();
    }
    return publish;
});
exports.createPublish = createPublish;

},{"../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U","ipfs-core-utils/multipart-request":"byZwt","../lib/abort-signal.js":"eZ7xd","native-abort-controller":"9z1Uk"}],"eyuga":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var fromString = require('uint8arrays/from-string');
var toString = require('uint8arrays/to-string');
var debug = require('debug');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
const log = debug__default['default']('ipfs-http-client:pubsub:subscribe');
const createSubscribe = (options1, subsTracker)=>{
    return configure.configure((api)=>{
        async function subscribe(topic, handler, options = {
        }) {
            options.signal = subsTracker.subscribe(topic, handler, options.signal);
            let done;
            let fail;
            const result = new Promise((resolve, reject)=>{
                done = resolve;
                fail = reject;
            });
            const ffWorkaround = setTimeout(()=>done()
            , 1000);
            api.post('pubsub/sub', {
                signal: options.signal,
                searchParams: toUrlSearchParams.toUrlSearchParams({
                    arg: topic,
                    ...options
                }),
                headers: options.headers
            }).catch((err)=>{
                subsTracker.unsubscribe(topic, handler);
                fail(err);
            }).then((response)=>{
                clearTimeout(ffWorkaround);
                if (!response) return;
                readMessages(response, {
                    onMessage: handler,
                    onEnd: ()=>subsTracker.unsubscribe(topic, handler)
                    ,
                    onError: options.onError
                });
                done();
            });
            return result;
        }
        return subscribe;
    })(options1);
};
async function readMessages(response, { onMessage , onEnd , onError  }) {
    onError = onError || log;
    try {
        for await (const msg of response.ndjson())try {
            if (!msg.from) continue;
            onMessage({
                from: toString.toString(fromString.fromString(msg.from, 'base64pad'), 'base58btc'),
                data: fromString.fromString(msg.data, 'base64pad'),
                seqno: fromString.fromString(msg.seqno, 'base64pad'),
                topicIDs: msg.topicIDs
            });
        } catch (err) {
            err.message = `Failed to parse pubsub message: ${err.message}`;
            onError(err, false, msg);
        }
    } catch (err) {
        if (!isAbortError(err)) onError(err, true);
    } finally{
        onEnd();
    }
}
const isAbortError = (error)=>{
    switch(error.type){
        case 'aborted':
            return true;
        case 'abort':
            return true;
        default:
            return error.name === 'AbortError';
    }
};
exports.createSubscribe = createSubscribe;

},{"uint8arrays/from-string":"lo45E","uint8arrays/to-string":"g3mCQ","debug":"lWlU4","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"4X63Q":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
const createUnsubscribe = (options, subsTracker)=>{
    async function unsubscribe(topic, handler) {
        subsTracker.unsubscribe(topic, handler);
    }
    return unsubscribe;
};
exports.createUnsubscribe = createUnsubscribe;

},{}],"6vvg9":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var nativeAbortController = require('native-abort-controller');
class SubscriptionTracker {
    constructor(){
        this._subs = new Map();
    }
    subscribe(topic, handler, signal) {
        const topicSubs = this._subs.get(topic) || [];
        if (topicSubs.find((s)=>s.handler === handler
        )) throw new Error(`Already subscribed to ${topic} with this handler`);
        const controller = new nativeAbortController.AbortController();
        this._subs.set(topic, [
            {
                handler,
                controller
            }
        ].concat(topicSubs));
        if (signal) signal.addEventListener('abort', ()=>this.unsubscribe(topic, handler)
        );
        return controller.signal;
    }
    unsubscribe(topic1, handler1) {
        const subs = this._subs.get(topic1) || [];
        let unsubs;
        if (handler1) {
            this._subs.set(topic1, subs.filter((s)=>s.handler !== handler1
            ));
            unsubs = subs.filter((s)=>s.handler === handler1
            );
        } else {
            this._subs.set(topic1, []);
            unsubs = subs;
        }
        if (!(this._subs.get(topic1) || []).length) this._subs.delete(topic1);
        unsubs.forEach((s)=>s.controller.abort()
        );
    }
}
exports.SubscriptionTracker = SubscriptionTracker;

},{"native-abort-controller":"9z1Uk"}],"5AJ5a":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
var objectToCamel = require('../lib/object-to-camel.js');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
var local = require('./local.js');
const createRefs = configure.configure((api, opts)=>{
    const refs = async function*(args, options = {
    }) {
        const argsArr = Array.isArray(args) ? args : [
            args
        ];
        const res = await api.post('refs', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: argsArr.map((arg)=>`${arg instanceof Uint8Array ? cid.CID.decode(arg) : arg}`
                ),
                ...options
            }),
            headers: options.headers,
            transform: objectToCamel.objectToCamel
        });
        yield* res.ndjson();
    };
    return Object.assign(refs, {
        local: local.createLocal(opts)
    });
});
exports.createRefs = createRefs;

},{"multiformats/cid":"fJJnW","../lib/object-to-camel.js":"5IyF9","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U","./local.js":"1BlCg"}],"1BlCg":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var objectToCamel = require('../lib/object-to-camel.js');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createLocal = configure.configure((api)=>{
    async function* refsLocal(options = {
    }) {
        const res = await api.post('refs/local', {
            signal: options.signal,
            transform: objectToCamel.objectToCamel,
            searchParams: toUrlSearchParams.toUrlSearchParams(options),
            headers: options.headers
        });
        yield* res.ndjson();
    }
    return refsLocal;
});
exports.createLocal = createLocal;

},{"../lib/object-to-camel.js":"5IyF9","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"iTArq":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var gc = require('./gc.js');
var stat = require('./stat.js');
var version = require('./version.js');
function createRepo(config) {
    return {
        gc: gc.createGc(config),
        stat: stat.createStat(config),
        version: version.createVersion(config)
    };
}
exports.createRepo = createRepo;

},{"./gc.js":"8p7wY","./stat.js":"2oxBg","./version.js":"cYcwa"}],"8p7wY":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createGc = configure.configure((api)=>{
    async function* gc(options = {
    }) {
        const res1 = await api.post('repo/gc', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams(options),
            headers: options.headers,
            transform: (res)=>{
                return {
                    err: res.Error ? new Error(res.Error) : null,
                    cid: (res.Key || {
                    })['/'] ? cid.CID.parse(res.Key['/']) : null
                };
            }
        });
        yield* res1.ndjson();
    }
    return gc;
});
exports.createGc = createGc;

},{"multiformats/cid":"fJJnW","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"2oxBg":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createStat = configure.configure((api)=>{
    async function stat(options = {
    }) {
        const res = await api.post('repo/stat', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams(options),
            headers: options.headers
        });
        const data = await res.json();
        return {
            numObjects: BigInt(data.NumObjects),
            repoSize: BigInt(data.RepoSize),
            repoPath: data.RepoPath,
            version: data.Version,
            storageMax: BigInt(data.StorageMax)
        };
    }
    return stat;
});
exports.createStat = createStat;

},{"../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"cYcwa":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createVersion = configure.configure((api)=>{
    async function version(options = {
    }) {
        const res = await (await api.post('repo/version', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams(options),
            headers: options.headers
        })).json();
        return res.Version;
    }
    return version;
});
exports.createVersion = createVersion;

},{"../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"jNimi":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var stat = require('../bitswap/stat.js');
var stat$1 = require('../repo/stat.js');
var bw = require('./bw.js');
function createStats(config) {
    return {
        bitswap: stat.createStat(config),
        repo: stat$1.createStat(config),
        bw: bw.createBw(config)
    };
}
exports.createStats = createStats;

},{"../bitswap/stat.js":"jutRZ","../repo/stat.js":"2oxBg","./bw.js":"hOdfI"}],"hOdfI":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createBw = configure.configure((api)=>{
    async function* bw(options = {
    }) {
        const res = await api.post('stats/bw', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams(options),
            headers: options.headers,
            transform: (stats)=>({
                    totalIn: BigInt(stats.TotalIn),
                    totalOut: BigInt(stats.TotalOut),
                    rateIn: parseFloat(stats.RateIn),
                    rateOut: parseFloat(stats.RateOut)
                })
        });
        yield* res.ndjson();
    }
    return bw;
});
exports.createBw = createBw;

},{"../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"lvOze":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var addrs = require('./addrs.js');
var connect = require('./connect.js');
var disconnect = require('./disconnect.js');
var localAddrs = require('./local-addrs.js');
var peers = require('./peers.js');
function createSwarm(config) {
    return {
        addrs: addrs.createAddrs(config),
        connect: connect.createConnect(config),
        disconnect: disconnect.createDisconnect(config),
        localAddrs: localAddrs.createLocalAddrs(config),
        peers: peers.createPeers(config)
    };
}
exports.createSwarm = createSwarm;

},{"./addrs.js":"laFWa","./connect.js":"drlWf","./disconnect.js":"7KT2F","./local-addrs.js":"15Omc","./peers.js":"kWQIl"}],"laFWa":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var multiaddr = require('multiaddr');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createAddrs = configure.configure((api)=>{
    async function addrs(options = {
    }) {
        const res = await api.post('swarm/addrs', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams(options),
            headers: options.headers
        });
        const { Addrs  } = await res.json();
        return Object.keys(Addrs).map((id)=>({
                id,
                addrs: (Addrs[id] || []).map((a)=>new multiaddr.Multiaddr(a)
                )
            })
        );
    }
    return addrs;
});
exports.createAddrs = createAddrs;

},{"multiaddr":"kOPrF","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"drlWf":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createConnect = configure.configure((api)=>{
    async function connect(addr, options = {
    }) {
        const res = await api.post('swarm/connect', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: addr,
                ...options
            }),
            headers: options.headers
        });
        const { Strings  } = await res.json();
        return Strings || [];
    }
    return connect;
});
exports.createConnect = createConnect;

},{"../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"7KT2F":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createDisconnect = configure.configure((api)=>{
    async function disconnect(addr, options = {
    }) {
        const res = await api.post('swarm/disconnect', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: addr,
                ...options
            }),
            headers: options.headers
        });
        const { Strings  } = await res.json();
        return Strings || [];
    }
    return disconnect;
});
exports.createDisconnect = createDisconnect;

},{"../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"15Omc":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var multiaddr = require('multiaddr');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createLocalAddrs = configure.configure((api)=>{
    async function localAddrs(options = {
    }) {
        const res = await api.post('swarm/addrs/local', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams(options),
            headers: options.headers
        });
        const { Strings  } = await res.json();
        return (Strings || []).map((a)=>new multiaddr.Multiaddr(a)
        );
    }
    return localAddrs;
});
exports.createLocalAddrs = createLocalAddrs;

},{"multiaddr":"kOPrF","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"kWQIl":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var multiaddr = require('multiaddr');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
const createPeers = configure.configure((api)=>{
    async function peers(options = {
    }) {
        const res = await api.post('swarm/peers', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams(options),
            headers: options.headers
        });
        const { Peers  } = await res.json();
        return (Peers || []).map((peer)=>{
            return {
                addr: new multiaddr.Multiaddr(peer.Addr),
                peer: peer.Peer,
                muxer: peer.Muxer,
                latency: peer.Latency,
                streams: peer.Streams,
                direction: peer.Direction == null ? undefined : peer.Direction === 0 ? 'inbound' : 'outbound'
            };
        });
    }
    return peers;
});
exports.createPeers = createPeers;

},{"multiaddr":"kOPrF","../lib/configure.js":"eVYJh","../lib/to-url-search-params.js":"5cN7U"}],"gSIKT":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var addAll = require('./add-all.js');
var last = require('it-last');
var configure = require('./lib/configure.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var last__default = /*#__PURE__*/ _interopDefaultLegacy(last);
function createAdd(options1) {
    const all = addAll.createAddAll(options1);
    return configure.configure(()=>{
        async function add(input, options = {
        }) {
            return await last__default['default'](all(input, options));
        }
        return add;
    })(options1);
}
exports.createAdd = createAdd;

},{"./add-all.js":"6uXPs","it-last":"7VTHF","./lib/configure.js":"eVYJh"}],"6uXPs":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
var objectToCamel = require('./lib/object-to-camel.js');
var configure = require('./lib/configure.js');
var multipartRequest = require('ipfs-core-utils/multipart-request');
var toUrlSearchParams = require('./lib/to-url-search-params.js');
var abortSignal = require('./lib/abort-signal.js');
var nativeAbortController = require('native-abort-controller');
const createAddAll = configure.configure((api)=>{
    async function* addAll(source, options = {
    }) {
        const controller = new nativeAbortController.AbortController();
        const signal = abortSignal.abortSignal(controller.signal, options.signal);
        const { headers , body , total , parts  } = await multipartRequest.multipartRequest(source, controller, options.headers);
        const [progressFn, onUploadProgress] = typeof options.progress === 'function' ? createProgressHandler(total, parts, options.progress) : [
            undefined,
            undefined
        ];
        const res = await api.post('add', {
            searchParams: toUrlSearchParams.toUrlSearchParams({
                'stream-channels': true,
                ...options,
                progress: Boolean(progressFn)
            }),
            onUploadProgress,
            signal,
            headers,
            body
        });
        for await (let file of res.ndjson()){
            file = objectToCamel.objectToCamel(file);
            if (file.hash !== undefined) yield toCoreInterface(file);
            else if (progressFn) progressFn(file.bytes || 0, file.name);
        }
    }
    return addAll;
});
const createProgressHandler = (total, parts, progress)=>parts ? [
        undefined,
        createOnUploadProgress(total, parts, progress)
    ] : [
        progress,
        undefined
    ]
;
const createOnUploadProgress = (size, parts, progress)=>{
    let index = 0;
    const count = parts.length;
    return ({ loaded , total  })=>{
        const position = Math.floor(loaded / total * size);
        while(index < count){
            const { start , end , name  } = parts[index];
            if (position < end) {
                progress(position - start, name);
                break;
            } else {
                progress(end - start, name);
                index += 1;
            }
        }
    };
};
function toCoreInterface({ name , hash , size , mode , mtime , mtimeNsecs  }) {
    const output = {
        path: name,
        cid: cid.CID.parse(hash),
        size: parseInt(size)
    };
    if (mode != null) output.mode = parseInt(mode, 8);
    if (mtime != null) output.mtime = {
        secs: mtime,
        nsecs: mtimeNsecs || 0
    };
    return output;
}
exports.createAddAll = createAddAll;

},{"multiformats/cid":"fJJnW","./lib/object-to-camel.js":"5IyF9","./lib/configure.js":"eVYJh","ipfs-core-utils/multipart-request":"byZwt","./lib/to-url-search-params.js":"5cN7U","./lib/abort-signal.js":"eZ7xd","native-abort-controller":"9z1Uk"}],"h2iQz":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('./lib/configure.js');
var toUrlSearchParams = require('./lib/to-url-search-params.js');
const createCat = configure.configure((api)=>{
    async function* cat(path, options = {
    }) {
        const res = await api.post('cat', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: path.toString(),
                ...options
            }),
            headers: options.headers
        });
        yield* res.iterator();
    }
    return cat;
});
exports.createCat = createCat;

},{"./lib/configure.js":"eVYJh","./lib/to-url-search-params.js":"5cN7U"}],"1Y0eG":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('./lib/configure.js');
var toUrlSearchParams = require('./lib/to-url-search-params.js');
const createCommands = configure.configure((api)=>{
    const commands = async (options = {
    })=>{
        const res = await api.post('commands', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams(options),
            headers: options.headers
        });
        return res.json();
    };
    return commands;
});
exports.createCommands = createCommands;

},{"./lib/configure.js":"eVYJh","./lib/to-url-search-params.js":"5cN7U"}],"aEE8e":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('./lib/configure.js');
var toUrlSearchParams = require('./lib/to-url-search-params.js');
const createDns = configure.configure((api)=>{
    const dns = async (domain, options = {
    })=>{
        const res = await api.post('dns', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: domain,
                ...options
            }),
            headers: options.headers
        });
        const data = await res.json();
        return data.Path;
    };
    return dns;
});
exports.createDns = createDns;

},{"./lib/configure.js":"eVYJh","./lib/to-url-search-params.js":"5cN7U"}],"4iqJl":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('./lib/configure.js');
const createGetEndpointConfig = configure.configure((api)=>{
    return ()=>{
        const url = new URL(api.opts.base || '');
        return {
            host: url.hostname,
            port: url.port,
            protocol: url.protocol,
            pathname: url.pathname,
            'api-path': url.pathname
        };
    };
});
exports.createGetEndpointConfig = createGetEndpointConfig;

},{"./lib/configure.js":"eVYJh"}],"2d7NW":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
var configure = require('./lib/configure.js');
var toUrlSearchParams = require('./lib/to-url-search-params.js');
const createGet = configure.configure((api)=>{
    async function* get(path, options = {
    }) {
        const opts = {
            arg: `${path instanceof Uint8Array ? cid.CID.decode(path) : path}`,
            ...options
        };
        if (opts.compressionLevel) {
            opts['compression-level'] = opts.compressionLevel;
            delete opts.compressionLevel;
        }
        const res = await api.post('get', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams(opts),
            headers: options.headers
        });
        yield* res.iterator();
    }
    return get;
});
exports.createGet = createGet;

},{"multiformats/cid":"fJJnW","./lib/configure.js":"eVYJh","./lib/to-url-search-params.js":"5cN7U"}],"4v7TH":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var objectToCamel = require('./lib/object-to-camel.js');
var multiaddr = require('multiaddr');
var configure = require('./lib/configure.js');
var toUrlSearchParams = require('./lib/to-url-search-params.js');
const createId = configure.configure((api)=>{
    async function id(options = {
    }) {
        const res = await api.post('id', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: options.peerId ? options.peerId.toString() : undefined,
                ...options
            }),
            headers: options.headers
        });
        const data = await res.json();
        const output = {
            ...objectToCamel.objectToCamel(data)
        };
        if (output.addresses) output.addresses = output.addresses.map((ma)=>new multiaddr.Multiaddr(ma)
        );
        return output;
    }
    return id;
});
exports.createId = createId;

},{"./lib/object-to-camel.js":"5IyF9","multiaddr":"kOPrF","./lib/configure.js":"eVYJh","./lib/to-url-search-params.js":"5cN7U"}],"ilvG8":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var id = require('./id.js');
const createIsOnline = (options1)=>{
    const id$1 = id.createId(options1);
    async function isOnline(options = {
    }) {
        const res = await id$1(options);
        return Boolean(res && res.addresses && res.addresses.length);
    }
    return isOnline;
};
exports.createIsOnline = createIsOnline;

},{"./id.js":"4v7TH"}],"hOWyo":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid = require('multiformats/cid');
var configure = require('./lib/configure.js');
var toUrlSearchParams = require('./lib/to-url-search-params.js');
var stat = require('./files/stat.js');
const createLs = configure.configure((api, opts)=>{
    async function* ls(path, options = {
    }) {
        const pathStr = `${path instanceof Uint8Array ? cid.CID.decode(path) : path}`;
        async function mapLink(link) {
            let hash = link.Hash;
            if (hash.includes('/')) {
                const ipfsPath = hash.startsWith('/ipfs/') ? hash : `/ipfs/${hash}`;
                const stats = await stat.createStat(opts)(ipfsPath);
                hash = stats.cid;
            } else hash = cid.CID.parse(hash);
            const entry = {
                name: link.Name,
                path: pathStr + (link.Name ? `/${link.Name}` : ''),
                size: link.Size,
                cid: hash,
                type: typeOf(link)
            };
            if (link.Mode) entry.mode = parseInt(link.Mode, 8);
            if (link.Mtime !== undefined && link.Mtime !== null) {
                entry.mtime = {
                    secs: link.Mtime
                };
                if (link.MtimeNsecs !== undefined && link.MtimeNsecs !== null) entry.mtime.nsecs = link.MtimeNsecs;
            }
            return entry;
        }
        const res = await api.post('ls', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: pathStr,
                ...options
            }),
            headers: options.headers
        });
        for await (let result of res.ndjson()){
            result = result.Objects;
            if (!result) throw new Error('expected .Objects in results');
            result = result[0];
            if (!result) throw new Error('expected one array in results.Objects');
            const links = result.Links;
            if (!Array.isArray(links)) throw new Error('expected one array in results.Objects[0].Links');
            if (!links.length) {
                yield mapLink(result);
                return;
            }
            yield* links.map(mapLink);
        }
    }
    return ls;
});
function typeOf(link) {
    switch(link.Type){
        case 1:
        case 5:
            return 'dir';
        case 2:
            return 'file';
        default:
            return 'file';
    }
}
exports.createLs = createLs;

},{"multiformats/cid":"fJJnW","./lib/configure.js":"eVYJh","./lib/to-url-search-params.js":"5cN7U","./files/stat.js":"5sduk"}],"eeUuW":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var objectToCamel = require('./lib/object-to-camel.js');
var configure = require('./lib/configure.js');
var toUrlSearchParams = require('./lib/to-url-search-params.js');
const createMount = configure.configure((api)=>{
    async function mount(options = {
    }) {
        const res = await api.post('dns', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams(options),
            headers: options.headers
        });
        return objectToCamel.objectToCamel(await res.json());
    }
    return mount;
});
exports.createMount = createMount;

},{"./lib/object-to-camel.js":"5IyF9","./lib/configure.js":"eVYJh","./lib/to-url-search-params.js":"5cN7U"}],"93a94":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var objectToCamel = require('./lib/object-to-camel.js');
var configure = require('./lib/configure.js');
var toUrlSearchParams = require('./lib/to-url-search-params.js');
const createPing = configure.configure((api)=>{
    async function* ping(peerId, options = {
    }) {
        const res = await api.post('ping', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: `${peerId}`,
                ...options
            }),
            headers: options.headers,
            transform: objectToCamel.objectToCamel
        });
        yield* res.ndjson();
    }
    return ping;
});
exports.createPing = createPing;

},{"./lib/object-to-camel.js":"5IyF9","./lib/configure.js":"eVYJh","./lib/to-url-search-params.js":"5cN7U"}],"kN9C4":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('./lib/configure.js');
var toUrlSearchParams = require('./lib/to-url-search-params.js');
const createResolve = configure.configure((api)=>{
    async function resolve(path, options = {
    }) {
        const res = await api.post('resolve', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams({
                arg: path,
                ...options
            }),
            headers: options.headers
        });
        const { Path  } = await res.json();
        return Path;
    }
    return resolve;
});
exports.createResolve = createResolve;

},{"./lib/configure.js":"eVYJh","./lib/to-url-search-params.js":"5cN7U"}],"9OnII":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('./lib/configure.js');
var errCode = require('err-code');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
const createStart = configure.configure((api)=>{
    const start = async (options = {
    })=>{
        throw errCode__default['default'](new Error('Not implemented'), 'ERR_NOT_IMPLEMENTED');
    };
    return start;
});
exports.createStart = createStart;

},{"./lib/configure.js":"eVYJh","err-code":"eQvyh"}],"cBDOX":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var configure = require('./lib/configure.js');
var toUrlSearchParams = require('./lib/to-url-search-params.js');
const createStop = configure.configure((api)=>{
    async function stop(options = {
    }) {
        const res = await api.post('shutdown', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams(options),
            headers: options.headers
        });
        await res.text();
    }
    return stop;
});
exports.createStop = createStop;

},{"./lib/configure.js":"eVYJh","./lib/to-url-search-params.js":"5cN7U"}],"9pYnJ":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var objectToCamel = require('./lib/object-to-camel.js');
var configure = require('./lib/configure.js');
var toUrlSearchParams = require('./lib/to-url-search-params.js');
const createVersion = configure.configure((api)=>{
    async function version(options = {
    }) {
        const res = await api.post('version', {
            signal: options.signal,
            searchParams: toUrlSearchParams.toUrlSearchParams(options),
            headers: options.headers
        });
        return {
            ...objectToCamel.objectToCamel(await res.json()),
            'ipfs-http-client': '1.0.0'
        };
    }
    return version;
});
exports.createVersion = createVersion;

},{"./lib/object-to-camel.js":"5IyF9","./lib/configure.js":"eVYJh","./lib/to-url-search-params.js":"5cN7U"}],"hdaYP":[function(require,module,exports) {
'use strict';
const HTTP = require('../http');
/**
 *
 * @param {string} url
 * @param {import("../types").HTTPOptions} [options]
 * @returns {{ path: string; content?: AsyncIterable<Uint8Array> }}
 */ const urlSource = (url, options)=>{
    return {
        path: decodeURIComponent(new URL(url).pathname.split('/').pop() || ''),
        content: readURLContent(url, options)
    };
};
/**
 *
 * @param {string} url
 * @param {import("../types").HTTPOptions} [options]
 * @returns {AsyncIterable<Uint8Array>}
 */ async function* readURLContent(url, options) {
    const http = new HTTP();
    const response = await http.get(url, options);
    yield* response.iterator();
}
module.exports = urlSource;

},{"../http":"2w2r7"}],"bANS0":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var WS = require('libp2p-websockets');
var WebRTCStar = require('libp2p-webrtc-star');
var Multiplex = require('libp2p-mplex');
var libp2pNoise = require('@chainsafe/libp2p-noise');
var KadDHT = require('libp2p-kad-dht');
var GossipSub = require('libp2p-gossipsub');
var ipns = require('./utils/ipns.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var WS__default = /*#__PURE__*/ _interopDefaultLegacy(WS);
var WebRTCStar__default = /*#__PURE__*/ _interopDefaultLegacy(WebRTCStar);
var Multiplex__default = /*#__PURE__*/ _interopDefaultLegacy(Multiplex);
var KadDHT__default = /*#__PURE__*/ _interopDefaultLegacy(KadDHT);
var GossipSub__default = /*#__PURE__*/ _interopDefaultLegacy(GossipSub);
function libp2pConfig() {
    const options = {
        dialer: {
            maxParallelDials: 150,
            maxDialsPerPeer: 4,
            dialTimeout: 10000
        },
        modules: {
            transport: [
                WS__default["default"],
                WebRTCStar__default["default"]
            ],
            streamMuxer: [
                Multiplex__default["default"]
            ],
            connEncryption: [
                libp2pNoise.NOISE
            ],
            peerDiscovery: [],
            dht: KadDHT__default["default"],
            pubsub: GossipSub__default["default"]
        },
        config: {
            peerDiscovery: {
                autoDial: true,
                bootstrap: {
                    enabled: true
                },
                webRTCStar: {
                    enabled: true
                }
            },
            dht: {
                kBucketSize: 20,
                enabled: false,
                clientMode: true,
                randomWalk: {
                    enabled: false
                },
                validators: {
                    ipns: ipns.validator
                },
                selectors: {
                    ipns: ipns.selector
                }
            },
            pubsub: {
                enabled: true,
                emitSelf: true
            },
            nat: {
                enabled: false
            }
        },
        metrics: {
            enabled: true
        },
        peerStore: {
            persistence: true,
            threshold: 1
        }
    };
    return options;
}
exports.libp2pConfig = libp2pConfig;

},{"libp2p-websockets":"i2v8y","libp2p-webrtc-star":"ceZpI","libp2p-mplex":"lXsA5","@chainsafe/libp2p-noise":"1tH8u","libp2p-kad-dht":"eg2db","libp2p-gossipsub":"4HG11","./utils/ipns.js":"1OT9O"}],"i2v8y":[function(require,module,exports) {
'use strict';
const connect = require('it-ws/client');
const withIs = require('class-is');
const toUri = require('multiaddr-to-uri');
const { AbortError  } = require('abortable-iterator');
const pDefer = require('p-defer');
const debug = require('debug');
const log = debug('libp2p:websockets');
log.error = debug('libp2p:websockets:error');
const env = require('ipfs-utils/src/env');
const createListener = require('./listener');
const toConnection = require('./socket-to-conn');
const filters = require('./filters');
/**
 * @typedef {import('multiaddr').Multiaddr} Multiaddr
 */ /**
 * @class WebSockets
 */ class WebSockets {
    /**
   * @class
   * @param {object} options
   * @param {Upgrader} options.upgrader
   * @param {(multiaddrs: Array<Multiaddr>) => Array<Multiaddr>} options.filter - override transport addresses filter
   */ constructor({ upgrader , filter  }){
        if (!upgrader) throw new Error('An upgrader must be provided. See https://github.com/libp2p/interface-transport#upgrader.');
        this._upgrader = upgrader;
        this._filter = filter;
    }
    /**
   * @async
   * @param {Multiaddr} ma
   * @param {object} [options]
   * @param {AbortSignal} [options.signal] - Used to abort dial requests
   * @returns {Connection} An upgraded Connection
   */ async dial(ma, options = {
    }) {
        log('dialing %s', ma);
        const socket = await this._connect(ma, options);
        const maConn = toConnection(socket, {
            remoteAddr: ma,
            signal: options.signal
        });
        log('new outbound connection %s', maConn.remoteAddr);
        const conn = await this._upgrader.upgradeOutbound(maConn);
        log('outbound connection %s upgraded', maConn.remoteAddr);
        return conn;
    }
    /**
   * @private
   * @param {Multiaddr} ma
   * @param {object} [options]
   * @param {AbortSignal} [options.signal] - Used to abort dial requests
   * @returns {Promise<WebSocket>} Resolves a extended duplex iterable on top of a WebSocket
   */ async _connect(ma1, options1 = {
    }) {
        if (options1.signal && options1.signal.aborted) throw new AbortError();
        const cOpts = ma1.toOptions();
        log('dialing %s:%s', cOpts.host, cOpts.port);
        const errorPromise = pDefer();
        const errfn = (err)=>{
            const msg = `connection error: ${err.message}`;
            log.error(msg);
            errorPromise.reject(err);
        };
        const rawSocket = connect(toUri(ma1), Object.assign({
            binary: true
        }, options1));
        if (rawSocket.socket.on) rawSocket.socket.on('error', errfn);
        else rawSocket.socket.onerror = errfn;
        if (!options1.signal) {
            await Promise.race([
                rawSocket.connected(),
                errorPromise.promise
            ]);
            log('connected %s', ma1);
            return rawSocket;
        }
        // Allow abort via signal during connect
        let onAbort;
        const abort = new Promise((resolve, reject)=>{
            onAbort = ()=>{
                reject(new AbortError());
                // FIXME: https://github.com/libp2p/js-libp2p-websockets/issues/121
                setTimeout(()=>{
                    rawSocket.close();
                });
            };
            // Already aborted?
            if (options1.signal.aborted) return onAbort();
            options1.signal.addEventListener('abort', onAbort);
        });
        try {
            await Promise.race([
                abort,
                errorPromise.promise,
                rawSocket.connected()
            ]);
        } finally{
            options1.signal.removeEventListener('abort', onAbort);
        }
        log('connected %s', ma1);
        return rawSocket;
    }
    /**
   * Creates a Websockets listener. The provided `handler` function will be called
   * anytime a new incoming Connection has been successfully upgraded via
   * `upgrader.upgradeInbound`.
   *
   * @param {object} [options]
   * @param {http.Server} [options.server] - A pre-created Node.js HTTP/S server.
   * @param {function (Connection)} handler
   * @returns {Listener} A Websockets listener
   */ createListener(options2 = {
    }, handler) {
        if (typeof options2 === 'function') {
            handler = options2;
            options2 = {
            };
        }
        return createListener({
            handler,
            upgrader: this._upgrader
        }, options2);
    }
    /**
   * Takes a list of `Multiaddr`s and returns only valid Websockets addresses.
   * By default, in a browser environment only DNS+WSS multiaddr is accepted,
   * while in a Node.js environment DNS+{WS, WSS} multiaddrs are accepted.
   *
   * @param {Multiaddr[]} multiaddrs
   * @returns {Multiaddr[]} Valid Websockets multiaddrs
   */ filter(multiaddrs) {
        multiaddrs = Array.isArray(multiaddrs) ? multiaddrs : [
            multiaddrs
        ];
        if (this._filter) return this._filter(multiaddrs);
        // Browser
        if (env.isBrowser || env.isWebWorker) return filters.dnsWss(multiaddrs);
        return filters.all(multiaddrs);
    }
}
module.exports = withIs(WebSockets, {
    className: 'WebSockets',
    symbolName: '@libp2p/js-libp2p-websockets/websockets'
});

},{"it-ws/client":"25asf","class-is":"eROOZ","multiaddr-to-uri":"94qb6","abortable-iterator":"3n79Y","p-defer":"gZqcC","debug":"lWlU4","ipfs-utils/src/env":"42nOp","./listener":"aCIAQ","./socket-to-conn":"2i3x2","./filters":"ffciF"}],"25asf":[function(require,module,exports) {
'use strict';
// load websocket library if we are not in the browser
var WebSocket = require('./web-socket');
var duplex = require('./duplex');
var wsurl = require('./ws-url');
module.exports = function(addr, opts = {
}) {
    const location = typeof window === 'undefined' ? {
    } : window.location;
    const url = wsurl(addr, location);
    const socket = new WebSocket(url, opts.websocket);
    const stream = duplex(socket, opts);
    stream.remoteAddress = url;
    stream.close = ()=>new Promise((resolve, reject)=>{
            socket.addEventListener('close', resolve);
            socket.close();
        })
    ;
    stream.destroy = ()=>{
        if (socket.terminate) socket.terminate();
        else socket.close();
    };
    stream.socket = socket;
    return stream;
};
module.exports.connect = module.exports;

},{"./web-socket":"5ocUT","./duplex":"65zLf","./ws-url":"kd3VB"}],"5ocUT":[function(require,module,exports) {
/* eslint-env browser */ module.exports = typeof WebSocket === 'undefined' ? require('ws') : WebSocket;

},{"ws":"joWnX"}],"65zLf":[function(require,module,exports) {
const source = require('./source');
const sink = require('./sink');
module.exports = (socket, options)=>{
    options = options || {
    };
    if (options.binaryType) socket.binaryType = options.binaryType;
    else if (options.binary) socket.binaryType = 'arraybuffer';
    const duplex = {
        sink: sink(socket, options),
        source: source(socket, options),
        connected: ()=>duplex.source.connected()
    };
    return duplex;
};

},{"./source":"azmey","./sink":"3pjlV"}],"azmey":[function(require,module,exports) {
const { Buffer  } = require('buffer');
const { EventIterator  } = require('event-iterator');
// copied from github.com/feross/buffer
// Some ArrayBuffers are not passing the instanceof check, so we need to do a bit more work :(
function isArrayBuffer(obj) {
    return obj instanceof ArrayBuffer || obj != null && obj.constructor != null && obj.constructor.name === 'ArrayBuffer' && typeof obj.byteLength === 'number';
}
module.exports = (socket)=>{
    const removeListener = socket.removeEventListener || socket.removeListener;
    const source = async function*() {
        const messages = new EventIterator(({ push , stop , fail  })=>{
            socket.addEventListener('message', push);
            socket.addEventListener('error', fail);
            socket.addEventListener('close', stop);
            return ()=>{
                removeListener.call(socket, 'message', push);
                removeListener.call(socket, 'error', fail);
                removeListener.call(socket, 'close', stop);
            };
        }, {
            highWaterMark: Infinity
        });
        for await (const { data  } of messages)yield isArrayBuffer(data) ? Buffer.from(data) : data;
    }();
    let connected = socket.readyState === 1;
    let connError;
    socket.addEventListener('open', ()=>{
        connected = true;
        connError = null;
    });
    socket.addEventListener('close', ()=>{
        connected = false;
        connError = null;
    });
    socket.addEventListener('error', (err)=>{
        if (!connected) connError = err;
    });
    source.connected = ()=>new Promise((resolve, reject)=>{
            if (connected) return resolve();
            if (connError) return reject(connError);
            const cleanUp = (cont)=>{
                removeListener.call(socket, 'open', onOpen);
                removeListener.call(socket, 'error', onError);
                cont();
            };
            const onOpen = ()=>cleanUp(resolve)
            ;
            const onError = (err)=>cleanUp(()=>reject(err)
                )
            ;
            socket.addEventListener('open', onOpen);
            socket.addEventListener('error', onError);
        })
    ;
    return source;
};

},{"buffer":"eKea5","event-iterator":"hFxHJ"}],"hFxHJ":[function(require,module,exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
const event_iterator_1 = require("./event-iterator");
exports.EventIterator = event_iterator_1.EventIterator;
function subscribe(event, options, evOptions) {
    return new event_iterator_1.EventIterator(({ push  })=>{
        this.addEventListener(event, push, options);
        return ()=>this.removeEventListener(event, push, options)
        ;
    }, evOptions);
}
exports.subscribe = subscribe;
exports.default = event_iterator_1.EventIterator;

},{"./event-iterator":"b7mZp"}],"b7mZp":[function(require,module,exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
class EventQueue {
    constructor(){
        this.pullQueue = [];
        this.pushQueue = [];
        this.eventHandlers = {
        };
        this.isPaused = false;
        this.isStopped = false;
    }
    push(value1) {
        if (this.isStopped) return;
        const resolution = {
            value: value1,
            done: false
        };
        if (this.pullQueue.length) {
            const placeholder = this.pullQueue.shift();
            if (placeholder) placeholder.resolve(resolution);
        } else {
            this.pushQueue.push(Promise.resolve(resolution));
            if (this.highWaterMark !== undefined && this.pushQueue.length >= this.highWaterMark && !this.isPaused) {
                this.isPaused = true;
                if (this.eventHandlers.highWater) this.eventHandlers.highWater();
                else if (console) console.warn(`EventIterator queue reached ${this.pushQueue.length} items`);
            }
        }
    }
    stop() {
        if (this.isStopped) return;
        this.isStopped = true;
        this.remove();
        for (const placeholder of this.pullQueue)placeholder.resolve({
            value: undefined,
            done: true
        });
        this.pullQueue.length = 0;
    }
    fail(error1) {
        if (this.isStopped) return;
        this.isStopped = true;
        this.remove();
        if (this.pullQueue.length) {
            for (const placeholder of this.pullQueue)placeholder.reject(error1);
            this.pullQueue.length = 0;
        } else {
            const rejection = Promise.reject(error1);
            /* Attach error handler to avoid leaking an unhandled promise rejection. */ rejection.catch(()=>{
            });
            this.pushQueue.push(rejection);
        }
    }
    remove() {
        Promise.resolve().then(()=>{
            if (this.removeCallback) this.removeCallback();
        });
    }
    [Symbol.asyncIterator]() {
        return {
            next: (value)=>{
                const result = this.pushQueue.shift();
                if (result) {
                    if (this.lowWaterMark !== undefined && this.pushQueue.length <= this.lowWaterMark && this.isPaused) {
                        this.isPaused = false;
                        if (this.eventHandlers.lowWater) this.eventHandlers.lowWater();
                    }
                    return result;
                } else if (this.isStopped) return Promise.resolve({
                    value: undefined,
                    done: true
                });
                else return new Promise((resolve, reject)=>{
                    this.pullQueue.push({
                        resolve,
                        reject
                    });
                });
            },
            return: ()=>{
                this.isStopped = true;
                this.pushQueue.length = 0;
                this.remove();
                return Promise.resolve({
                    value: undefined,
                    done: true
                });
            }
        };
    }
}
class EventIterator {
    constructor(listen, { highWaterMark =100 , lowWaterMark =1  } = {
    }){
        const queue = new EventQueue();
        queue.highWaterMark = highWaterMark;
        queue.lowWaterMark = lowWaterMark;
        queue.removeCallback = listen({
            push: (value)=>queue.push(value)
            ,
            stop: ()=>queue.stop()
            ,
            fail: (error)=>queue.fail(error)
            ,
            on: (event, fn)=>{
                queue.eventHandlers[event] = fn;
            }
        }) || (()=>{
        });
        this[Symbol.asyncIterator] = ()=>queue[Symbol.asyncIterator]()
        ;
        Object.freeze(this);
    }
}
exports.EventIterator = EventIterator;
exports.default = EventIterator;

},{}],"3pjlV":[function(require,module,exports) {
const ready = require('./ready');
module.exports = (socket, options)=>{
    options = options || {
    };
    options.closeOnEnd = options.closeOnEnd !== false;
    return async (source)=>{
        for await (const data of source){
            try {
                await ready(socket);
            } catch (err) {
                if (err.message === 'socket closed') break;
                throw err;
            }
            socket.send(data);
        }
        if (options.closeOnEnd && socket.readyState <= 1) return new Promise((resolve, reject)=>{
            socket.addEventListener('close', (event)=>{
                if (event.wasClean || event.code === 1006) resolve();
                else {
                    const err = Object.assign(new Error('ws error'), {
                        event
                    });
                    reject(err);
                }
            });
            setTimeout(()=>socket.close()
            );
        });
    };
};

},{"./ready":"TbFpA"}],"TbFpA":[function(require,module,exports) {
module.exports = async (socket)=>{
    // if the socket is closing or closed, return end
    if (socket.readyState >= 2) throw new Error('socket closed');
    // if open, return
    if (socket.readyState === 1) return;
    return new Promise((resolve, reject)=>{
        const remove = socket && (socket.removeEventListener || socket.removeListener);
        function cleanup() {
            if (typeof remove === 'function') {
                remove.call(socket, 'open', handleOpen);
                remove.call(socket, 'error', handleErr);
            }
        }
        function handleOpen() {
            cleanup();
            resolve();
        }
        function handleErr(evt) {
            cleanup();
            reject(evt);
        }
        socket.addEventListener('open', handleOpen);
        socket.addEventListener('error', handleErr);
    });
};

},{}],"kd3VB":[function(require,module,exports) {
const { relative  } = require('iso-url');
const map = {
    http: 'ws',
    https: 'wss'
};
const def = 'ws';
module.exports = (url, location)=>relative(url, location, map, def)
;

},{"iso-url":"9XZNu"}],"aCIAQ":[function(require,module,exports) {
'use strict';
module.exports = function() {
    throw new Error('WebSocket Servers can not be created in the browser!');
};

},{}],"2i3x2":[function(require,module,exports) {
'use strict';
const abortable = require('abortable-iterator');
const { CLOSE_TIMEOUT  } = require('./constants');
const toMultiaddr = require('libp2p-utils/src/ip-port-to-multiaddr');
const pTimeout = require('p-timeout');
const debug = require('debug');
const log = debug('libp2p:websockets:socket');
log.error = debug('libp2p:websockets:socket:error');
// Convert a stream into a MultiaddrConnection
// https://github.com/libp2p/interface-transport#multiaddrconnection
module.exports = (stream, options = {
})=>{
    const maConn = {
        async sink (source) {
            if (options.signal) source = abortable(source, options.signal);
            try {
                await stream.sink(async function*() {
                    for await (const chunk of source)// Convert BufferList to Buffer
                    yield chunk instanceof Uint8Array ? chunk : chunk.slice();
                }());
            } catch (err) {
                if (err.type !== 'aborted') log.error(err);
            }
        },
        source: options.signal ? abortable(stream.source, options.signal) : stream.source,
        conn: stream,
        localAddr: options.localAddr || (stream.localAddress && stream.localPort ? toMultiaddr(stream.localAddress, stream.localPort) : undefined),
        // If the remote address was passed, use it - it may have the peer ID encapsulated
        remoteAddr: options.remoteAddr || toMultiaddr(stream.remoteAddress, stream.remotePort),
        timeline: {
            open: Date.now()
        },
        async close () {
            const start = Date.now();
            try {
                await pTimeout(stream.close(), CLOSE_TIMEOUT);
            } catch (err) {
                const { host , port  } = maConn.remoteAddr.toOptions();
                log('timeout closing stream to %s:%s after %dms, destroying it manually', host, port, Date.now() - start);
                stream.destroy();
            } finally{
                maConn.timeline.close = Date.now();
            }
        }
    };
    stream.socket.once && stream.socket.once('close', ()=>{
        // In instances where `close` was not explicitly called,
        // such as an iterable stream ending, ensure we have set the close
        // timeline
        if (!maConn.timeline.close) maConn.timeline.close = Date.now();
    });
    return maConn;
};

},{"abortable-iterator":"3n79Y","./constants":"gjY9S","libp2p-utils/src/ip-port-to-multiaddr":"bkzJE","p-timeout":"5asWS","debug":"lWlU4"}],"gjY9S":[function(require,module,exports) {
'use strict';
// p2p multi-address code
exports.CODE_P2P = 421;
exports.CODE_CIRCUIT = 290;
exports.CODE_TCP = 6;
exports.CODE_WS = 477;
exports.CODE_WSS = 478;
// Time to wait for a connection to close gracefully before destroying it manually
exports.CLOSE_TIMEOUT = 2000;

},{}],"bkzJE":[function(require,module,exports) {
'use strict';
const debug = require('debug');
const log = Object.assign(debug('libp2p:ip-port-to-multiaddr'), {
    error: debug('libp2p:ip-port-to-multiaddr:err')
});
const { Multiaddr  } = require('multiaddr');
const errCode = require('err-code');
const { Address4 , Address6  } = require('ip-address');
const errors = {
    ERR_INVALID_IP_PARAMETER: 'ERR_INVALID_IP_PARAMETER',
    ERR_INVALID_PORT_PARAMETER: 'ERR_INVALID_PORT_PARAMETER',
    ERR_INVALID_IP: 'ERR_INVALID_IP'
};
/**
 * Transform an IP, Port pair into a multiaddr
 *
 * @param {string} ip
 * @param {number|string} port
 */ function ipPortToMultiaddr(ip, port) {
    if (typeof ip !== 'string') throw errCode(new Error(`invalid ip provided: ${ip}`), errors.ERR_INVALID_IP_PARAMETER);
    if (typeof port === 'string') port = parseInt(port);
    if (isNaN(port)) throw errCode(new Error(`invalid port provided: ${port}`), errors.ERR_INVALID_PORT_PARAMETER);
    try {
        // Test valid IPv4
        new Address4(ip) // eslint-disable-line no-new
        ;
        return new Multiaddr(`/ip4/${ip}/tcp/${port}`);
    } catch  {
    }
    try {
        // Test valid IPv6
        const ip6 = new Address6(ip);
        return ip6.is4() ? new Multiaddr(`/ip4/${ip6.to4().correctForm()}/tcp/${port}`) : new Multiaddr(`/ip6/${ip}/tcp/${port}`);
    } catch (err) {
        const errMsg = `invalid ip:port for creating a multiaddr: ${ip}:${port}`;
        log.error(errMsg);
        throw errCode(new Error(errMsg), errors.ERR_INVALID_IP);
    }
}
module.exports = ipPortToMultiaddr;
module.exports.Errors = errors;

},{"debug":"lWlU4","multiaddr":"kOPrF","err-code":"eQvyh","ip-address":"1yvLg"}],"1yvLg":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "Address4", ()=>_ipv4.Address4
);
parcelHelpers.export(exports, "Address6", ()=>_ipv6.Address6
);
parcelHelpers.export(exports, "AddressError", ()=>_addressError.AddressError
);
parcelHelpers.export(exports, "v6", ()=>v6
);
var _ipv4 = require("./lib/ipv4");
var _ipv6 = require("./lib/ipv6");
var _addressError = require("./lib/address-error");
var _helpers = require("./lib/v6/helpers");
const v6 = {
    helpers: _helpers
};

},{"./lib/ipv4":"hVqYT","./lib/ipv6":"6aAh9","./lib/address-error":"4u0zS","./lib/v6/helpers":"9TPlr","@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"hVqYT":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
/**
 * Represents an IPv4 address
 * @class Address4
 * @param {string} address - An IPv4 address string
 */ parcelHelpers.export(exports, "Address4", ()=>Address4
);
/* eslint-disable no-param-reassign */ var _common = require("./common");
var _constants = require("./v4/constants");
var _addressError = require("./address-error");
var _jsbn = require("jsbn");
var _sprintfJs = require("sprintf-js");
class Address4 {
    constructor(address){
        this.groups = _constants.GROUPS;
        this.parsedAddress = [];
        this.parsedSubnet = '';
        this.subnet = '/32';
        this.subnetMask = 32;
        this.v4 = true;
        /**
         * Returns true if the address is correct, false otherwise
         * @memberof Address4
         * @instance
         * @returns {Boolean}
         */ this.isCorrect = _common.isCorrect(_constants.BITS);
        /**
         * Returns true if the given address is in the subnet of the current address
         * @memberof Address4
         * @instance
         * @returns {boolean}
         */ this.isInSubnet = _common.isInSubnet;
        this.address = address;
        const subnet = _constants.RE_SUBNET_STRING.exec(address);
        if (subnet) {
            this.parsedSubnet = subnet[0].replace('/', '');
            this.subnetMask = parseInt(this.parsedSubnet, 10);
            this.subnet = `/${this.subnetMask}`;
            if (this.subnetMask < 0 || this.subnetMask > _constants.BITS) throw new _addressError.AddressError('Invalid subnet mask.');
            address = address.replace(_constants.RE_SUBNET_STRING, '');
        }
        this.addressMinusSuffix = address;
        this.parsedAddress = this.parse(address);
    }
    static isValid(address1) {
        try {
            // eslint-disable-next-line no-new
            new Address4(address1);
            return true;
        } catch (e) {
            return false;
        }
    }
    /*
     * Parses a v4 address
     */ parse(address2) {
        const groups = address2.split('.');
        if (!address2.match(_constants.RE_ADDRESS)) throw new _addressError.AddressError('Invalid IPv4 address.');
        return groups;
    }
    /**
     * Returns the correct form of an address
     * @memberof Address4
     * @instance
     * @returns {String}
     */ correctForm() {
        return this.parsedAddress.map((part)=>parseInt(part, 10)
        ).join('.');
    }
    /**
     * Converts a hex string to an IPv4 address object
     * @memberof Address4
     * @static
     * @param {string} hex - a hex string to convert
     * @returns {Address4}
     */ static fromHex(hex) {
        const padded = hex.replace(/:/g, '').padStart(8, '0');
        const groups = [];
        let i;
        for(i = 0; i < 8; i += 2){
            const h = padded.slice(i, i + 2);
            groups.push(parseInt(h, 16));
        }
        return new Address4(groups.join('.'));
    }
    /**
     * Converts an integer into a IPv4 address object
     * @memberof Address4
     * @static
     * @param {integer} integer - a number to convert
     * @returns {Address4}
     */ static fromInteger(integer) {
        return Address4.fromHex(integer.toString(16));
    }
    /**
     * Return an address from in-addr.arpa form
     * @memberof Address4
     * @static
     * @param {string} arpaFormAddress - an 'in-addr.arpa' form ipv4 address
     * @returns {Adress4}
     * @example
     * var address = Address4.fromArpa(42.2.0.192.in-addr.arpa.)
     * address.correctForm(); // '192.0.2.42'
     */ static fromArpa(arpaFormAddress) {
        // remove ending ".in-addr.arpa." or just "."
        const leader = arpaFormAddress.replace(/(\.in-addr\.arpa)?\.$/, '');
        const address = leader.split('.').reverse().join('.');
        return new Address4(address);
    }
    /**
     * Converts an IPv4 address object to a hex string
     * @memberof Address4
     * @instance
     * @returns {String}
     */ toHex() {
        return this.parsedAddress.map((part)=>_sprintfJs.sprintf('%02x', parseInt(part, 10))
        ).join(':');
    }
    /**
     * Converts an IPv4 address object to an array of bytes
     * @memberof Address4
     * @instance
     * @returns {Array}
     */ toArray() {
        return this.parsedAddress.map((part)=>parseInt(part, 10)
        );
    }
    /**
     * Converts an IPv4 address object to an IPv6 address group
     * @memberof Address4
     * @instance
     * @returns {String}
     */ toGroup6() {
        const output = [];
        let i;
        for(i = 0; i < _constants.GROUPS; i += 2){
            const hex = _sprintfJs.sprintf('%02x%02x', parseInt(this.parsedAddress[i], 10), parseInt(this.parsedAddress[i + 1], 10));
            output.push(_sprintfJs.sprintf('%x', parseInt(hex, 16)));
        }
        return output.join(':');
    }
    /**
     * Returns the address as a BigInteger
     * @memberof Address4
     * @instance
     * @returns {BigInteger}
     */ bigInteger() {
        return new _jsbn.BigInteger(this.parsedAddress.map((n)=>_sprintfJs.sprintf('%02x', parseInt(n, 10))
        ).join(''), 16);
    }
    /**
     * Helper function getting start address.
     * @memberof Address4
     * @instance
     * @returns {BigInteger}
     */ _startAddress() {
        return new _jsbn.BigInteger(this.mask() + '0'.repeat(_constants.BITS - this.subnetMask), 2);
    }
    /**
     * The first address in the range given by this address' subnet.
     * Often referred to as the Network Address.
     * @memberof Address4
     * @instance
     * @returns {Address4}
     */ startAddress() {
        return Address4.fromBigInteger(this._startAddress());
    }
    /**
     * The first host address in the range given by this address's subnet ie
     * the first address after the Network Address
     * @memberof Address4
     * @instance
     * @returns {Address4}
     */ startAddressExclusive() {
        const adjust = new _jsbn.BigInteger('1');
        return Address4.fromBigInteger(this._startAddress().add(adjust));
    }
    /**
     * Helper function getting end address.
     * @memberof Address4
     * @instance
     * @returns {BigInteger}
     */ _endAddress() {
        return new _jsbn.BigInteger(this.mask() + '1'.repeat(_constants.BITS - this.subnetMask), 2);
    }
    /**
     * The last address in the range given by this address' subnet
     * Often referred to as the Broadcast
     * @memberof Address4
     * @instance
     * @returns {Address4}
     */ endAddress() {
        return Address4.fromBigInteger(this._endAddress());
    }
    /**
     * The last host address in the range given by this address's subnet ie
     * the last address prior to the Broadcast Address
     * @memberof Address4
     * @instance
     * @returns {Address4}
     */ endAddressExclusive() {
        const adjust = new _jsbn.BigInteger('1');
        return Address4.fromBigInteger(this._endAddress().subtract(adjust));
    }
    /**
     * Converts a BigInteger to a v4 address object
     * @memberof Address4
     * @static
     * @param {BigInteger} bigInteger - a BigInteger to convert
     * @returns {Address4}
     */ static fromBigInteger(bigInteger) {
        return Address4.fromInteger(parseInt(bigInteger.toString(), 10));
    }
    /**
     * Returns the first n bits of the address, defaulting to the
     * subnet mask
     * @memberof Address4
     * @instance
     * @returns {String}
     */ mask(mask) {
        if (mask === undefined) mask = this.subnetMask;
        return this.getBitsBase2(0, mask);
    }
    /**
     * Returns the bits in the given range as a base-2 string
     * @memberof Address4
     * @instance
     * @returns {string}
     */ getBitsBase2(start, end) {
        return this.binaryZeroPad().slice(start, end);
    }
    /**
     * Return the reversed ip6.arpa form of the address
     * @memberof Address4
     * @param {Object} options
     * @param {boolean} options.omitSuffix - omit the "in-addr.arpa" suffix
     * @instance
     * @returns {String}
     */ reverseForm(options) {
        if (!options) options = {
        };
        const reversed = this.correctForm().split('.').reverse().join('.');
        if (options.omitSuffix) return reversed;
        return _sprintfJs.sprintf('%s.in-addr.arpa.', reversed);
    }
    /**
     * Returns true if the given address is a multicast address
     * @memberof Address4
     * @instance
     * @returns {boolean}
     */ isMulticast() {
        return this.isInSubnet(new Address4('224.0.0.0/4'));
    }
    /**
     * Returns a zero-padded base-2 string representation of the address
     * @memberof Address4
     * @instance
     * @returns {string}
     */ binaryZeroPad() {
        return this.bigInteger().toString(2).padStart(_constants.BITS, '0');
    }
    /**
     * Groups an IPv4 address for inclusion at the end of an IPv6 address
     * @returns {String}
     */ groupForV6() {
        const segments = this.parsedAddress;
        return this.address.replace(_constants.RE_ADDRESS, _sprintfJs.sprintf('<span class="hover-group group-v4 group-6">%s</span>.<span class="hover-group group-v4 group-7">%s</span>', segments.slice(0, 2).join('.'), segments.slice(2, 4).join('.')));
    }
}

},{"./common":"7Q894","./v4/constants":"jDbQp","./address-error":"4u0zS","jsbn":"3AMga","sprintf-js":"5Vzwd","@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"7Q894":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "isInSubnet", ()=>isInSubnet
);
parcelHelpers.export(exports, "isCorrect", ()=>isCorrect
);
function isInSubnet(address) {
    if (this.subnetMask < address.subnetMask) return false;
    if (this.mask(address.subnetMask) === address.mask()) return true;
    return false;
}
function isCorrect(defaultBits) {
    return function() {
        if (this.addressMinusSuffix !== this.correctForm()) return false;
        if (this.subnetMask === defaultBits && !this.parsedSubnet) return true;
        return this.parsedSubnet === String(this.subnetMask);
    };
}

},{"@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"jDbQp":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "BITS", ()=>BITS
);
parcelHelpers.export(exports, "GROUPS", ()=>GROUPS
);
parcelHelpers.export(exports, "RE_ADDRESS", ()=>RE_ADDRESS
);
parcelHelpers.export(exports, "RE_SUBNET_STRING", ()=>RE_SUBNET_STRING
);
const BITS = 32;
const GROUPS = 4;
const RE_ADDRESS = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/g;
const RE_SUBNET_STRING = /\/\d{1,2}$/;

},{"@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"4u0zS":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "AddressError", ()=>AddressError
);
class AddressError extends Error {
    constructor(message, parseMessage){
        super(message);
        this.name = 'AddressError';
        if (parseMessage !== null) this.parseMessage = parseMessage;
    }
}

},{"@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"3AMga":[function(require,module,exports) {
(function() {
    // Copyright (c) 2005  Tom Wu
    // All Rights Reserved.
    // See "LICENSE" for details.
    // Basic JavaScript BN library - subset useful for RSA encryption.
    // Bits per digit
    var dbits;
    // JavaScript engine analysis
    var canary = 244837814094590;
    var j_lm = (canary & 16777215) == 15715070;
    // (public) Constructor
    function BigInteger(a, b, c) {
        if (a != null) {
            if ("number" == typeof a) this.fromNumber(a, b, c);
            else if (b == null && "string" != typeof a) this.fromString(a, 256);
            else this.fromString(a, b);
        }
    }
    // return new, unset BigInteger
    function nbi() {
        return new BigInteger(null);
    }
    // am: Compute w_j += (x*this_i), propagate carries,
    // c is initial carry, returns final carry.
    // c < 3*dvalue, x < 2*dvalue, this_i < dvalue
    // We need to select the fastest one that works in this environment.
    // am1: use a single mult and divide to get the high bits,
    // max digit bits should be 26 because
    // max internal value = 2*dvalue^2-2*dvalue (< 2^53)
    function am1(i, x, w, j, c, n) {
        while(--n >= 0){
            var v = x * this[i++] + w[j] + c;
            c = Math.floor(v / 67108864);
            w[j++] = v & 67108863;
        }
        return c;
    }
    // am2 avoids a big mult-and-extract completely.
    // Max digit bits should be <= 30 because we do bitwise ops
    // on values up to 2*hdvalue^2-hdvalue-1 (< 2^31)
    function am2(i, x, w, j, c, n) {
        var xl = x & 32767, xh = x >> 15;
        while(--n >= 0){
            var l = this[i] & 32767;
            var h = this[i++] >> 15;
            var m = xh * l + h * xl;
            l = xl * l + ((m & 32767) << 15) + w[j] + (c & 1073741823);
            c = (l >>> 30) + (m >>> 15) + xh * h + (c >>> 30);
            w[j++] = l & 1073741823;
        }
        return c;
    }
    // Alternately, set max digit bits to 28 since some
    // browsers slow down when dealing with 32-bit numbers.
    function am3(i, x, w, j, c, n) {
        var xl = x & 16383, xh = x >> 14;
        while(--n >= 0){
            var l = this[i] & 16383;
            var h = this[i++] >> 14;
            var m = xh * l + h * xl;
            l = xl * l + ((m & 16383) << 14) + w[j] + c;
            c = (l >> 28) + (m >> 14) + xh * h;
            w[j++] = l & 268435455;
        }
        return c;
    }
    var inBrowser = typeof navigator !== "undefined";
    if (inBrowser && j_lm && navigator.appName == "Microsoft Internet Explorer") {
        BigInteger.prototype.am = am2;
        dbits = 30;
    } else if (inBrowser && j_lm && navigator.appName != "Netscape") {
        BigInteger.prototype.am = am1;
        dbits = 26;
    } else {
        BigInteger.prototype.am = am3;
        dbits = 28;
    }
    BigInteger.prototype.DB = dbits;
    BigInteger.prototype.DM = (1 << dbits) - 1;
    BigInteger.prototype.DV = 1 << dbits;
    var BI_FP = 52;
    BigInteger.prototype.FV = Math.pow(2, BI_FP);
    BigInteger.prototype.F1 = BI_FP - dbits;
    BigInteger.prototype.F2 = 2 * dbits - BI_FP;
    // Digit conversions
    var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";
    var BI_RC = new Array();
    var rr, vv;
    rr = "0".charCodeAt(0);
    for(vv = 0; vv <= 9; ++vv)BI_RC[rr++] = vv;
    rr = "a".charCodeAt(0);
    for(vv = 10; vv < 36; ++vv)BI_RC[rr++] = vv;
    rr = "A".charCodeAt(0);
    for(vv = 10; vv < 36; ++vv)BI_RC[rr++] = vv;
    function int2char(n) {
        return BI_RM.charAt(n);
    }
    function intAt(s, i) {
        var c = BI_RC[s.charCodeAt(i)];
        return c == null ? -1 : c;
    }
    // (protected) copy this to r
    function bnpCopyTo(r) {
        for(var i = this.t - 1; i >= 0; --i)r[i] = this[i];
        r.t = this.t;
        r.s = this.s;
    }
    // (protected) set from integer value x, -DV <= x < DV
    function bnpFromInt(x) {
        this.t = 1;
        this.s = x < 0 ? -1 : 0;
        if (x > 0) this[0] = x;
        else if (x < -1) this[0] = x + this.DV;
        else this.t = 0;
    }
    // return bigint initialized to value
    function nbv(i) {
        var r = nbi();
        r.fromInt(i);
        return r;
    }
    // (protected) set from string and radix
    function bnpFromString(s, b) {
        var k;
        if (b == 16) k = 4;
        else if (b == 8) k = 3;
        else if (b == 256) k = 8; // byte array
        else if (b == 2) k = 1;
        else if (b == 32) k = 5;
        else if (b == 4) k = 2;
        else {
            this.fromRadix(s, b);
            return;
        }
        this.t = 0;
        this.s = 0;
        var i = s.length, mi = false, sh = 0;
        while(--i >= 0){
            var x = k == 8 ? s[i] & 255 : intAt(s, i);
            if (x < 0) {
                if (s.charAt(i) == "-") mi = true;
                continue;
            }
            mi = false;
            if (sh == 0) this[this.t++] = x;
            else if (sh + k > this.DB) {
                this[this.t - 1] |= (x & (1 << this.DB - sh) - 1) << sh;
                this[this.t++] = x >> this.DB - sh;
            } else this[this.t - 1] |= x << sh;
            sh += k;
            if (sh >= this.DB) sh -= this.DB;
        }
        if (k == 8 && (s[0] & 128) != 0) {
            this.s = -1;
            if (sh > 0) this[this.t - 1] |= (1 << this.DB - sh) - 1 << sh;
        }
        this.clamp();
        if (mi) BigInteger.ZERO.subTo(this, this);
    }
    // (protected) clamp off excess high words
    function bnpClamp() {
        var c = this.s & this.DM;
        while(this.t > 0 && this[this.t - 1] == c)--this.t;
    }
    // (public) return string representation in given radix
    function bnToString(b) {
        if (this.s < 0) return "-" + this.negate().toString(b);
        var k;
        if (b == 16) k = 4;
        else if (b == 8) k = 3;
        else if (b == 2) k = 1;
        else if (b == 32) k = 5;
        else if (b == 4) k = 2;
        else return this.toRadix(b);
        var km = (1 << k) - 1, d, m = false, r = "", i = this.t;
        var p = this.DB - i * this.DB % k;
        if (i-- > 0) {
            if (p < this.DB && (d = this[i] >> p) > 0) {
                m = true;
                r = int2char(d);
            }
            while(i >= 0){
                if (p < k) {
                    d = (this[i] & (1 << p) - 1) << k - p;
                    d |= this[--i] >> (p += this.DB - k);
                } else {
                    d = this[i] >> (p -= k) & km;
                    if (p <= 0) {
                        p += this.DB;
                        --i;
                    }
                }
                if (d > 0) m = true;
                if (m) r += int2char(d);
            }
        }
        return m ? r : "0";
    }
    // (public) -this
    function bnNegate() {
        var r = nbi();
        BigInteger.ZERO.subTo(this, r);
        return r;
    }
    // (public) |this|
    function bnAbs() {
        return this.s < 0 ? this.negate() : this;
    }
    // (public) return + if this > a, - if this < a, 0 if equal
    function bnCompareTo(a) {
        var r = this.s - a.s;
        if (r != 0) return r;
        var i = this.t;
        r = i - a.t;
        if (r != 0) return this.s < 0 ? -r : r;
        while(--i >= 0)if ((r = this[i] - a[i]) != 0) return r;
        return 0;
    }
    // returns bit length of the integer x
    function nbits(x) {
        var r = 1, t;
        if ((t = x >>> 16) != 0) {
            x = t;
            r += 16;
        }
        if ((t = x >> 8) != 0) {
            x = t;
            r += 8;
        }
        if ((t = x >> 4) != 0) {
            x = t;
            r += 4;
        }
        if ((t = x >> 2) != 0) {
            x = t;
            r += 2;
        }
        if ((t = x >> 1) != 0) {
            x = t;
            r += 1;
        }
        return r;
    }
    // (public) return the number of bits in "this"
    function bnBitLength() {
        if (this.t <= 0) return 0;
        return this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ this.s & this.DM);
    }
    // (protected) r = this << n*DB
    function bnpDLShiftTo(n, r) {
        var i;
        for(i = this.t - 1; i >= 0; --i)r[i + n] = this[i];
        for(i = n - 1; i >= 0; --i)r[i] = 0;
        r.t = this.t + n;
        r.s = this.s;
    }
    // (protected) r = this >> n*DB
    function bnpDRShiftTo(n, r) {
        for(var i = n; i < this.t; ++i)r[i - n] = this[i];
        r.t = Math.max(this.t - n, 0);
        r.s = this.s;
    }
    // (protected) r = this << n
    function bnpLShiftTo(n, r) {
        var bs = n % this.DB;
        var cbs = this.DB - bs;
        var bm = (1 << cbs) - 1;
        var ds = Math.floor(n / this.DB), c = this.s << bs & this.DM, i;
        for(i = this.t - 1; i >= 0; --i){
            r[i + ds + 1] = this[i] >> cbs | c;
            c = (this[i] & bm) << bs;
        }
        for(i = ds - 1; i >= 0; --i)r[i] = 0;
        r[ds] = c;
        r.t = this.t + ds + 1;
        r.s = this.s;
        r.clamp();
    }
    // (protected) r = this >> n
    function bnpRShiftTo(n, r) {
        r.s = this.s;
        var ds = Math.floor(n / this.DB);
        if (ds >= this.t) {
            r.t = 0;
            return;
        }
        var bs = n % this.DB;
        var cbs = this.DB - bs;
        var bm = (1 << bs) - 1;
        r[0] = this[ds] >> bs;
        for(var i = ds + 1; i < this.t; ++i){
            r[i - ds - 1] |= (this[i] & bm) << cbs;
            r[i - ds] = this[i] >> bs;
        }
        if (bs > 0) r[this.t - ds - 1] |= (this.s & bm) << cbs;
        r.t = this.t - ds;
        r.clamp();
    }
    // (protected) r = this - a
    function bnpSubTo(a, r) {
        var i = 0, c = 0, m = Math.min(a.t, this.t);
        while(i < m){
            c += this[i] - a[i];
            r[i++] = c & this.DM;
            c >>= this.DB;
        }
        if (a.t < this.t) {
            c -= a.s;
            while(i < this.t){
                c += this[i];
                r[i++] = c & this.DM;
                c >>= this.DB;
            }
            c += this.s;
        } else {
            c += this.s;
            while(i < a.t){
                c -= a[i];
                r[i++] = c & this.DM;
                c >>= this.DB;
            }
            c -= a.s;
        }
        r.s = c < 0 ? -1 : 0;
        if (c < -1) r[i++] = this.DV + c;
        else if (c > 0) r[i++] = c;
        r.t = i;
        r.clamp();
    }
    // (protected) r = this * a, r != this,a (HAC 14.12)
    // "this" should be the larger one if appropriate.
    function bnpMultiplyTo(a, r) {
        var x = this.abs(), y = a.abs();
        var i = x.t;
        r.t = i + y.t;
        while(--i >= 0)r[i] = 0;
        for(i = 0; i < y.t; ++i)r[i + x.t] = x.am(0, y[i], r, i, 0, x.t);
        r.s = 0;
        r.clamp();
        if (this.s != a.s) BigInteger.ZERO.subTo(r, r);
    }
    // (protected) r = this^2, r != this (HAC 14.16)
    function bnpSquareTo(r) {
        var x = this.abs();
        var i = r.t = 2 * x.t;
        while(--i >= 0)r[i] = 0;
        for(i = 0; i < x.t - 1; ++i){
            var c = x.am(i, x[i], r, 2 * i, 0, 1);
            if ((r[i + x.t] += x.am(i + 1, 2 * x[i], r, 2 * i + 1, c, x.t - i - 1)) >= x.DV) {
                r[i + x.t] -= x.DV;
                r[i + x.t + 1] = 1;
            }
        }
        if (r.t > 0) r[r.t - 1] += x.am(i, x[i], r, 2 * i, 0, 1);
        r.s = 0;
        r.clamp();
    }
    // (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
    // r != q, this != m.  q or r may be null.
    function bnpDivRemTo(m, q, r) {
        var pm = m.abs();
        if (pm.t <= 0) return;
        var pt = this.abs();
        if (pt.t < pm.t) {
            if (q != null) q.fromInt(0);
            if (r != null) this.copyTo(r);
            return;
        }
        if (r == null) r = nbi();
        var y = nbi(), ts = this.s, ms = m.s;
        var nsh = this.DB - nbits(pm[pm.t - 1]); // normalize modulus
        if (nsh > 0) {
            pm.lShiftTo(nsh, y);
            pt.lShiftTo(nsh, r);
        } else {
            pm.copyTo(y);
            pt.copyTo(r);
        }
        var ys = y.t;
        var y0 = y[ys - 1];
        if (y0 == 0) return;
        var yt = y0 * (1 << this.F1) + (ys > 1 ? y[ys - 2] >> this.F2 : 0);
        var d1 = this.FV / yt, d2 = (1 << this.F1) / yt, e = 1 << this.F2;
        var i = r.t, j = i - ys, t = q == null ? nbi() : q;
        y.dlShiftTo(j, t);
        if (r.compareTo(t) >= 0) {
            r[r.t++] = 1;
            r.subTo(t, r);
        }
        BigInteger.ONE.dlShiftTo(ys, t);
        t.subTo(y, y); // "negative" y so we can replace sub with am later
        while(y.t < ys)y[y.t++] = 0;
        while(--j >= 0){
            // Estimate quotient digit
            var qd = r[--i] == y0 ? this.DM : Math.floor(r[i] * d1 + (r[i - 1] + e) * d2);
            if ((r[i] += y.am(0, qd, r, j, 0, ys)) < qd) {
                y.dlShiftTo(j, t);
                r.subTo(t, r);
                while(r[i] < --qd)r.subTo(t, r);
            }
        }
        if (q != null) {
            r.drShiftTo(ys, q);
            if (ts != ms) BigInteger.ZERO.subTo(q, q);
        }
        r.t = ys;
        r.clamp();
        if (nsh > 0) r.rShiftTo(nsh, r); // Denormalize remainder
        if (ts < 0) BigInteger.ZERO.subTo(r, r);
    }
    // (public) this mod a
    function bnMod(a) {
        var r = nbi();
        this.abs().divRemTo(a, null, r);
        if (this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r, r);
        return r;
    }
    // Modular reduction using "classic" algorithm
    function Classic(m) {
        this.m = m;
    }
    function cConvert(x) {
        if (x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m);
        else return x;
    }
    function cRevert(x) {
        return x;
    }
    function cReduce(x) {
        x.divRemTo(this.m, null, x);
    }
    function cMulTo(x, y, r) {
        x.multiplyTo(y, r);
        this.reduce(r);
    }
    function cSqrTo(x, r) {
        x.squareTo(r);
        this.reduce(r);
    }
    Classic.prototype.convert = cConvert;
    Classic.prototype.revert = cRevert;
    Classic.prototype.reduce = cReduce;
    Classic.prototype.mulTo = cMulTo;
    Classic.prototype.sqrTo = cSqrTo;
    // (protected) return "-1/this % 2^DB"; useful for Mont. reduction
    // justification:
    //         xy == 1 (mod m)
    //         xy =  1+km
    //   xy(2-xy) = (1+km)(1-km)
    // x[y(2-xy)] = 1-k^2m^2
    // x[y(2-xy)] == 1 (mod m^2)
    // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
    // should reduce x and y(2-xy) by m^2 at each step to keep size bounded.
    // JS multiply "overflows" differently from C/C++, so care is needed here.
    function bnpInvDigit() {
        if (this.t < 1) return 0;
        var x = this[0];
        if ((x & 1) == 0) return 0;
        var y = x & 3; // y == 1/x mod 2^2
        y = y * (2 - (x & 15) * y) & 15; // y == 1/x mod 2^4
        y = y * (2 - (x & 255) * y) & 255; // y == 1/x mod 2^8
        y = y * (2 - ((x & 65535) * y & 65535)) & 65535; // y == 1/x mod 2^16
        // last step - calculate inverse mod DV directly;
        // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
        y = y * (2 - x * y % this.DV) % this.DV; // y == 1/x mod 2^dbits
        // we really want the negative inverse, and -DV < y < DV
        return y > 0 ? this.DV - y : -y;
    }
    // Montgomery reduction
    function Montgomery(m) {
        this.m = m;
        this.mp = m.invDigit();
        this.mpl = this.mp & 32767;
        this.mph = this.mp >> 15;
        this.um = (1 << m.DB - 15) - 1;
        this.mt2 = 2 * m.t;
    }
    // xR mod m
    function montConvert(x) {
        var r = nbi();
        x.abs().dlShiftTo(this.m.t, r);
        r.divRemTo(this.m, null, r);
        if (x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r, r);
        return r;
    }
    // x/R mod m
    function montRevert(x) {
        var r = nbi();
        x.copyTo(r);
        this.reduce(r);
        return r;
    }
    // x = x/R mod m (HAC 14.32)
    function montReduce(x) {
        while(x.t <= this.mt2)x[x.t++] = 0;
        for(var i = 0; i < this.m.t; ++i){
            // faster way of calculating u0 = x[i]*mp mod DV
            var j = x[i] & 32767;
            var u0 = j * this.mpl + ((j * this.mph + (x[i] >> 15) * this.mpl & this.um) << 15) & x.DM;
            // use am to combine the multiply-shift-add into one call
            j = i + this.m.t;
            x[j] += this.m.am(0, u0, x, i, 0, this.m.t);
            // propagate carry
            while(x[j] >= x.DV){
                x[j] -= x.DV;
                x[++j]++;
            }
        }
        x.clamp();
        x.drShiftTo(this.m.t, x);
        if (x.compareTo(this.m) >= 0) x.subTo(this.m, x);
    }
    // r = "x^2/R mod m"; x != r
    function montSqrTo(x, r) {
        x.squareTo(r);
        this.reduce(r);
    }
    // r = "xy/R mod m"; x,y != r
    function montMulTo(x, y, r) {
        x.multiplyTo(y, r);
        this.reduce(r);
    }
    Montgomery.prototype.convert = montConvert;
    Montgomery.prototype.revert = montRevert;
    Montgomery.prototype.reduce = montReduce;
    Montgomery.prototype.mulTo = montMulTo;
    Montgomery.prototype.sqrTo = montSqrTo;
    // (protected) true iff this is even
    function bnpIsEven() {
        return (this.t > 0 ? this[0] & 1 : this.s) == 0;
    }
    // (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
    function bnpExp(e, z) {
        if (e > 4294967295 || e < 1) return BigInteger.ONE;
        var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e) - 1;
        g.copyTo(r);
        while(--i >= 0){
            z.sqrTo(r, r2);
            if ((e & 1 << i) > 0) z.mulTo(r2, g, r);
            else {
                var t = r;
                r = r2;
                r2 = t;
            }
        }
        return z.revert(r);
    }
    // (public) this^e % m, 0 <= e < 2^32
    function bnModPowInt(e, m) {
        var z;
        if (e < 256 || m.isEven()) z = new Classic(m);
        else z = new Montgomery(m);
        return this.exp(e, z);
    }
    // protected
    BigInteger.prototype.copyTo = bnpCopyTo;
    BigInteger.prototype.fromInt = bnpFromInt;
    BigInteger.prototype.fromString = bnpFromString;
    BigInteger.prototype.clamp = bnpClamp;
    BigInteger.prototype.dlShiftTo = bnpDLShiftTo;
    BigInteger.prototype.drShiftTo = bnpDRShiftTo;
    BigInteger.prototype.lShiftTo = bnpLShiftTo;
    BigInteger.prototype.rShiftTo = bnpRShiftTo;
    BigInteger.prototype.subTo = bnpSubTo;
    BigInteger.prototype.multiplyTo = bnpMultiplyTo;
    BigInteger.prototype.squareTo = bnpSquareTo;
    BigInteger.prototype.divRemTo = bnpDivRemTo;
    BigInteger.prototype.invDigit = bnpInvDigit;
    BigInteger.prototype.isEven = bnpIsEven;
    BigInteger.prototype.exp = bnpExp;
    // public
    BigInteger.prototype.toString = bnToString;
    BigInteger.prototype.negate = bnNegate;
    BigInteger.prototype.abs = bnAbs;
    BigInteger.prototype.compareTo = bnCompareTo;
    BigInteger.prototype.bitLength = bnBitLength;
    BigInteger.prototype.mod = bnMod;
    BigInteger.prototype.modPowInt = bnModPowInt;
    // "constants"
    BigInteger.ZERO = nbv(0);
    BigInteger.ONE = nbv(1);
    // Copyright (c) 2005-2009  Tom Wu
    // All Rights Reserved.
    // See "LICENSE" for details.
    // Extended JavaScript BN functions, required for RSA private ops.
    // Version 1.1: new BigInteger("0", 10) returns "proper" zero
    // Version 1.2: square() API, isProbablePrime fix
    // (public)
    function bnClone() {
        var r = nbi();
        this.copyTo(r);
        return r;
    }
    // (public) return value as integer
    function bnIntValue() {
        if (this.s < 0) {
            if (this.t == 1) return this[0] - this.DV;
            else if (this.t == 0) return -1;
        } else if (this.t == 1) return this[0];
        else if (this.t == 0) return 0;
        // assumes 16 < DB < 32
        return (this[1] & (1 << 32 - this.DB) - 1) << this.DB | this[0];
    }
    // (public) return value as byte
    function bnByteValue() {
        return this.t == 0 ? this.s : this[0] << 24 >> 24;
    }
    // (public) return value as short (assumes DB>=16)
    function bnShortValue() {
        return this.t == 0 ? this.s : this[0] << 16 >> 16;
    }
    // (protected) return x s.t. r^x < DV
    function bnpChunkSize(r) {
        return Math.floor(Math.LN2 * this.DB / Math.log(r));
    }
    // (public) 0 if this == 0, 1 if this > 0
    function bnSigNum() {
        if (this.s < 0) return -1;
        else if (this.t <= 0 || this.t == 1 && this[0] <= 0) return 0;
        else return 1;
    }
    // (protected) convert to radix string
    function bnpToRadix(b) {
        if (b == null) b = 10;
        if (this.signum() == 0 || b < 2 || b > 36) return "0";
        var cs = this.chunkSize(b);
        var a = Math.pow(b, cs);
        var d = nbv(a), y = nbi(), z = nbi(), r = "";
        this.divRemTo(d, y, z);
        while(y.signum() > 0){
            r = (a + z.intValue()).toString(b).substr(1) + r;
            y.divRemTo(d, y, z);
        }
        return z.intValue().toString(b) + r;
    }
    // (protected) convert from radix string
    function bnpFromRadix(s, b) {
        this.fromInt(0);
        if (b == null) b = 10;
        var cs = this.chunkSize(b);
        var d = Math.pow(b, cs), mi = false, j = 0, w = 0;
        for(var i = 0; i < s.length; ++i){
            var x = intAt(s, i);
            if (x < 0) {
                if (s.charAt(i) == "-" && this.signum() == 0) mi = true;
                continue;
            }
            w = b * w + x;
            if (++j >= cs) {
                this.dMultiply(d);
                this.dAddOffset(w, 0);
                j = 0;
                w = 0;
            }
        }
        if (j > 0) {
            this.dMultiply(Math.pow(b, j));
            this.dAddOffset(w, 0);
        }
        if (mi) BigInteger.ZERO.subTo(this, this);
    }
    // (protected) alternate constructor
    function bnpFromNumber(a, b, c) {
        if ("number" == typeof b) {
            // new BigInteger(int,int,RNG)
            if (a < 2) this.fromInt(1);
            else {
                this.fromNumber(a, c);
                if (!this.testBit(a - 1)) this.bitwiseTo(BigInteger.ONE.shiftLeft(a - 1), op_or, this);
                if (this.isEven()) this.dAddOffset(1, 0); // force odd
                while(!this.isProbablePrime(b)){
                    this.dAddOffset(2, 0);
                    if (this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a - 1), this);
                }
            }
        } else {
            // new BigInteger(int,RNG)
            var x = new Array(), t = a & 7;
            x.length = (a >> 3) + 1;
            b.nextBytes(x);
            if (t > 0) x[0] &= (1 << t) - 1;
            else x[0] = 0;
            this.fromString(x, 256);
        }
    }
    // (public) convert to bigendian byte array
    function bnToByteArray() {
        var i = this.t, r = new Array();
        r[0] = this.s;
        var p = this.DB - i * this.DB % 8, d, k = 0;
        if (i-- > 0) {
            if (p < this.DB && (d = this[i] >> p) != (this.s & this.DM) >> p) r[k++] = d | this.s << this.DB - p;
            while(i >= 0){
                if (p < 8) {
                    d = (this[i] & (1 << p) - 1) << 8 - p;
                    d |= this[--i] >> (p += this.DB - 8);
                } else {
                    d = this[i] >> (p -= 8) & 255;
                    if (p <= 0) {
                        p += this.DB;
                        --i;
                    }
                }
                if ((d & 128) != 0) d |= -256;
                if (k == 0 && (this.s & 128) != (d & 128)) ++k;
                if (k > 0 || d != this.s) r[k++] = d;
            }
        }
        return r;
    }
    function bnEquals(a) {
        return this.compareTo(a) == 0;
    }
    function bnMin(a) {
        return this.compareTo(a) < 0 ? this : a;
    }
    function bnMax(a) {
        return this.compareTo(a) > 0 ? this : a;
    }
    // (protected) r = this op a (bitwise)
    function bnpBitwiseTo(a, op, r) {
        var i, f, m = Math.min(a.t, this.t);
        for(i = 0; i < m; ++i)r[i] = op(this[i], a[i]);
        if (a.t < this.t) {
            f = a.s & this.DM;
            for(i = m; i < this.t; ++i)r[i] = op(this[i], f);
            r.t = this.t;
        } else {
            f = this.s & this.DM;
            for(i = m; i < a.t; ++i)r[i] = op(f, a[i]);
            r.t = a.t;
        }
        r.s = op(this.s, a.s);
        r.clamp();
    }
    // (public) this & a
    function op_and(x, y) {
        return x & y;
    }
    function bnAnd(a) {
        var r = nbi();
        this.bitwiseTo(a, op_and, r);
        return r;
    }
    // (public) this | a
    function op_or(x, y) {
        return x | y;
    }
    function bnOr(a) {
        var r = nbi();
        this.bitwiseTo(a, op_or, r);
        return r;
    }
    // (public) this ^ a
    function op_xor(x, y) {
        return x ^ y;
    }
    function bnXor(a) {
        var r = nbi();
        this.bitwiseTo(a, op_xor, r);
        return r;
    }
    // (public) this & ~a
    function op_andnot(x, y) {
        return x & ~y;
    }
    function bnAndNot(a) {
        var r = nbi();
        this.bitwiseTo(a, op_andnot, r);
        return r;
    }
    // (public) ~this
    function bnNot() {
        var r = nbi();
        for(var i = 0; i < this.t; ++i)r[i] = this.DM & ~this[i];
        r.t = this.t;
        r.s = ~this.s;
        return r;
    }
    // (public) this << n
    function bnShiftLeft(n) {
        var r = nbi();
        if (n < 0) this.rShiftTo(-n, r);
        else this.lShiftTo(n, r);
        return r;
    }
    // (public) this >> n
    function bnShiftRight(n) {
        var r = nbi();
        if (n < 0) this.lShiftTo(-n, r);
        else this.rShiftTo(n, r);
        return r;
    }
    // return index of lowest 1-bit in x, x < 2^31
    function lbit(x) {
        if (x == 0) return -1;
        var r = 0;
        if ((x & 65535) == 0) {
            x >>= 16;
            r += 16;
        }
        if ((x & 255) == 0) {
            x >>= 8;
            r += 8;
        }
        if ((x & 15) == 0) {
            x >>= 4;
            r += 4;
        }
        if ((x & 3) == 0) {
            x >>= 2;
            r += 2;
        }
        if ((x & 1) == 0) ++r;
        return r;
    }
    // (public) returns index of lowest 1-bit (or -1 if none)
    function bnGetLowestSetBit() {
        for(var i = 0; i < this.t; ++i)if (this[i] != 0) return i * this.DB + lbit(this[i]);
        if (this.s < 0) return this.t * this.DB;
        return -1;
    }
    // return number of 1 bits in x
    function cbit(x) {
        var r = 0;
        while(x != 0){
            x &= x - 1;
            ++r;
        }
        return r;
    }
    // (public) return number of set bits
    function bnBitCount() {
        var r = 0, x = this.s & this.DM;
        for(var i = 0; i < this.t; ++i)r += cbit(this[i] ^ x);
        return r;
    }
    // (public) true iff nth bit is set
    function bnTestBit(n) {
        var j = Math.floor(n / this.DB);
        if (j >= this.t) return this.s != 0;
        return (this[j] & 1 << n % this.DB) != 0;
    }
    // (protected) this op (1<<n)
    function bnpChangeBit(n, op) {
        var r = BigInteger.ONE.shiftLeft(n);
        this.bitwiseTo(r, op, r);
        return r;
    }
    // (public) this | (1<<n)
    function bnSetBit(n) {
        return this.changeBit(n, op_or);
    }
    // (public) this & ~(1<<n)
    function bnClearBit(n) {
        return this.changeBit(n, op_andnot);
    }
    // (public) this ^ (1<<n)
    function bnFlipBit(n) {
        return this.changeBit(n, op_xor);
    }
    // (protected) r = this + a
    function bnpAddTo(a, r) {
        var i = 0, c = 0, m = Math.min(a.t, this.t);
        while(i < m){
            c += this[i] + a[i];
            r[i++] = c & this.DM;
            c >>= this.DB;
        }
        if (a.t < this.t) {
            c += a.s;
            while(i < this.t){
                c += this[i];
                r[i++] = c & this.DM;
                c >>= this.DB;
            }
            c += this.s;
        } else {
            c += this.s;
            while(i < a.t){
                c += a[i];
                r[i++] = c & this.DM;
                c >>= this.DB;
            }
            c += a.s;
        }
        r.s = c < 0 ? -1 : 0;
        if (c > 0) r[i++] = c;
        else if (c < -1) r[i++] = this.DV + c;
        r.t = i;
        r.clamp();
    }
    // (public) this + a
    function bnAdd(a) {
        var r = nbi();
        this.addTo(a, r);
        return r;
    }
    // (public) this - a
    function bnSubtract(a) {
        var r = nbi();
        this.subTo(a, r);
        return r;
    }
    // (public) this * a
    function bnMultiply(a) {
        var r = nbi();
        this.multiplyTo(a, r);
        return r;
    }
    // (public) this^2
    function bnSquare() {
        var r = nbi();
        this.squareTo(r);
        return r;
    }
    // (public) this / a
    function bnDivide(a) {
        var r = nbi();
        this.divRemTo(a, r, null);
        return r;
    }
    // (public) this % a
    function bnRemainder(a) {
        var r = nbi();
        this.divRemTo(a, null, r);
        return r;
    }
    // (public) [this/a,this%a]
    function bnDivideAndRemainder(a) {
        var q = nbi(), r = nbi();
        this.divRemTo(a, q, r);
        return new Array(q, r);
    }
    // (protected) this *= n, this >= 0, 1 < n < DV
    function bnpDMultiply(n) {
        this[this.t] = this.am(0, n - 1, this, 0, 0, this.t);
        ++this.t;
        this.clamp();
    }
    // (protected) this += n << w words, this >= 0
    function bnpDAddOffset(n, w) {
        if (n == 0) return;
        while(this.t <= w)this[this.t++] = 0;
        this[w] += n;
        while(this[w] >= this.DV){
            this[w] -= this.DV;
            if (++w >= this.t) this[this.t++] = 0;
            ++this[w];
        }
    }
    // A "null" reducer
    function NullExp() {
    }
    function nNop(x) {
        return x;
    }
    function nMulTo(x, y, r) {
        x.multiplyTo(y, r);
    }
    function nSqrTo(x, r) {
        x.squareTo(r);
    }
    NullExp.prototype.convert = nNop;
    NullExp.prototype.revert = nNop;
    NullExp.prototype.mulTo = nMulTo;
    NullExp.prototype.sqrTo = nSqrTo;
    // (public) this^e
    function bnPow(e) {
        return this.exp(e, new NullExp());
    }
    // (protected) r = lower n words of "this * a", a.t <= n
    // "this" should be the larger one if appropriate.
    function bnpMultiplyLowerTo(a, n, r) {
        var i = Math.min(this.t + a.t, n);
        r.s = 0; // assumes a,this >= 0
        r.t = i;
        while(i > 0)r[--i] = 0;
        var j;
        for(j = r.t - this.t; i < j; ++i)r[i + this.t] = this.am(0, a[i], r, i, 0, this.t);
        for(j = Math.min(a.t, n); i < j; ++i)this.am(0, a[i], r, i, 0, n - i);
        r.clamp();
    }
    // (protected) r = "this * a" without lower n words, n > 0
    // "this" should be the larger one if appropriate.
    function bnpMultiplyUpperTo(a, n, r) {
        --n;
        var i = r.t = this.t + a.t - n;
        r.s = 0; // assumes a,this >= 0
        while(--i >= 0)r[i] = 0;
        for(i = Math.max(n - this.t, 0); i < a.t; ++i)r[this.t + i - n] = this.am(n - i, a[i], r, 0, 0, this.t + i - n);
        r.clamp();
        r.drShiftTo(1, r);
    }
    // Barrett modular reduction
    function Barrett(m) {
        // setup Barrett
        this.r2 = nbi();
        this.q3 = nbi();
        BigInteger.ONE.dlShiftTo(2 * m.t, this.r2);
        this.mu = this.r2.divide(m);
        this.m = m;
    }
    function barrettConvert(x) {
        if (x.s < 0 || x.t > 2 * this.m.t) return x.mod(this.m);
        else if (x.compareTo(this.m) < 0) return x;
        else {
            var r = nbi();
            x.copyTo(r);
            this.reduce(r);
            return r;
        }
    }
    function barrettRevert(x) {
        return x;
    }
    // x = x mod m (HAC 14.42)
    function barrettReduce(x) {
        x.drShiftTo(this.m.t - 1, this.r2);
        if (x.t > this.m.t + 1) {
            x.t = this.m.t + 1;
            x.clamp();
        }
        this.mu.multiplyUpperTo(this.r2, this.m.t + 1, this.q3);
        this.m.multiplyLowerTo(this.q3, this.m.t + 1, this.r2);
        while(x.compareTo(this.r2) < 0)x.dAddOffset(1, this.m.t + 1);
        x.subTo(this.r2, x);
        while(x.compareTo(this.m) >= 0)x.subTo(this.m, x);
    }
    // r = x^2 mod m; x != r
    function barrettSqrTo(x, r) {
        x.squareTo(r);
        this.reduce(r);
    }
    // r = x*y mod m; x,y != r
    function barrettMulTo(x, y, r) {
        x.multiplyTo(y, r);
        this.reduce(r);
    }
    Barrett.prototype.convert = barrettConvert;
    Barrett.prototype.revert = barrettRevert;
    Barrett.prototype.reduce = barrettReduce;
    Barrett.prototype.mulTo = barrettMulTo;
    Barrett.prototype.sqrTo = barrettSqrTo;
    // (public) this^e % m (HAC 14.85)
    function bnModPow(e, m) {
        var i = e.bitLength(), k, r = nbv(1), z;
        if (i <= 0) return r;
        else if (i < 18) k = 1;
        else if (i < 48) k = 3;
        else if (i < 144) k = 4;
        else if (i < 768) k = 5;
        else k = 6;
        if (i < 8) z = new Classic(m);
        else if (m.isEven()) z = new Barrett(m);
        else z = new Montgomery(m);
        // precomputation
        var g = new Array(), n = 3, k1 = k - 1, km = (1 << k) - 1;
        g[1] = z.convert(this);
        if (k > 1) {
            var g2 = nbi();
            z.sqrTo(g[1], g2);
            while(n <= km){
                g[n] = nbi();
                z.mulTo(g2, g[n - 2], g[n]);
                n += 2;
            }
        }
        var j = e.t - 1, w, is1 = true, r2 = nbi(), t;
        i = nbits(e[j]) - 1;
        while(j >= 0){
            if (i >= k1) w = e[j] >> i - k1 & km;
            else {
                w = (e[j] & (1 << i + 1) - 1) << k1 - i;
                if (j > 0) w |= e[j - 1] >> this.DB + i - k1;
            }
            n = k;
            while((w & 1) == 0){
                w >>= 1;
                --n;
            }
            if ((i -= n) < 0) {
                i += this.DB;
                --j;
            }
            if (is1) {
                g[w].copyTo(r);
                is1 = false;
            } else {
                while(n > 1){
                    z.sqrTo(r, r2);
                    z.sqrTo(r2, r);
                    n -= 2;
                }
                if (n > 0) z.sqrTo(r, r2);
                else {
                    t = r;
                    r = r2;
                    r2 = t;
                }
                z.mulTo(r2, g[w], r);
            }
            while(j >= 0 && (e[j] & 1 << i) == 0){
                z.sqrTo(r, r2);
                t = r;
                r = r2;
                r2 = t;
                if (--i < 0) {
                    i = this.DB - 1;
                    --j;
                }
            }
        }
        return z.revert(r);
    }
    // (public) gcd(this,a) (HAC 14.54)
    function bnGCD(a) {
        var x = this.s < 0 ? this.negate() : this.clone();
        var y = a.s < 0 ? a.negate() : a.clone();
        if (x.compareTo(y) < 0) {
            var t = x;
            x = y;
            y = t;
        }
        var i = x.getLowestSetBit(), g = y.getLowestSetBit();
        if (g < 0) return x;
        if (i < g) g = i;
        if (g > 0) {
            x.rShiftTo(g, x);
            y.rShiftTo(g, y);
        }
        while(x.signum() > 0){
            if ((i = x.getLowestSetBit()) > 0) x.rShiftTo(i, x);
            if ((i = y.getLowestSetBit()) > 0) y.rShiftTo(i, y);
            if (x.compareTo(y) >= 0) {
                x.subTo(y, x);
                x.rShiftTo(1, x);
            } else {
                y.subTo(x, y);
                y.rShiftTo(1, y);
            }
        }
        if (g > 0) y.lShiftTo(g, y);
        return y;
    }
    // (protected) this % n, n < 2^26
    function bnpModInt(n) {
        if (n <= 0) return 0;
        var d = this.DV % n, r = this.s < 0 ? n - 1 : 0;
        if (this.t > 0) {
            if (d == 0) r = this[0] % n;
            else for(var i = this.t - 1; i >= 0; --i)r = (d * r + this[i]) % n;
        }
        return r;
    }
    // (public) 1/this % m (HAC 14.61)
    function bnModInverse(m) {
        var ac = m.isEven();
        if (this.isEven() && ac || m.signum() == 0) return BigInteger.ZERO;
        var u = m.clone(), v = this.clone();
        var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1);
        while(u.signum() != 0){
            while(u.isEven()){
                u.rShiftTo(1, u);
                if (ac) {
                    if (!a.isEven() || !b.isEven()) {
                        a.addTo(this, a);
                        b.subTo(m, b);
                    }
                    a.rShiftTo(1, a);
                } else if (!b.isEven()) b.subTo(m, b);
                b.rShiftTo(1, b);
            }
            while(v.isEven()){
                v.rShiftTo(1, v);
                if (ac) {
                    if (!c.isEven() || !d.isEven()) {
                        c.addTo(this, c);
                        d.subTo(m, d);
                    }
                    c.rShiftTo(1, c);
                } else if (!d.isEven()) d.subTo(m, d);
                d.rShiftTo(1, d);
            }
            if (u.compareTo(v) >= 0) {
                u.subTo(v, u);
                if (ac) a.subTo(c, a);
                b.subTo(d, b);
            } else {
                v.subTo(u, v);
                if (ac) c.subTo(a, c);
                d.subTo(b, d);
            }
        }
        if (v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO;
        if (d.compareTo(m) >= 0) return d.subtract(m);
        if (d.signum() < 0) d.addTo(m, d);
        else return d;
        if (d.signum() < 0) return d.add(m);
        else return d;
    }
    var lowprimes = [
        2,
        3,
        5,
        7,
        11,
        13,
        17,
        19,
        23,
        29,
        31,
        37,
        41,
        43,
        47,
        53,
        59,
        61,
        67,
        71,
        73,
        79,
        83,
        89,
        97,
        101,
        103,
        107,
        109,
        113,
        127,
        131,
        137,
        139,
        149,
        151,
        157,
        163,
        167,
        173,
        179,
        181,
        191,
        193,
        197,
        199,
        211,
        223,
        227,
        229,
        233,
        239,
        241,
        251,
        257,
        263,
        269,
        271,
        277,
        281,
        283,
        293,
        307,
        311,
        313,
        317,
        331,
        337,
        347,
        349,
        353,
        359,
        367,
        373,
        379,
        383,
        389,
        397,
        401,
        409,
        419,
        421,
        431,
        433,
        439,
        443,
        449,
        457,
        461,
        463,
        467,
        479,
        487,
        491,
        499,
        503,
        509,
        521,
        523,
        541,
        547,
        557,
        563,
        569,
        571,
        577,
        587,
        593,
        599,
        601,
        607,
        613,
        617,
        619,
        631,
        641,
        643,
        647,
        653,
        659,
        661,
        673,
        677,
        683,
        691,
        701,
        709,
        719,
        727,
        733,
        739,
        743,
        751,
        757,
        761,
        769,
        773,
        787,
        797,
        809,
        811,
        821,
        823,
        827,
        829,
        839,
        853,
        857,
        859,
        863,
        877,
        881,
        883,
        887,
        907,
        911,
        919,
        929,
        937,
        941,
        947,
        953,
        967,
        971,
        977,
        983,
        991,
        997
    ];
    var lplim = 67108864 / lowprimes[lowprimes.length - 1];
    // (public) test primality with certainty >= 1-.5^t
    function bnIsProbablePrime(t) {
        var i, x = this.abs();
        if (x.t == 1 && x[0] <= lowprimes[lowprimes.length - 1]) {
            for(i = 0; i < lowprimes.length; ++i)if (x[0] == lowprimes[i]) return true;
            return false;
        }
        if (x.isEven()) return false;
        i = 1;
        while(i < lowprimes.length){
            var m = lowprimes[i], j = i + 1;
            while(j < lowprimes.length && m < lplim)m *= lowprimes[j++];
            m = x.modInt(m);
            while(i < j)if (m % lowprimes[i++] == 0) return false;
        }
        return x.millerRabin(t);
    }
    // (protected) true if probably prime (HAC 4.24, Miller-Rabin)
    function bnpMillerRabin(t) {
        var n1 = this.subtract(BigInteger.ONE);
        var k = n1.getLowestSetBit();
        if (k <= 0) return false;
        var r = n1.shiftRight(k);
        t = t + 1 >> 1;
        if (t > lowprimes.length) t = lowprimes.length;
        var a = nbi();
        for(var i = 0; i < t; ++i){
            //Pick bases at random, instead of starting at 2
            a.fromInt(lowprimes[Math.floor(Math.random() * lowprimes.length)]);
            var y = a.modPow(r, this);
            if (y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) {
                var j = 1;
                while((j++) < k && y.compareTo(n1) != 0){
                    y = y.modPowInt(2, this);
                    if (y.compareTo(BigInteger.ONE) == 0) return false;
                }
                if (y.compareTo(n1) != 0) return false;
            }
        }
        return true;
    }
    // protected
    BigInteger.prototype.chunkSize = bnpChunkSize;
    BigInteger.prototype.toRadix = bnpToRadix;
    BigInteger.prototype.fromRadix = bnpFromRadix;
    BigInteger.prototype.fromNumber = bnpFromNumber;
    BigInteger.prototype.bitwiseTo = bnpBitwiseTo;
    BigInteger.prototype.changeBit = bnpChangeBit;
    BigInteger.prototype.addTo = bnpAddTo;
    BigInteger.prototype.dMultiply = bnpDMultiply;
    BigInteger.prototype.dAddOffset = bnpDAddOffset;
    BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo;
    BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo;
    BigInteger.prototype.modInt = bnpModInt;
    BigInteger.prototype.millerRabin = bnpMillerRabin;
    // public
    BigInteger.prototype.clone = bnClone;
    BigInteger.prototype.intValue = bnIntValue;
    BigInteger.prototype.byteValue = bnByteValue;
    BigInteger.prototype.shortValue = bnShortValue;
    BigInteger.prototype.signum = bnSigNum;
    BigInteger.prototype.toByteArray = bnToByteArray;
    BigInteger.prototype.equals = bnEquals;
    BigInteger.prototype.min = bnMin;
    BigInteger.prototype.max = bnMax;
    BigInteger.prototype.and = bnAnd;
    BigInteger.prototype.or = bnOr;
    BigInteger.prototype.xor = bnXor;
    BigInteger.prototype.andNot = bnAndNot;
    BigInteger.prototype.not = bnNot;
    BigInteger.prototype.shiftLeft = bnShiftLeft;
    BigInteger.prototype.shiftRight = bnShiftRight;
    BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit;
    BigInteger.prototype.bitCount = bnBitCount;
    BigInteger.prototype.testBit = bnTestBit;
    BigInteger.prototype.setBit = bnSetBit;
    BigInteger.prototype.clearBit = bnClearBit;
    BigInteger.prototype.flipBit = bnFlipBit;
    BigInteger.prototype.add = bnAdd;
    BigInteger.prototype.subtract = bnSubtract;
    BigInteger.prototype.multiply = bnMultiply;
    BigInteger.prototype.divide = bnDivide;
    BigInteger.prototype.remainder = bnRemainder;
    BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder;
    BigInteger.prototype.modPow = bnModPow;
    BigInteger.prototype.modInverse = bnModInverse;
    BigInteger.prototype.pow = bnPow;
    BigInteger.prototype.gcd = bnGCD;
    BigInteger.prototype.isProbablePrime = bnIsProbablePrime;
    // JSBN-specific extension
    BigInteger.prototype.square = bnSquare;
    // Expose the Barrett function
    BigInteger.prototype.Barrett = Barrett;
    // BigInteger interfaces not implemented in jsbn:
    // BigInteger(int signum, byte[] magnitude)
    // double doubleValue()
    // float floatValue()
    // int hashCode()
    // long longValue()
    // static BigInteger valueOf(long val)
    // Random number generator - requires a PRNG backend, e.g. prng4.js
    // For best results, put code like
    // <body onClick='rng_seed_time();' onKeyPress='rng_seed_time();'>
    // in your main HTML document.
    var rng_state;
    var rng_pool;
    var rng_pptr;
    // Mix in a 32-bit integer into the pool
    function rng_seed_int(x) {
        rng_pool[rng_pptr++] ^= x & 255;
        rng_pool[rng_pptr++] ^= x >> 8 & 255;
        rng_pool[rng_pptr++] ^= x >> 16 & 255;
        rng_pool[rng_pptr++] ^= x >> 24 & 255;
        if (rng_pptr >= rng_psize) rng_pptr -= rng_psize;
    }
    // Mix in the current time (w/milliseconds) into the pool
    function rng_seed_time() {
        rng_seed_int(new Date().getTime());
    }
    // Initialize the pool with junk if needed.
    if (rng_pool == null) {
        rng_pool = new Array();
        rng_pptr = 0;
        var t1;
        if (typeof window !== "undefined" && window.crypto) {
            if (window.crypto.getRandomValues) {
                // Use webcrypto if available
                var ua = new Uint8Array(32);
                window.crypto.getRandomValues(ua);
                for(t1 = 0; t1 < 32; ++t1)rng_pool[rng_pptr++] = ua[t1];
            } else if (navigator.appName == "Netscape" && navigator.appVersion < "5") {
                // Extract entropy (256 bits) from NS4 RNG if available
                var z1 = window.crypto.random(32);
                for(t1 = 0; t1 < z1.length; ++t1)rng_pool[rng_pptr++] = z1.charCodeAt(t1) & 255;
            }
        }
        while(rng_pptr < rng_psize){
            t1 = Math.floor(65536 * Math.random());
            rng_pool[rng_pptr++] = t1 >>> 8;
            rng_pool[rng_pptr++] = t1 & 255;
        }
        rng_pptr = 0;
        rng_seed_time();
    //rng_seed_int(window.screenX);
    //rng_seed_int(window.screenY);
    }
    function rng_get_byte() {
        if (rng_state == null) {
            rng_seed_time();
            rng_state = prng_newstate();
            rng_state.init(rng_pool);
            for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr)rng_pool[rng_pptr] = 0;
            rng_pptr = 0;
        //rng_pool = null;
        }
        // TODO: allow reseeding after first request
        return rng_state.next();
    }
    function rng_get_bytes(ba) {
        var i;
        for(i = 0; i < ba.length; ++i)ba[i] = rng_get_byte();
    }
    function SecureRandom() {
    }
    SecureRandom.prototype.nextBytes = rng_get_bytes;
    // prng4.js - uses Arcfour as a PRNG
    function Arcfour() {
        this.i = 0;
        this.j = 0;
        this.S = new Array();
    }
    // Initialize arcfour context from key, an array of ints, each from [0..255]
    function ARC4init(key) {
        var i, j, t;
        for(i = 0; i < 256; ++i)this.S[i] = i;
        j = 0;
        for(i = 0; i < 256; ++i){
            j = j + this.S[i] + key[i % key.length] & 255;
            t = this.S[i];
            this.S[i] = this.S[j];
            this.S[j] = t;
        }
        this.i = 0;
        this.j = 0;
    }
    function ARC4next() {
        var t;
        this.i = this.i + 1 & 255;
        this.j = this.j + this.S[this.i] & 255;
        t = this.S[this.i];
        this.S[this.i] = this.S[this.j];
        this.S[this.j] = t;
        return this.S[t + this.S[this.i] & 255];
    }
    Arcfour.prototype.init = ARC4init;
    Arcfour.prototype.next = ARC4next;
    // Plug in your RNG constructor here
    function prng_newstate() {
        return new Arcfour();
    }
    // Pool size must be a multiple of 4 and greater than 32.
    // An array of bytes the size of the pool will be passed to init()
    var rng_psize = 256;
    if (typeof exports !== 'undefined') exports = module.exports = {
        default: BigInteger,
        BigInteger: BigInteger,
        SecureRandom: SecureRandom
    };
    else this.jsbn = {
        BigInteger: BigInteger,
        SecureRandom: SecureRandom
    };
}).call(this);

},{}],"5Vzwd":[function(require,module,exports) {
/* global window, exports, define */ !function() {
    var re = {
        not_string: /[^s]/,
        not_bool: /[^t]/,
        not_type: /[^T]/,
        not_primitive: /[^v]/,
        number: /[diefg]/,
        numeric_arg: /[bcdiefguxX]/,
        json: /[j]/,
        not_json: /[^j]/,
        text: /^[^\x25]+/,
        modulo: /^\x25{2}/,
        placeholder: /^\x25(?:([1-9]\d*)\$|\(([^)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijostTuvxX])/,
        key: /^([a-z_][a-z_\d]*)/i,
        key_access: /^\.([a-z_][a-z_\d]*)/i,
        index_access: /^\[(\d+)\]/,
        sign: /^[+-]/
    };
    function sprintf(key) {
        // `arguments` is not an array, but should be fine for this call
        return sprintf_format(sprintf_parse(key), arguments);
    }
    function vsprintf(fmt, argv) {
        return sprintf.apply(null, [
            fmt
        ].concat(argv || []));
    }
    function sprintf_format(parse_tree, argv) {
        var cursor = 1, tree_length = parse_tree.length, arg, output = '', i, k, ph, pad, pad_character, pad_length, is_positive, sign;
        for(i = 0; i < tree_length; i++){
            if (typeof parse_tree[i] === 'string') output += parse_tree[i];
            else if (typeof parse_tree[i] === 'object') {
                ph = parse_tree[i] // convenience purposes only
                ;
                if (ph.keys) {
                    arg = argv[cursor];
                    for(k = 0; k < ph.keys.length; k++){
                        if (arg == undefined) throw new Error(sprintf('[sprintf] Cannot access property "%s" of undefined value "%s"', ph.keys[k], ph.keys[k - 1]));
                        arg = arg[ph.keys[k]];
                    }
                } else if (ph.param_no) arg = argv[ph.param_no];
                else arg = argv[cursor++];
                if (re.not_type.test(ph.type) && re.not_primitive.test(ph.type) && arg instanceof Function) arg = arg();
                if (re.numeric_arg.test(ph.type) && typeof arg !== 'number' && isNaN(arg)) throw new TypeError(sprintf('[sprintf] expecting number but found %T', arg));
                if (re.number.test(ph.type)) is_positive = arg >= 0;
                switch(ph.type){
                    case 'b':
                        arg = parseInt(arg, 10).toString(2);
                        break;
                    case 'c':
                        arg = String.fromCharCode(parseInt(arg, 10));
                        break;
                    case 'd':
                    case 'i':
                        arg = parseInt(arg, 10);
                        break;
                    case 'j':
                        arg = JSON.stringify(arg, null, ph.width ? parseInt(ph.width) : 0);
                        break;
                    case 'e':
                        arg = ph.precision ? parseFloat(arg).toExponential(ph.precision) : parseFloat(arg).toExponential();
                        break;
                    case 'f':
                        arg = ph.precision ? parseFloat(arg).toFixed(ph.precision) : parseFloat(arg);
                        break;
                    case 'g':
                        arg = ph.precision ? String(Number(arg.toPrecision(ph.precision))) : parseFloat(arg);
                        break;
                    case 'o':
                        arg = (parseInt(arg, 10) >>> 0).toString(8);
                        break;
                    case 's':
                        arg = String(arg);
                        arg = ph.precision ? arg.substring(0, ph.precision) : arg;
                        break;
                    case 't':
                        arg = String(!!arg);
                        arg = ph.precision ? arg.substring(0, ph.precision) : arg;
                        break;
                    case 'T':
                        arg = Object.prototype.toString.call(arg).slice(8, -1).toLowerCase();
                        arg = ph.precision ? arg.substring(0, ph.precision) : arg;
                        break;
                    case 'u':
                        arg = parseInt(arg, 10) >>> 0;
                        break;
                    case 'v':
                        arg = arg.valueOf();
                        arg = ph.precision ? arg.substring(0, ph.precision) : arg;
                        break;
                    case 'x':
                        arg = (parseInt(arg, 10) >>> 0).toString(16);
                        break;
                    case 'X':
                        arg = (parseInt(arg, 10) >>> 0).toString(16).toUpperCase();
                        break;
                }
                if (re.json.test(ph.type)) output += arg;
                else {
                    if (re.number.test(ph.type) && (!is_positive || ph.sign)) {
                        sign = is_positive ? '+' : '-';
                        arg = arg.toString().replace(re.sign, '');
                    } else sign = '';
                    pad_character = ph.pad_char ? ph.pad_char === '0' ? '0' : ph.pad_char.charAt(1) : ' ';
                    pad_length = ph.width - (sign + arg).length;
                    pad = ph.width ? pad_length > 0 ? pad_character.repeat(pad_length) : '' : '';
                    output += ph.align ? sign + arg + pad : pad_character === '0' ? sign + pad + arg : pad + sign + arg;
                }
            }
        }
        return output;
    }
    var sprintf_cache = Object.create(null);
    function sprintf_parse(fmt) {
        if (sprintf_cache[fmt]) return sprintf_cache[fmt];
        var _fmt = fmt, match, parse_tree = [], arg_names = 0;
        while(_fmt){
            if ((match = re.text.exec(_fmt)) !== null) parse_tree.push(match[0]);
            else if ((match = re.modulo.exec(_fmt)) !== null) parse_tree.push('%');
            else if ((match = re.placeholder.exec(_fmt)) !== null) {
                if (match[2]) {
                    arg_names |= 1;
                    var field_list = [], replacement_field = match[2], field_match = [];
                    if ((field_match = re.key.exec(replacement_field)) !== null) {
                        field_list.push(field_match[1]);
                        while((replacement_field = replacement_field.substring(field_match[0].length)) !== ''){
                            if ((field_match = re.key_access.exec(replacement_field)) !== null) field_list.push(field_match[1]);
                            else if ((field_match = re.index_access.exec(replacement_field)) !== null) field_list.push(field_match[1]);
                            else throw new SyntaxError('[sprintf] failed to parse named argument key');
                        }
                    } else throw new SyntaxError('[sprintf] failed to parse named argument key');
                    match[2] = field_list;
                } else arg_names |= 2;
                if (arg_names === 3) throw new Error('[sprintf] mixing positional and named placeholders is not (yet) supported');
                parse_tree.push({
                    placeholder: match[0],
                    param_no: match[1],
                    keys: match[2],
                    sign: match[3],
                    pad_char: match[4],
                    align: match[5],
                    width: match[6],
                    precision: match[7],
                    type: match[8]
                });
            } else throw new SyntaxError('[sprintf] unexpected placeholder');
            _fmt = _fmt.substring(match[0].length);
        }
        return sprintf_cache[fmt] = parse_tree;
    }
    /**
     * export to either browser or node.js
     */ /* eslint-disable quote-props */ if (typeof exports !== 'undefined') {
        exports['sprintf'] = sprintf;
        exports['vsprintf'] = vsprintf;
    }
    if (typeof window !== 'undefined') {
        window['sprintf'] = sprintf;
        window['vsprintf'] = vsprintf;
        if (typeof define === 'function' && define['amd']) define(function() {
            return {
                'sprintf': sprintf,
                'vsprintf': vsprintf
            };
        });
    }
/* eslint-enable quote-props */ }(); // eslint-disable-line

},{}],"6aAh9":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
/**
 * Represents an IPv6 address
 * @class Address6
 * @param {string} address - An IPv6 address string
 * @param {number} [groups=8] - How many octets to parse
 * @example
 * var address = new Address6('2001::/32');
 */ parcelHelpers.export(exports, "Address6", ()=>Address6
);
/* eslint-disable prefer-destructuring */ /* eslint-disable no-param-reassign */ var _common = require("./common");
var _constants = require("./v4/constants");
var _constants1 = require("./v6/constants");
var _helpers = require("./v6/helpers");
var _ipv4 = require("./ipv4");
var _regularExpressions = require("./v6/regular-expressions");
var _addressError = require("./address-error");
var _jsbn = require("jsbn");
var _sprintfJs = require("sprintf-js");
function assert(condition) {
    if (!condition) throw new Error('Assertion failed.');
}
function addCommas(number) {
    const r = /(\d+)(\d{3})/;
    while(r.test(number))number = number.replace(r, '$1,$2');
    return number;
}
function spanLeadingZeroes4(n) {
    n = n.replace(/^(0{1,})([1-9]+)$/, '<span class="parse-error">$1</span>$2');
    n = n.replace(/^(0{1,})(0)$/, '<span class="parse-error">$1</span>$2');
    return n;
}
/*
 * A helper function to compact an array
 */ function compact(address, slice) {
    const s1 = [];
    const s2 = [];
    let i;
    for(i = 0; i < address.length; i++){
        if (i < slice[0]) s1.push(address[i]);
        else if (i > slice[1]) s2.push(address[i]);
    }
    return s1.concat([
        'compact'
    ]).concat(s2);
}
function paddedHex(octet) {
    return _sprintfJs.sprintf('%04x', parseInt(octet, 16));
}
function unsignByte(b) {
    // eslint-disable-next-line no-bitwise
    return b & 255;
}
class Address6 {
    constructor(address, optionalGroups){
        this.addressMinusSuffix = '';
        this.parsedSubnet = '';
        this.subnet = '/128';
        this.subnetMask = 128;
        this.v4 = false;
        this.zone = '';
        // #region Attributes
        /**
         * Returns true if the given address is in the subnet of the current address
         * @memberof Address6
         * @instance
         * @returns {boolean}
         */ this.isInSubnet = _common.isInSubnet;
        /**
         * Returns true if the address is correct, false otherwise
         * @memberof Address6
         * @instance
         * @returns {boolean}
         */ this.isCorrect = _common.isCorrect(_constants1.BITS);
        if (optionalGroups === undefined) this.groups = _constants1.GROUPS;
        else this.groups = optionalGroups;
        this.address = address;
        const subnet = _constants1.RE_SUBNET_STRING.exec(address);
        if (subnet) {
            this.parsedSubnet = subnet[0].replace('/', '');
            this.subnetMask = parseInt(this.parsedSubnet, 10);
            this.subnet = `/${this.subnetMask}`;
            if (Number.isNaN(this.subnetMask) || this.subnetMask < 0 || this.subnetMask > _constants1.BITS) throw new _addressError.AddressError('Invalid subnet mask.');
            address = address.replace(_constants1.RE_SUBNET_STRING, '');
        } else if (/\//.test(address)) throw new _addressError.AddressError('Invalid subnet mask.');
        const zone = _constants1.RE_ZONE_STRING.exec(address);
        if (zone) {
            this.zone = zone[0];
            address = address.replace(_constants1.RE_ZONE_STRING, '');
        }
        this.addressMinusSuffix = address;
        this.parsedAddress = this.parse(this.addressMinusSuffix);
    }
    static isValid(address1) {
        try {
            // eslint-disable-next-line no-new
            new Address6(address1);
            return true;
        } catch (e) {
            return false;
        }
    }
    /**
     * Convert a BigInteger to a v6 address object
     * @memberof Address6
     * @static
     * @param {BigInteger} bigInteger - a BigInteger to convert
     * @returns {Address6}
     * @example
     * var bigInteger = new BigInteger('1000000000000');
     * var address = Address6.fromBigInteger(bigInteger);
     * address.correctForm(); // '::e8:d4a5:1000'
     */ static fromBigInteger(bigInteger) {
        const hex = bigInteger.toString(16).padStart(32, '0');
        const groups = [];
        let i;
        for(i = 0; i < _constants1.GROUPS; i++)groups.push(hex.slice(i * 4, (i + 1) * 4));
        return new Address6(groups.join(':'));
    }
    /**
     * Convert a URL (with optional port number) to an address object
     * @memberof Address6
     * @static
     * @param {string} url - a URL with optional port number
     * @example
     * var addressAndPort = Address6.fromURL('http://[ffff::]:8080/foo/');
     * addressAndPort.address.correctForm(); // 'ffff::'
     * addressAndPort.port; // 8080
     */ static fromURL(url) {
        let host;
        let port = null;
        let result;
        // If we have brackets parse them and find a port
        if (url.indexOf('[') !== -1 && url.indexOf(']:') !== -1) {
            result = _constants1.RE_URL_WITH_PORT.exec(url);
            if (result === null) return {
                error: 'failed to parse address with port',
                address: null,
                port: null
            };
            host = result[1];
            port = result[2];
        // If there's a URL extract the address
        } else if (url.indexOf('/') !== -1) {
            // Remove the protocol prefix
            url = url.replace(/^[a-z0-9]+:\/\//, '');
            // Parse the address
            result = _constants1.RE_URL.exec(url);
            if (result === null) return {
                error: 'failed to parse address from URL',
                address: null,
                port: null
            };
            host = result[1];
        // Otherwise just assign the URL to the host and let the library parse it
        } else host = url;
        // If there's a port convert it to an integer
        if (port) {
            port = parseInt(port, 10);
            // squelch out of range ports
            if (port < 0 || port > 65536) port = null;
        } else // Standardize `undefined` to `null`
        port = null;
        return {
            address: new Address6(host),
            port
        };
    }
    /**
     * Create an IPv6-mapped address given an IPv4 address
     * @memberof Address6
     * @static
     * @param {string} address - An IPv4 address string
     * @returns {Address6}
     * @example
     * var address = Address6.fromAddress4('192.168.0.1');
     * address.correctForm(); // '::ffff:c0a8:1'
     * address.to4in6(); // '::ffff:192.168.0.1'
     */ static fromAddress4(address2) {
        const address4 = new _ipv4.Address4(address2);
        const mask6 = _constants1.BITS - (_constants.BITS - address4.subnetMask);
        return new Address6(`::ffff:${address4.correctForm()}/${mask6}`);
    }
    /**
     * Return an address from ip6.arpa form
     * @memberof Address6
     * @static
     * @param {string} arpaFormAddress - an 'ip6.arpa' form address
     * @returns {Adress6}
     * @example
     * var address = Address6.fromArpa(e.f.f.f.3.c.2.6.f.f.f.e.6.6.8.e.1.0.6.7.9.4.e.c.0.0.0.0.1.0.0.2.ip6.arpa.)
     * address.correctForm(); // '2001:0:ce49:7601:e866:efff:62c3:fffe'
     */ static fromArpa(arpaFormAddress) {
        // remove ending ".ip6.arpa." or just "."
        let address = arpaFormAddress.replace(/(\.ip6\.arpa)?\.$/, '');
        const semicolonAmount = 7;
        // correct ip6.arpa form with ending removed will be 63 characters
        if (address.length !== 63) throw new _addressError.AddressError("Invalid 'ip6.arpa' form.");
        const parts = address.split('.').reverse();
        for(let i = semicolonAmount; i > 0; i--){
            const insertIndex = i * 4;
            parts.splice(insertIndex, 0, ':');
        }
        address = parts.join('');
        return new Address6(address);
    }
    /**
     * Return the Microsoft UNC transcription of the address
     * @memberof Address6
     * @instance
     * @returns {String} the Microsoft UNC transcription of the address
     */ microsoftTranscription() {
        return _sprintfJs.sprintf('%s.ipv6-literal.net', this.correctForm().replace(/:/g, '-'));
    }
    /**
     * Return the first n bits of the address, defaulting to the subnet mask
     * @memberof Address6
     * @instance
     * @param {number} [mask=subnet] - the number of bits to mask
     * @returns {String} the first n bits of the address as a string
     */ mask(mask = this.subnetMask) {
        return this.getBitsBase2(0, mask);
    }
    /**
     * Return the number of possible subnets of a given size in the address
     * @memberof Address6
     * @instance
     * @param {number} [size=128] - the subnet size
     * @returns {String}
     */ // TODO: probably useful to have a numeric version of this too
    possibleSubnets(subnetSize = 128) {
        const availableBits = _constants1.BITS - this.subnetMask;
        const subnetBits = Math.abs(subnetSize - _constants1.BITS);
        const subnetPowers = availableBits - subnetBits;
        if (subnetPowers < 0) return '0';
        return addCommas(new _jsbn.BigInteger('2', 10).pow(subnetPowers).toString(10));
    }
    /**
     * Helper function getting start address.
     * @memberof Address6
     * @instance
     * @returns {BigInteger}
     */ _startAddress() {
        return new _jsbn.BigInteger(this.mask() + '0'.repeat(_constants1.BITS - this.subnetMask), 2);
    }
    /**
     * The first address in the range given by this address' subnet
     * Often referred to as the Network Address.
     * @memberof Address6
     * @instance
     * @returns {Address6}
     */ startAddress() {
        return Address6.fromBigInteger(this._startAddress());
    }
    /**
     * The first host address in the range given by this address's subnet ie
     * the first address after the Network Address
     * @memberof Address6
     * @instance
     * @returns {Address6}
     */ startAddressExclusive() {
        const adjust = new _jsbn.BigInteger('1');
        return Address6.fromBigInteger(this._startAddress().add(adjust));
    }
    /**
     * Helper function getting end address.
     * @memberof Address6
     * @instance
     * @returns {BigInteger}
     */ _endAddress() {
        return new _jsbn.BigInteger(this.mask() + '1'.repeat(_constants1.BITS - this.subnetMask), 2);
    }
    /**
     * The last address in the range given by this address' subnet
     * Often referred to as the Broadcast
     * @memberof Address6
     * @instance
     * @returns {Address6}
     */ endAddress() {
        return Address6.fromBigInteger(this._endAddress());
    }
    /**
     * The last host address in the range given by this address's subnet ie
     * the last address prior to the Broadcast Address
     * @memberof Address6
     * @instance
     * @returns {Address6}
     */ endAddressExclusive() {
        const adjust = new _jsbn.BigInteger('1');
        return Address6.fromBigInteger(this._endAddress().subtract(adjust));
    }
    /**
     * Return the scope of the address
     * @memberof Address6
     * @instance
     * @returns {String}
     */ getScope() {
        let scope = _constants1.SCOPES[this.getBits(12, 16).intValue()];
        if (this.getType() === 'Global unicast' && scope !== 'Link local') scope = 'Global';
        return scope || 'Unknown';
    }
    /**
     * Return the type of the address
     * @memberof Address6
     * @instance
     * @returns {String}
     */ getType() {
        for (const subnet of Object.keys(_constants1.TYPES)){
            if (this.isInSubnet(new Address6(subnet))) return _constants1.TYPES[subnet];
        }
        return 'Global unicast';
    }
    /**
     * Return the bits in the given range as a BigInteger
     * @memberof Address6
     * @instance
     * @returns {BigInteger}
     */ getBits(start, end) {
        return new _jsbn.BigInteger(this.getBitsBase2(start, end), 2);
    }
    /**
     * Return the bits in the given range as a base-2 string
     * @memberof Address6
     * @instance
     * @returns {String}
     */ getBitsBase2(start1, end1) {
        return this.binaryZeroPad().slice(start1, end1);
    }
    /**
     * Return the bits in the given range as a base-16 string
     * @memberof Address6
     * @instance
     * @returns {String}
     */ getBitsBase16(start2, end2) {
        const length = end2 - start2;
        if (length % 4 !== 0) throw new Error('Length of bits to retrieve must be divisible by four');
        return this.getBits(start2, end2).toString(16).padStart(length / 4, '0');
    }
    /**
     * Return the bits that are set past the subnet mask length
     * @memberof Address6
     * @instance
     * @returns {String}
     */ getBitsPastSubnet() {
        return this.getBitsBase2(this.subnetMask, _constants1.BITS);
    }
    /**
     * Return the reversed ip6.arpa form of the address
     * @memberof Address6
     * @param {Object} options
     * @param {boolean} options.omitSuffix - omit the "ip6.arpa" suffix
     * @instance
     * @returns {String}
     */ reverseForm(options) {
        if (!options) options = {
        };
        const characters = Math.floor(this.subnetMask / 4);
        const reversed = this.canonicalForm().replace(/:/g, '').split('').slice(0, characters).reverse().join('.');
        if (characters > 0) {
            if (options.omitSuffix) return reversed;
            return _sprintfJs.sprintf('%s.ip6.arpa.', reversed);
        }
        if (options.omitSuffix) return '';
        return 'ip6.arpa.';
    }
    /**
     * Return the correct form of the address
     * @memberof Address6
     * @instance
     * @returns {String}
     */ correctForm() {
        let i;
        let groups = [];
        let zeroCounter = 0;
        const zeroes = [];
        for(i = 0; i < this.parsedAddress.length; i++){
            const value = parseInt(this.parsedAddress[i], 16);
            if (value === 0) zeroCounter++;
            if (value !== 0 && zeroCounter > 0) {
                if (zeroCounter > 1) zeroes.push([
                    i - zeroCounter,
                    i - 1
                ]);
                zeroCounter = 0;
            }
        }
        // Do we end with a string of zeroes?
        if (zeroCounter > 1) zeroes.push([
            this.parsedAddress.length - zeroCounter,
            this.parsedAddress.length - 1
        ]);
        const zeroLengths = zeroes.map((n)=>n[1] - n[0] + 1
        );
        if (zeroes.length > 0) {
            const index = zeroLengths.indexOf(Math.max(...zeroLengths));
            groups = compact(this.parsedAddress, zeroes[index]);
        } else groups = this.parsedAddress;
        for(i = 0; i < groups.length; i++)if (groups[i] !== 'compact') groups[i] = parseInt(groups[i], 16).toString(16);
        let correct = groups.join(':');
        correct = correct.replace(/^compact$/, '::');
        correct = correct.replace(/^compact|compact$/, ':');
        correct = correct.replace(/compact/, '');
        return correct;
    }
    /**
     * Return a zero-padded base-2 string representation of the address
     * @memberof Address6
     * @instance
     * @returns {String}
     * @example
     * var address = new Address6('2001:4860:4001:803::1011');
     * address.binaryZeroPad();
     * // '0010000000000001010010000110000001000000000000010000100000000011
     * //  0000000000000000000000000000000000000000000000000001000000010001'
     */ binaryZeroPad() {
        return this.bigInteger().toString(2).padStart(_constants1.BITS, '0');
    }
    // TODO: Improve the semantics of this helper function
    parse4in6(address3) {
        const groups = address3.split(':');
        const lastGroup = groups.slice(-1)[0];
        const address4 = lastGroup.match(_constants.RE_ADDRESS);
        if (address4) {
            this.parsedAddress4 = address4[0];
            this.address4 = new _ipv4.Address4(this.parsedAddress4);
            for(let i = 0; i < this.address4.groups; i++){
                if (/^0[0-9]+/.test(this.address4.parsedAddress[i])) throw new _addressError.AddressError("IPv4 addresses can't have leading zeroes.", address3.replace(_constants.RE_ADDRESS, this.address4.parsedAddress.map(spanLeadingZeroes4).join('.')));
            }
            this.v4 = true;
            groups[groups.length - 1] = this.address4.toGroup6();
            address3 = groups.join(':');
        }
        return address3;
    }
    // TODO: Make private?
    parse(address4) {
        address4 = this.parse4in6(address4);
        const badCharacters = address4.match(_constants1.RE_BAD_CHARACTERS);
        if (badCharacters) throw new _addressError.AddressError(_sprintfJs.sprintf('Bad character%s detected in address: %s', badCharacters.length > 1 ? 's' : '', badCharacters.join('')), address4.replace(_constants1.RE_BAD_CHARACTERS, '<span class="parse-error">$1</span>'));
        const badAddress = address4.match(_constants1.RE_BAD_ADDRESS);
        if (badAddress) throw new _addressError.AddressError(_sprintfJs.sprintf('Address failed regex: %s', badAddress.join('')), address4.replace(_constants1.RE_BAD_ADDRESS, '<span class="parse-error">$1</span>'));
        let groups = [];
        const halves = address4.split('::');
        if (halves.length === 2) {
            let first = halves[0].split(':');
            let last = halves[1].split(':');
            if (first.length === 1 && first[0] === '') first = [];
            if (last.length === 1 && last[0] === '') last = [];
            const remaining = this.groups - (first.length + last.length);
            if (!remaining) throw new _addressError.AddressError('Error parsing groups');
            this.elidedGroups = remaining;
            this.elisionBegin = first.length;
            this.elisionEnd = first.length + this.elidedGroups;
            groups = groups.concat(first);
            for(let i = 0; i < remaining; i++)groups.push('0');
            groups = groups.concat(last);
        } else if (halves.length === 1) {
            groups = address4.split(':');
            this.elidedGroups = 0;
        } else throw new _addressError.AddressError('Too many :: groups found');
        groups = groups.map((group)=>_sprintfJs.sprintf('%x', parseInt(group, 16))
        );
        if (groups.length !== this.groups) throw new _addressError.AddressError('Incorrect number of groups found');
        return groups;
    }
    /**
     * Return the canonical form of the address
     * @memberof Address6
     * @instance
     * @returns {String}
     */ canonicalForm() {
        return this.parsedAddress.map(paddedHex).join(':');
    }
    /**
     * Return the decimal form of the address
     * @memberof Address6
     * @instance
     * @returns {String}
     */ decimal() {
        return this.parsedAddress.map((n)=>_sprintfJs.sprintf('%05d', parseInt(n, 16))
        ).join(':');
    }
    /**
     * Return the address as a BigInteger
     * @memberof Address6
     * @instance
     * @returns {BigInteger}
     */ bigInteger() {
        return new _jsbn.BigInteger(this.parsedAddress.map(paddedHex).join(''), 16);
    }
    /**
     * Return the last two groups of this address as an IPv4 address string
     * @memberof Address6
     * @instance
     * @returns {Address4}
     * @example
     * var address = new Address6('2001:4860:4001::1825:bf11');
     * address.to4().correctForm(); // '24.37.191.17'
     */ to4() {
        const binary = this.binaryZeroPad().split('');
        return _ipv4.Address4.fromHex(new _jsbn.BigInteger(binary.slice(96, 128).join(''), 2).toString(16));
    }
    /**
     * Return the v4-in-v6 form of the address
     * @memberof Address6
     * @instance
     * @returns {String}
     */ to4in6() {
        const address4 = this.to4();
        const address6 = new Address6(this.parsedAddress.slice(0, 6).join(':'), 6);
        const correct = address6.correctForm();
        let infix = '';
        if (!/:$/.test(correct)) infix = ':';
        return correct + infix + address4.address;
    }
    /**
     * Return an object containing the Teredo properties of the address
     * @memberof Address6
     * @instance
     * @returns {Object}
     */ inspectTeredo() {
        /*
        - Bits 0 to 31 are set to the Teredo prefix (normally 2001:0000::/32).
        - Bits 32 to 63 embed the primary IPv4 address of the Teredo server that
          is used.
        - Bits 64 to 79 can be used to define some flags. Currently only the
          higher order bit is used; it is set to 1 if the Teredo client is
          located behind a cone NAT, 0 otherwise. For Microsoft's Windows Vista
          and Windows Server 2008 implementations, more bits are used. In those
          implementations, the format for these 16 bits is "CRAAAAUG AAAAAAAA",
          where "C" remains the "Cone" flag. The "R" bit is reserved for future
          use. The "U" bit is for the Universal/Local flag (set to 0). The "G" bit
          is Individual/Group flag (set to 0). The A bits are set to a 12-bit
          randomly generated number chosen by the Teredo client to introduce
          additional protection for the Teredo node against IPv6-based scanning
          attacks.
        - Bits 80 to 95 contains the obfuscated UDP port number. This is the
          port number that is mapped by the NAT to the Teredo client with all
          bits inverted.
        - Bits 96 to 127 contains the obfuscated IPv4 address. This is the
          public IPv4 address of the NAT with all bits inverted.
        */ const prefix = this.getBitsBase16(0, 32);
        const udpPort = this.getBits(80, 96).xor(new _jsbn.BigInteger('ffff', 16)).toString();
        const server4 = _ipv4.Address4.fromHex(this.getBitsBase16(32, 64));
        const client4 = _ipv4.Address4.fromHex(this.getBits(96, 128).xor(new _jsbn.BigInteger('ffffffff', 16)).toString(16));
        const flags = this.getBits(64, 80);
        const flagsBase2 = this.getBitsBase2(64, 80);
        const coneNat = flags.testBit(15);
        const reserved = flags.testBit(14);
        const groupIndividual = flags.testBit(8);
        const universalLocal = flags.testBit(9);
        const nonce = new _jsbn.BigInteger(flagsBase2.slice(2, 6) + flagsBase2.slice(8, 16), 2).toString(10);
        return {
            prefix: _sprintfJs.sprintf('%s:%s', prefix.slice(0, 4), prefix.slice(4, 8)),
            server4: server4.address,
            client4: client4.address,
            flags: flagsBase2,
            coneNat,
            microsoft: {
                reserved,
                universalLocal,
                groupIndividual,
                nonce
            },
            udpPort
        };
    }
    /**
     * Return an object containing the 6to4 properties of the address
     * @memberof Address6
     * @instance
     * @returns {Object}
     */ inspect6to4() {
        /*
        - Bits 0 to 15 are set to the 6to4 prefix (2002::/16).
        - Bits 16 to 48 embed the IPv4 address of the 6to4 gateway that is used.
        */ const prefix = this.getBitsBase16(0, 16);
        const gateway = _ipv4.Address4.fromHex(this.getBitsBase16(16, 48));
        return {
            prefix: _sprintfJs.sprintf('%s', prefix.slice(0, 4)),
            gateway: gateway.address
        };
    }
    /**
     * Return a v6 6to4 address from a v6 v4inv6 address
     * @memberof Address6
     * @instance
     * @returns {Address6}
     */ to6to4() {
        if (!this.is4()) return null;
        const addr6to4 = [
            '2002',
            this.getBitsBase16(96, 112),
            this.getBitsBase16(112, 128),
            '',
            '/16', 
        ].join(':');
        return new Address6(addr6to4);
    }
    /**
     * Return a byte array
     * @memberof Address6
     * @instance
     * @returns {Array}
     */ toByteArray() {
        const byteArray = this.bigInteger().toByteArray();
        // work around issue where `toByteArray` returns a leading 0 element
        if (byteArray.length === 17 && byteArray[0] === 0) return byteArray.slice(1);
        return byteArray;
    }
    /**
     * Return an unsigned byte array
     * @memberof Address6
     * @instance
     * @returns {Array}
     */ toUnsignedByteArray() {
        return this.toByteArray().map(unsignByte);
    }
    /**
     * Convert a byte array to an Address6 object
     * @memberof Address6
     * @static
     * @returns {Address6}
     */ static fromByteArray(bytes) {
        return this.fromUnsignedByteArray(bytes.map(unsignByte));
    }
    /**
     * Convert an unsigned byte array to an Address6 object
     * @memberof Address6
     * @static
     * @returns {Address6}
     */ static fromUnsignedByteArray(bytes1) {
        const BYTE_MAX = new _jsbn.BigInteger('256', 10);
        let result = new _jsbn.BigInteger('0', 10);
        let multiplier = new _jsbn.BigInteger('1', 10);
        for(let i = bytes1.length - 1; i >= 0; i--){
            result = result.add(multiplier.multiply(new _jsbn.BigInteger(bytes1[i].toString(10), 10)));
            multiplier = multiplier.multiply(BYTE_MAX);
        }
        return Address6.fromBigInteger(result);
    }
    /**
     * Returns true if the address is in the canonical form, false otherwise
     * @memberof Address6
     * @instance
     * @returns {boolean}
     */ isCanonical() {
        return this.addressMinusSuffix === this.canonicalForm();
    }
    /**
     * Returns true if the address is a link local address, false otherwise
     * @memberof Address6
     * @instance
     * @returns {boolean}
     */ isLinkLocal() {
        // Zeroes are required, i.e. we can't check isInSubnet with 'fe80::/10'
        if (this.getBitsBase2(0, 64) === '1111111010000000000000000000000000000000000000000000000000000000') return true;
        return false;
    }
    /**
     * Returns true if the address is a multicast address, false otherwise
     * @memberof Address6
     * @instance
     * @returns {boolean}
     */ isMulticast() {
        return this.getType() === 'Multicast';
    }
    /**
     * Returns true if the address is a v4-in-v6 address, false otherwise
     * @memberof Address6
     * @instance
     * @returns {boolean}
     */ is4() {
        return this.v4;
    }
    /**
     * Returns true if the address is a Teredo address, false otherwise
     * @memberof Address6
     * @instance
     * @returns {boolean}
     */ isTeredo() {
        return this.isInSubnet(new Address6('2001::/32'));
    }
    /**
     * Returns true if the address is a 6to4 address, false otherwise
     * @memberof Address6
     * @instance
     * @returns {boolean}
     */ is6to4() {
        return this.isInSubnet(new Address6('2002::/16'));
    }
    /**
     * Returns true if the address is a loopback address, false otherwise
     * @memberof Address6
     * @instance
     * @returns {boolean}
     */ isLoopback() {
        return this.getType() === 'Loopback';
    }
    // #endregion
    // #region HTML
    /**
     * @returns {String} the address in link form with a default port of 80
     */ href(optionalPort) {
        if (optionalPort === undefined) optionalPort = '';
        else optionalPort = _sprintfJs.sprintf(':%s', optionalPort);
        return _sprintfJs.sprintf('http://[%s]%s/', this.correctForm(), optionalPort);
    }
    /**
     * @returns {String} a link suitable for conveying the address via a URL hash
     */ link(options1) {
        if (!options1) options1 = {
        };
        if (options1.className === undefined) options1.className = '';
        if (options1.prefix === undefined) options1.prefix = '/#address=';
        if (options1.v4 === undefined) options1.v4 = false;
        let formFunction = this.correctForm;
        if (options1.v4) formFunction = this.to4in6;
        if (options1.className) return _sprintfJs.sprintf('<a href="%1$s%2$s" class="%3$s">%2$s</a>', options1.prefix, formFunction.call(this), options1.className);
        return _sprintfJs.sprintf('<a href="%1$s%2$s">%2$s</a>', options1.prefix, formFunction.call(this));
    }
    /**
     * Groups an address
     * @returns {String}
     */ group() {
        if (this.elidedGroups === 0) // The simple case
        return _helpers.simpleGroup(this.address).join(':');
        assert(typeof this.elidedGroups === 'number');
        assert(typeof this.elisionBegin === 'number');
        // The elided case
        const output = [];
        const [left, right] = this.address.split('::');
        if (left.length) output.push(..._helpers.simpleGroup(left));
        else output.push('');
        const classes = [
            'hover-group'
        ];
        for(let i = this.elisionBegin; i < this.elisionBegin + this.elidedGroups; i++)classes.push(_sprintfJs.sprintf('group-%d', i));
        output.push(_sprintfJs.sprintf('<span class="%s"></span>', classes.join(' ')));
        if (right.length) output.push(..._helpers.simpleGroup(right, this.elisionEnd));
        else output.push('');
        if (this.is4()) {
            assert(this.address4 instanceof _ipv4.Address4);
            output.pop();
            output.push(this.address4.groupForV6());
        }
        return output.join(':');
    }
    // #endregion
    // #region Regular expressions
    /**
     * Generate a regular expression string that can be used to find or validate
     * all variations of this address
     * @memberof Address6
     * @instance
     * @param {boolean} substringSearch
     * @returns {string}
     */ regularExpressionString(substringSearch = false) {
        let output = [];
        // TODO: revisit why this is necessary
        const address6 = new Address6(this.correctForm());
        if (address6.elidedGroups === 0) // The simple case
        output.push(_regularExpressions.simpleRegularExpression(address6.parsedAddress));
        else if (address6.elidedGroups === _constants1.GROUPS) // A completely elided address
        output.push(_regularExpressions.possibleElisions(_constants1.GROUPS));
        else {
            // A partially elided address
            const halves = address6.address.split('::');
            if (halves[0].length) output.push(_regularExpressions.simpleRegularExpression(halves[0].split(':')));
            assert(typeof address6.elidedGroups === 'number');
            output.push(_regularExpressions.possibleElisions(address6.elidedGroups, halves[0].length !== 0, halves[1].length !== 0));
            if (halves[1].length) output.push(_regularExpressions.simpleRegularExpression(halves[1].split(':')));
            output = [
                output.join(':')
            ];
        }
        if (!substringSearch) output = [
            '(?=^|',
            _regularExpressions.ADDRESS_BOUNDARY,
            '|[^\\w\\:])(',
            ...output,
            ')(?=[^\\w\\:]|',
            _regularExpressions.ADDRESS_BOUNDARY,
            '|$)', 
        ];
        return output.join('');
    }
    /**
     * Generate a regular expression that can be used to find or validate all
     * variations of this address.
     * @memberof Address6
     * @instance
     * @param {boolean} substringSearch
     * @returns {RegExp}
     */ regularExpression(substringSearch1 = false) {
        return new RegExp(this.regularExpressionString(substringSearch1), 'i');
    }
}

},{"./common":"7Q894","./v4/constants":"jDbQp","./v6/constants":"hNgps","./v6/helpers":"9TPlr","./ipv4":"hVqYT","./v6/regular-expressions":"fCubN","./address-error":"4u0zS","jsbn":"3AMga","sprintf-js":"5Vzwd","@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"hNgps":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "BITS", ()=>BITS
);
parcelHelpers.export(exports, "GROUPS", ()=>GROUPS
);
parcelHelpers.export(exports, "SCOPES", ()=>SCOPES
);
parcelHelpers.export(exports, "TYPES", ()=>TYPES
);
parcelHelpers.export(exports, "RE_BAD_CHARACTERS", ()=>RE_BAD_CHARACTERS
);
parcelHelpers.export(exports, "RE_BAD_ADDRESS", ()=>RE_BAD_ADDRESS
);
parcelHelpers.export(exports, "RE_SUBNET_STRING", ()=>RE_SUBNET_STRING
);
parcelHelpers.export(exports, "RE_ZONE_STRING", ()=>RE_ZONE_STRING
);
parcelHelpers.export(exports, "RE_URL", ()=>RE_URL
);
parcelHelpers.export(exports, "RE_URL_WITH_PORT", ()=>RE_URL_WITH_PORT
);
const BITS = 128;
const GROUPS = 8;
const SCOPES = {
    0: 'Reserved',
    1: 'Interface local',
    2: 'Link local',
    4: 'Admin local',
    5: 'Site local',
    8: 'Organization local',
    14: 'Global',
    15: 'Reserved'
};
const TYPES = {
    'ff01::1/128': 'Multicast (All nodes on this interface)',
    'ff01::2/128': 'Multicast (All routers on this interface)',
    'ff02::1/128': 'Multicast (All nodes on this link)',
    'ff02::2/128': 'Multicast (All routers on this link)',
    'ff05::2/128': 'Multicast (All routers in this site)',
    'ff02::5/128': 'Multicast (OSPFv3 AllSPF routers)',
    'ff02::6/128': 'Multicast (OSPFv3 AllDR routers)',
    'ff02::9/128': 'Multicast (RIP routers)',
    'ff02::a/128': 'Multicast (EIGRP routers)',
    'ff02::d/128': 'Multicast (PIM routers)',
    'ff02::16/128': 'Multicast (MLDv2 reports)',
    'ff01::fb/128': 'Multicast (mDNSv6)',
    'ff02::fb/128': 'Multicast (mDNSv6)',
    'ff05::fb/128': 'Multicast (mDNSv6)',
    'ff02::1:2/128': 'Multicast (All DHCP servers and relay agents on this link)',
    'ff05::1:2/128': 'Multicast (All DHCP servers and relay agents in this site)',
    'ff02::1:3/128': 'Multicast (All DHCP servers on this link)',
    'ff05::1:3/128': 'Multicast (All DHCP servers in this site)',
    '::/128': 'Unspecified',
    '::1/128': 'Loopback',
    'ff00::/8': 'Multicast',
    'fe80::/10': 'Link-local unicast'
};
const RE_BAD_CHARACTERS = /([^0-9a-f:/%])/gi;
const RE_BAD_ADDRESS = /([0-9a-f]{5,}|:{3,}|[^:]:$|^:[^:]|\/$)/gi;
const RE_SUBNET_STRING = /\/\d{1,3}(?=%|$)/;
const RE_ZONE_STRING = /%.*$/;
const RE_URL = new RegExp(/^\[{0,1}([0-9a-f:]+)\]{0,1}/);
const RE_URL_WITH_PORT = new RegExp(/\[([0-9a-f:]+)\]:([0-9]{1,5})/);

},{"@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"9TPlr":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
/**
 * @returns {String} the string with all zeroes contained in a <span>
 */ parcelHelpers.export(exports, "spanAllZeroes", ()=>spanAllZeroes
);
/**
 * @returns {String} the string with each character contained in a <span>
 */ parcelHelpers.export(exports, "spanAll", ()=>spanAll
);
/**
 * @returns {String} the string with leading zeroes contained in a <span>
 */ parcelHelpers.export(exports, "spanLeadingZeroes", ()=>spanLeadingZeroes
);
/**
 * Groups an address
 * @returns {String} a grouped address
 */ parcelHelpers.export(exports, "simpleGroup", ()=>simpleGroup
);
var _sprintfJs = require("sprintf-js");
function spanAllZeroes(s) {
    return s.replace(/(0+)/g, '<span class="zero">$1</span>');
}
function spanAll(s, offset = 0) {
    const letters = s.split('');
    return letters.map((n, i)=>_sprintfJs.sprintf('<span class="digit value-%s position-%d">%s</span>', n, i + offset, spanAllZeroes(n)) // XXX Use #base-2 .value-0 instead?
    ).join('');
}
function spanLeadingZeroesSimple(group) {
    return group.replace(/^(0+)/, '<span class="zero">$1</span>');
}
function spanLeadingZeroes(address) {
    const groups = address.split(':');
    return groups.map((g)=>spanLeadingZeroesSimple(g)
    ).join(':');
}
function simpleGroup(addressString, offset = 0) {
    const groups = addressString.split(':');
    return groups.map((g, i)=>{
        if (/group-v4/.test(g)) return g;
        return _sprintfJs.sprintf('<span class="hover-group group-%d">%s</span>', i + offset, spanLeadingZeroesSimple(g));
    });
}

},{"sprintf-js":"5Vzwd","@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"fCubN":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "groupPossibilities", ()=>groupPossibilities
);
parcelHelpers.export(exports, "padGroup", ()=>padGroup
);
parcelHelpers.export(exports, "ADDRESS_BOUNDARY", ()=>ADDRESS_BOUNDARY
);
parcelHelpers.export(exports, "simpleRegularExpression", ()=>simpleRegularExpression
);
parcelHelpers.export(exports, "possibleElisions", ()=>possibleElisions
);
var _constants = require("./constants");
var _sprintfJs = require("sprintf-js");
function groupPossibilities(possibilities) {
    return _sprintfJs.sprintf('(%s)', possibilities.join('|'));
}
function padGroup(group) {
    if (group.length < 4) return _sprintfJs.sprintf('0{0,%d}%s', 4 - group.length, group);
    return group;
}
const ADDRESS_BOUNDARY = '[^A-Fa-f0-9:]';
function simpleRegularExpression(groups) {
    const zeroIndexes = [];
    groups.forEach((group, i)=>{
        const groupInteger = parseInt(group, 16);
        if (groupInteger === 0) zeroIndexes.push(i);
    });
    // You can technically elide a single 0, this creates the regular expressions
    // to match that eventuality
    const possibilities = zeroIndexes.map((zeroIndex)=>groups.map((group, i)=>{
            if (i === zeroIndex) {
                const elision = i === 0 || i === _constants.GROUPS - 1 ? ':' : '';
                return groupPossibilities([
                    padGroup(group),
                    elision
                ]);
            }
            return padGroup(group);
        }).join(':')
    );
    // The simplest case
    possibilities.push(groups.map(padGroup).join(':'));
    return groupPossibilities(possibilities);
}
function possibleElisions(elidedGroups, moreLeft, moreRight) {
    const left = moreLeft ? '' : ':';
    const right = moreRight ? '' : ':';
    const possibilities = [];
    // 1. elision of everything (::)
    if (!moreLeft && !moreRight) possibilities.push('::');
    // 2. complete elision of the middle
    if (moreLeft && moreRight) possibilities.push('');
    if (moreRight && !moreLeft || !moreRight && moreLeft) // 3. complete elision of one side
    possibilities.push(':');
    // 4. elision from the left side
    possibilities.push(_sprintfJs.sprintf('%s(:0{1,4}){1,%d}', left, elidedGroups - 1));
    // 5. elision from the right side
    possibilities.push(_sprintfJs.sprintf('(0{1,4}:){1,%d}%s', elidedGroups - 1, right));
    // 6. no elision
    possibilities.push(_sprintfJs.sprintf('(0{1,4}:){%d}0{1,4}', elidedGroups - 1));
    // 7. elision (including sloppy elision) from the middle
    for(let groups = 1; groups < elidedGroups - 1; groups++)for(let position = 1; position < elidedGroups - groups; position++)possibilities.push(_sprintfJs.sprintf('(0{1,4}:){%d}:(0{1,4}:){%d}0{1,4}', position, elidedGroups - position - groups - 1));
    return groupPossibilities(possibilities);
}

},{"./constants":"hNgps","sprintf-js":"5Vzwd","@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"5asWS":[function(require,module,exports) {
'use strict';
class TimeoutError extends Error {
    constructor(message1){
        super(message1);
        this.name = 'TimeoutError';
    }
}
const pTimeout = (promise, milliseconds, fallback, options)=>{
    let timer;
    const cancelablePromise = new Promise((resolve, reject)=>{
        if (typeof milliseconds !== 'number' || milliseconds < 0) throw new TypeError('Expected `milliseconds` to be a positive number');
        if (milliseconds === Infinity) {
            resolve(promise);
            return;
        }
        options = {
            customTimers: {
                setTimeout,
                clearTimeout
            },
            ...options
        };
        timer = options.customTimers.setTimeout.call(undefined, ()=>{
            if (typeof fallback === 'function') {
                try {
                    resolve(fallback());
                } catch (error) {
                    reject(error);
                }
                return;
            }
            const message = typeof fallback === 'string' ? fallback : `Promise timed out after ${milliseconds} milliseconds`;
            const timeoutError = fallback instanceof Error ? fallback : new TimeoutError(message);
            if (typeof promise.cancel === 'function') promise.cancel();
            reject(timeoutError);
        }, milliseconds);
        (async ()=>{
            try {
                resolve(await promise);
            } catch (error) {
                reject(error);
            } finally{
                options.customTimers.clearTimeout.call(undefined, timer);
            }
        })();
    });
    cancelablePromise.clear = ()=>{
        clearTimeout(timer);
        timer = undefined;
    };
    return cancelablePromise;
};
module.exports = pTimeout;
// TODO: Remove this for the next major release
module.exports.default = pTimeout;
module.exports.TimeoutError = TimeoutError;

},{}],"ffciF":[function(require,module,exports) {
'use strict';
const mafmt = require('mafmt');
const { CODE_CIRCUIT , CODE_P2P , CODE_TCP , CODE_WS , CODE_WSS  } = require('./constants');
module.exports = {
    all: (multiaddrs)=>multiaddrs.filter((ma)=>{
            if (ma.protoCodes().includes(CODE_CIRCUIT)) return false;
            const testMa = ma.decapsulateCode(CODE_P2P);
            return mafmt.WebSockets.matches(testMa) || mafmt.WebSocketsSecure.matches(testMa);
        })
    ,
    dnsWss: (multiaddrs)=>multiaddrs.filter((ma)=>{
            if (ma.protoCodes().includes(CODE_CIRCUIT)) return false;
            const testMa = ma.decapsulateCode(CODE_P2P);
            return mafmt.WebSocketsSecure.matches(testMa) && mafmt.DNS.matches(testMa.decapsulateCode(CODE_TCP).decapsulateCode(CODE_WSS));
        })
    ,
    dnsWsOrWss: (multiaddrs)=>multiaddrs.filter((ma)=>{
            if (ma.protoCodes().includes(CODE_CIRCUIT)) return false;
            const testMa = ma.decapsulateCode(CODE_P2P);
            // WS
            if (mafmt.WebSockets.matches(testMa)) return mafmt.DNS.matches(testMa.decapsulateCode(CODE_TCP).decapsulateCode(CODE_WS));
            // WSS
            return mafmt.WebSocketsSecure.matches(testMa) && mafmt.DNS.matches(testMa.decapsulateCode(CODE_TCP).decapsulateCode(CODE_WSS));
        })
};

},{"mafmt":"hdtcj","./constants":"gjY9S"}],"ceZpI":[function(require,module,exports) {
'use strict';
const debug = require('debug');
const log = debug('libp2p:webrtc-star');
log.error = debug('libp2p:webrtc-star:error');
const { EventEmitter  } = require('events');
const errcode = require('err-code');
const withIs = require('class-is');
const { AbortError  } = require('abortable-iterator');
const SimplePeer = require('libp2p-webrtc-peer');
const { supportsWebRTCDataChannels: webrtcSupport  } = require('ipfs-utils/src/supports');
const { Multiaddr  } = require('multiaddr');
const mafmt = require('mafmt');
const PeerId = require('peer-id');
const { CODE_CIRCUIT  } = require('./constants');
const createListener = require('./listener');
const toConnection = require('./socket-to-conn');
const { cleanMultiaddr , cleanUrlSIO  } = require('./utils');
function noop() {
}
/**
 * @class WebRTCStar
 */ class WebRTCStar {
    /**
   * @class
   * @param {object} options
   * @param {Upgrader} options.upgrader
   */ constructor(options = {
    }){
        if (!options.upgrader) throw new Error('An upgrader must be provided. See https://github.com/libp2p/interface-transport#upgrader.');
        this._upgrader = options.upgrader;
        this.sioOptions = {
            transports: [
                'websocket'
            ],
            'force new connection': true
        };
        if (options.wrtc) this.wrtc = options.wrtc;
        // Keep Signalling references
        this.sigReferences = new Map();
        // Discovery
        this.discovery = new EventEmitter();
        this.discovery.tag = 'webRTCStar';
        this.discovery._isStarted = false;
        this.discovery.start = ()=>{
            this.discovery._isStarted = true;
        };
        this.discovery.stop = ()=>{
            this.discovery._isStarted = false;
        };
        this._peerDiscovered = this._peerDiscovered.bind(this);
    }
    /**
   * @async
   * @param {Multiaddr} ma
   * @param {object} options
   * @param {AbortSignal} options.signal - Used to abort dial requests
   * @returns {Connection} An upgraded Connection
   */ async dial(ma2, options1 = {
    }) {
        const rawConn = await this._connect(ma2, options1);
        const maConn = toConnection(rawConn, {
            remoteAddr: ma2,
            signal: options1.signal
        });
        log('new outbound connection %s', maConn.remoteAddr);
        const conn = await this._upgrader.upgradeOutbound(maConn);
        log('outbound connection %s upgraded', maConn.remoteAddr);
        return conn;
    }
    /**
   * @private
   * @param {Multiaddr} ma
   * @param {object} options
   * @param {AbortSignal} options.signal - Used to abort dial requests
   * @returns {Promise<SimplePeer>} Resolves a SimplePeer Webrtc channel
   */ _connect(ma1, options2 = {
    }) {
        if (options2.signal && options2.signal.aborted) throw new AbortError();
        const spOptions = {
            initiator: true,
            trickle: false,
            ...options2.spOptions || {
            }
        };
        // Use custom WebRTC implementation
        if (this.wrtc) spOptions.wrtc = this.wrtc;
        const cOpts = ma1.toOptions();
        const intentId = (~~(Math.random() * 1000000000)).toString(36) + Date.now();
        return new Promise((resolve, reject)=>{
            const sio = this.sigReferences.get(cleanUrlSIO(ma1));
            if (!sio || !sio.listener) return reject(errcode(new Error('unknown signal server to use'), 'ERR_UNKNOWN_SIGNAL_SERVER'));
            const sioClient = sio.listener.io;
            const start = Date.now();
            let connected;
            log('dialing %s:%s', cOpts.host, cOpts.port);
            const channel = new SimplePeer(spOptions);
            const onError = (err)=>{
                if (!connected) {
                    const msg = `connection error ${cOpts.host}:${cOpts.port}: ${err.message}`;
                    log.error(msg);
                    done(err);
                }
            };
            const onTimeout = ()=>{
                log('connnection timeout %s:%s', cOpts.host, cOpts.port);
                const err = errcode(new Error(`connection timeout after ${Date.now() - start}ms`), 'ERR_CONNECT_TIMEOUT');
                // Note: this will result in onError() being called
                channel.emit('error', err);
            };
            const onConnect = ()=>{
                connected = true;
                log('connection opened %s:%s', cOpts.host, cOpts.port);
                done(null);
            };
            const onAbort = ()=>{
                log.error('connection aborted %s:%s', cOpts.host, cOpts.port);
                channel.destroy();
                done(new AbortError());
            };
            const done = (err)=>{
                channel.removeListener('timeout', onTimeout);
                channel.removeListener('connect', onConnect);
                options2.signal && options2.signal.removeEventListener('abort', onAbort);
                err ? reject(err) : resolve(channel);
            };
            channel.on('error', onError);
            channel.once('timeout', onTimeout);
            channel.once('connect', onConnect);
            channel.on('close', ()=>{
                channel.removeListener('error', onError);
            });
            options2.signal && options2.signal.addEventListener('abort', onAbort);
            channel.on('signal', (signal)=>{
                sioClient.emit('ss-handshake', {
                    intentId: intentId,
                    srcMultiaddr: sio.signallingAddr.toString(),
                    dstMultiaddr: ma1.toString(),
                    signal: signal
                });
            });
            // NOTE: aegir segfaults if we do .once on the socket.io event emitter and we
            // are clueless as to why.
            sioClient.on('ws-handshake', (offer)=>{
                if (offer.intentId === intentId && offer.err) {
                    channel.destroy();
                    reject(errcode(offer.err instanceof Error ? offer.err : new Error(offer.err), 'ERR_SIGNALLING_FAILED'));
                }
                if (offer.intentId !== intentId || !offer.answer || channel.destroyed) return;
                channel.signal(offer.signal);
            });
        });
    }
    /**
   * Creates a WebrtcStar listener. The provided `handler` function will be called
   * anytime a new incoming Connection has been successfully upgraded via
   * `upgrader.upgradeInbound`.
   *
   * @param {object} [options] - simple-peer options for listener
   * @param {function (Connection)} handler
   * @returns {Listener} A WebrtcStar listener
   */ createListener(options3 = {
    }, handler) {
        if (!webrtcSupport && !this.wrtc) throw errcode(new Error('no WebRTC support'), 'ERR_NO_WEBRTC_SUPPORT');
        if (typeof options3 === 'function') {
            handler = options3;
            options3 = {
            };
        }
        handler = handler || noop;
        return createListener({
            handler,
            upgrader: this._upgrader
        }, this, options3);
    }
    /**
   * Takes a list of `Multiaddr`s and returns only valid TCP addresses
   *
   * @param {Multiaddr[]} multiaddrs
   * @returns {Multiaddr[]} Valid TCP multiaddrs
   */ filter(multiaddrs) {
        multiaddrs = Array.isArray(multiaddrs) ? multiaddrs : [
            multiaddrs
        ];
        return multiaddrs.filter((ma)=>{
            if (ma.protoCodes().includes(CODE_CIRCUIT)) return false;
            return mafmt.WebRTCStar.matches(ma);
        });
    }
    _peerDiscovered(maStr) {
        if (!this.discovery._isStarted) return;
        log('Peer Discovered:', maStr);
        maStr = cleanMultiaddr(maStr);
        const ma = new Multiaddr(maStr);
        const peerId = PeerId.createFromB58String(ma.getPeerId());
        this.discovery.emit('peer', {
            id: peerId,
            multiaddrs: [
                ma
            ]
        });
    }
}
module.exports = withIs(WebRTCStar, {
    className: 'WebRTCStar',
    symbolName: '@libp2p/js-libp2p-webrtc-star/webrtcstar'
});

},{"debug":"lWlU4","events":"bHM3D","err-code":"eQvyh","class-is":"eROOZ","abortable-iterator":"3n79Y","libp2p-webrtc-peer":"f7Q78","ipfs-utils/src/supports":"J54xM","multiaddr":"kOPrF","mafmt":"hdtcj","peer-id":"4VGWt","./constants":"avCUo","./listener":"f01S2","./socket-to-conn":"9tZ4u","./utils":"cPlDM"}],"f7Q78":[function(require,module,exports) {
/*! simple-peer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */ var debug = require('debug')('simple-peer');
var getBrowserRTC = require('get-browser-rtc');
var randombytes = require('randombytes');
var stream1 = require('readable-stream');
var queueMicrotask = require('queue-microtask') // TODO: remove when Node 10 is not supported
;
var errCode = require('err-code');
var MAX_BUFFERED_AMOUNT = 65536;
var ICECOMPLETE_TIMEOUT = 5000;
var CHANNEL_CLOSING_TIMEOUT = 5000;
// HACK: Filter trickle lines when trickle is disabled #354
function filterTrickle(sdp) {
    return sdp.replace(/a=ice-options:trickle\s\n/g, '');
}
function warn(message) {
    console.warn(message);
}
/**
 * WebRTC peer connection. Same API as node core `net.Socket`, plus a few extra methods.
 * Duplex stream.
 * @param {Object} opts
 */ class Peer extends stream1.Duplex {
    constructor(opts){
        opts = Object.assign({
            allowHalfOpen: false
        }, opts);
        super(opts);
        this._id = randombytes(4).toString('hex').slice(0, 7);
        this._debug('new peer %o', opts);
        this.channelName = opts.initiator ? opts.channelName || randombytes(20).toString('hex') : null;
        this.initiator = opts.initiator || false;
        this.channelConfig = opts.channelConfig || Peer.channelConfig;
        this.negotiated = this.channelConfig.negotiated;
        this.config = Object.assign({
        }, Peer.config, opts.config);
        this.offerOptions = opts.offerOptions || {
        };
        this.answerOptions = opts.answerOptions || {
        };
        this.sdpTransform = opts.sdpTransform || ((sdp)=>sdp
        );
        this.streams = opts.streams || (opts.stream ? [
            opts.stream
        ] : []) // support old "stream" option
        ;
        this.trickle = opts.trickle !== undefined ? opts.trickle : true;
        this.allowHalfTrickle = opts.allowHalfTrickle !== undefined ? opts.allowHalfTrickle : false;
        this.iceCompleteTimeout = opts.iceCompleteTimeout || ICECOMPLETE_TIMEOUT;
        this._connected = false;
        this.remoteAddress = undefined;
        this.remoteFamily = undefined;
        this.remotePort = undefined;
        this.localAddress = undefined;
        this.localFamily = undefined;
        this.localPort = undefined;
        this._wrtc = opts.wrtc && typeof opts.wrtc === 'object' ? opts.wrtc : getBrowserRTC();
        if (!this._wrtc) {
            if (typeof window === 'undefined') throw errCode(new Error('No WebRTC support: Specify `opts.wrtc` option in this environment'), 'ERR_WEBRTC_SUPPORT');
            else throw errCode(new Error('No WebRTC support: Not a supported browser'), 'ERR_WEBRTC_SUPPORT');
        }
        this._pcReady = false;
        this._channelReady = false;
        this._iceComplete = false // ice candidate trickle done (got null candidate)
        ;
        this._iceCompleteTimer = null // send an offer/answer anyway after some timeout
        ;
        this._channel = null;
        this._pendingCandidates = [];
        this._isNegotiating = this.negotiated ? false : !this.initiator // is this peer waiting for negotiation to complete?
        ;
        this._batchedNegotiation = false // batch synchronous negotiations
        ;
        this._queuedNegotiation = false // is there a queued negotiation request?
        ;
        this._sendersAwaitingStable = [];
        this._senderMap = new Map();
        this._firstStable = true;
        this._closingInterval = null;
        this._remoteTracks = [];
        this._remoteStreams = [];
        this._chunk = null;
        this._cb = null;
        this._interval = null;
        try {
            this._pc = new this._wrtc.RTCPeerConnection(this.config);
        } catch (err) {
            queueMicrotask(()=>this.destroy(errCode(err, 'ERR_PC_CONSTRUCTOR'))
            );
            return;
        }
        // We prefer feature detection whenever possible, but sometimes that's not
        // possible for certain implementations.
        this._isReactNativeWebrtc = typeof this._pc._peerConnectionId === 'number';
        this._pc.oniceconnectionstatechange = ()=>{
            this._onIceStateChange();
        };
        this._pc.onicegatheringstatechange = ()=>{
            this._onIceStateChange();
        };
        this._pc.onconnectionstatechange = ()=>{
            this._onConnectionStateChange();
        };
        this._pc.onsignalingstatechange = ()=>{
            this._onSignalingStateChange();
        };
        this._pc.onicecandidate = (event)=>{
            this._onIceCandidate(event);
        };
        // Other spec events, unused by this implementation:
        // - onconnectionstatechange
        // - onicecandidateerror
        // - onfingerprintfailure
        // - onnegotiationneeded
        if (this.initiator || this.negotiated) this._setupData({
            channel: this._pc.createDataChannel(this.channelName, this.channelConfig)
        });
        else this._pc.ondatachannel = (event)=>{
            this._setupData(event);
        };
        if (this.streams) this.streams.forEach((stream)=>{
            this.addStream(stream);
        });
        this._pc.ontrack = (event)=>{
            this._onTrack(event);
        };
        if (this.initiator) this._needsNegotiation();
        this._onFinishBound = ()=>{
            this._onFinish();
        };
        this.once('finish', this._onFinishBound);
    }
    get bufferSize() {
        return this._channel && this._channel.bufferedAmount || 0;
    }
    // HACK: it's possible channel.readyState is "closing" before peer.destroy() fires
    // https://bugs.chromium.org/p/chromium/issues/detail?id=882743
    get connected() {
        return this._connected && this._channel.readyState === 'open';
    }
    address() {
        return {
            port: this.localPort,
            family: this.localFamily,
            address: this.localAddress
        };
    }
    signal(data) {
        if (this.destroyed) throw errCode(new Error('cannot signal after peer is destroyed'), 'ERR_SIGNALING');
        if (typeof data === 'string') try {
            data = JSON.parse(data);
        } catch (err1) {
            data = {
            };
        }
        this._debug('signal()');
        if (data.renegotiate && this.initiator) {
            this._debug('got request to renegotiate');
            this._needsNegotiation();
        }
        if (data.transceiverRequest && this.initiator) {
            this._debug('got request for transceiver');
            this.addTransceiver(data.transceiverRequest.kind, data.transceiverRequest.init);
        }
        if (data.candidate) {
            if (this._pc.remoteDescription && this._pc.remoteDescription.type) this._addIceCandidate(data.candidate);
            else this._pendingCandidates.push(data.candidate);
        }
        if (data.sdp) this._pc.setRemoteDescription(new this._wrtc.RTCSessionDescription(data)).then(()=>{
            if (this.destroyed) return;
            this._pendingCandidates.forEach((candidate)=>{
                this._addIceCandidate(candidate);
            });
            this._pendingCandidates = [];
            if (this._pc.remoteDescription.type === 'offer') this._createAnswer();
        }).catch((err)=>{
            this.destroy(errCode(err, 'ERR_SET_REMOTE_DESCRIPTION'));
        });
        if (!data.sdp && !data.candidate && !data.renegotiate && !data.transceiverRequest) this.destroy(errCode(new Error('signal() called with invalid signal data'), 'ERR_SIGNALING'));
    }
    _addIceCandidate(candidate) {
        var iceCandidateObj = new this._wrtc.RTCIceCandidate(candidate);
        this._pc.addIceCandidate(iceCandidateObj).catch((err)=>{
            if (!iceCandidateObj.address || iceCandidateObj.address.endsWith('.local')) warn('Ignoring unsupported ICE candidate.');
            else this.destroy(errCode(err, 'ERR_ADD_ICE_CANDIDATE'));
        });
    }
    /**
   * Send text/binary data to the remote peer.
   * @param {ArrayBufferView|ArrayBuffer|Buffer|string|Blob} chunk
   */ send(chunk) {
        this._channel.send(chunk);
    }
    /**
   * Add a Transceiver to the connection.
   * @param {String} kind
   * @param {Object} init
   */ addTransceiver(kind, init) {
        this._debug('addTransceiver()');
        if (this.initiator) try {
            this._pc.addTransceiver(kind, init);
            this._needsNegotiation();
        } catch (err) {
            this.destroy(errCode(err, 'ERR_ADD_TRANSCEIVER'));
        }
        else this.emit('signal', {
            transceiverRequest: {
                kind,
                init
            }
        });
    }
    /**
   * Add a MediaStream to the connection.
   * @param {MediaStream} stream
   */ addStream(stream) {
        this._debug('addStream()');
        stream.getTracks().forEach((track)=>{
            this.addTrack(track, stream);
        });
    }
    /**
   * Add a MediaStreamTrack to the connection.
   * @param {MediaStreamTrack} track
   * @param {MediaStream} stream
   */ addTrack(track2, stream2) {
        this._debug('addTrack()');
        var submap = this._senderMap.get(track2) || new Map() // nested Maps map [track, stream] to sender
        ;
        var sender = submap.get(stream2);
        if (!sender) {
            sender = this._pc.addTrack(track2, stream2);
            submap.set(stream2, sender);
            this._senderMap.set(track2, submap);
            this._needsNegotiation();
        } else if (sender.removed) throw errCode(new Error('Track has been removed. You should enable/disable tracks that you want to re-add.'), 'ERR_SENDER_REMOVED');
        else throw errCode(new Error('Track has already been added to that stream.'), 'ERR_SENDER_ALREADY_ADDED');
    }
    /**
   * Replace a MediaStreamTrack by another in the connection.
   * @param {MediaStreamTrack} oldTrack
   * @param {MediaStreamTrack} newTrack
   * @param {MediaStream} stream
   */ replaceTrack(oldTrack, newTrack, stream3) {
        this._debug('replaceTrack()');
        var submap = this._senderMap.get(oldTrack);
        var sender = submap ? submap.get(stream3) : null;
        if (!sender) throw errCode(new Error('Cannot replace track that was never added.'), 'ERR_TRACK_NOT_ADDED');
        if (newTrack) this._senderMap.set(newTrack, submap);
        if (sender.replaceTrack != null) sender.replaceTrack(newTrack);
        else this.destroy(errCode(new Error('replaceTrack is not supported in this browser'), 'ERR_UNSUPPORTED_REPLACETRACK'));
    }
    /**
   * Remove a MediaStreamTrack from the connection.
   * @param {MediaStreamTrack} track
   * @param {MediaStream} stream
   */ removeTrack(track1, stream4) {
        this._debug('removeSender()');
        var submap = this._senderMap.get(track1);
        var sender = submap ? submap.get(stream4) : null;
        if (!sender) throw errCode(new Error('Cannot remove track that was never added.'), 'ERR_TRACK_NOT_ADDED');
        try {
            sender.removed = true;
            this._pc.removeTrack(sender);
        } catch (err) {
            if (err.name === 'NS_ERROR_UNEXPECTED') this._sendersAwaitingStable.push(sender) // HACK: Firefox must wait until (signalingState === stable) https://bugzilla.mozilla.org/show_bug.cgi?id=1133874
            ;
            else this.destroy(errCode(err, 'ERR_REMOVE_TRACK'));
        }
        this._needsNegotiation();
    }
    /**
   * Remove a MediaStream from the connection.
   * @param {MediaStream} stream
   */ removeStream(stream5) {
        this._debug('removeSenders()');
        stream5.getTracks().forEach((track)=>{
            this.removeTrack(track, stream5);
        });
    }
    _needsNegotiation() {
        this._debug('_needsNegotiation');
        if (this._batchedNegotiation) return; // batch synchronous renegotiations
        this._batchedNegotiation = true;
        queueMicrotask(()=>{
            this._batchedNegotiation = false;
            this._debug('starting batched negotiation');
            this.negotiate();
        });
    }
    negotiate() {
        if (this.initiator) {
            if (this._isNegotiating) {
                this._queuedNegotiation = true;
                this._debug('already negotiating, queueing');
            } else {
                this._debug('start negotiation');
                setTimeout(()=>{
                    this._createOffer();
                }, 0);
            }
        } else if (this._isNegotiating) {
            this._queuedNegotiation = true;
            this._debug('already negotiating, queueing');
        } else {
            this._debug('requesting negotiation from initiator');
            this.emit('signal', {
                renegotiate: true
            });
        }
        this._isNegotiating = true;
    }
    _destroy(err2, cb3) {
        this._debug('destroy (error: %s)', err2 && (err2.message || err2));
        this.readable = this.writable = false;
        if (!this._readableState.ended) this.push(null);
        if (!this._writableState.finished) this.end();
        this._connected = false;
        this._pcReady = false;
        this._channelReady = false;
        this._remoteTracks = null;
        this._remoteStreams = null;
        this._senderMap = null;
        clearInterval(this._closingInterval);
        this._closingInterval = null;
        clearInterval(this._interval);
        this._interval = null;
        this._chunk = null;
        this._cb = null;
        if (this._onFinishBound) this.removeListener('finish', this._onFinishBound);
        this._onFinishBound = null;
        if (this._channel) {
            try {
                this._channel.close();
            } catch (err) {
            }
            this._channel.onmessage = null;
            this._channel.onopen = null;
            this._channel.onclose = null;
            this._channel.onerror = null;
        }
        if (this._pc) {
            try {
                this._pc.close();
            } catch (err) {
            }
            this._pc.oniceconnectionstatechange = null;
            this._pc.onicegatheringstatechange = null;
            this._pc.onsignalingstatechange = null;
            this._pc.onicecandidate = null;
            this._pc.ontrack = null;
            this._pc.ondatachannel = null;
        }
        this._pc = null;
        this._channel = null;
        cb3(err2);
    }
    _setupData(event1) {
        if (!event1.channel) // In some situations `pc.createDataChannel()` returns `undefined` (in wrtc),
        // which is invalid behavior. Handle it gracefully.
        // See: https://github.com/feross/simple-peer/issues/163
        return this.destroy(errCode(new Error('Data channel event is missing `channel` property'), 'ERR_DATA_CHANNEL'));
        this._channel = event1.channel;
        this._channel.binaryType = 'arraybuffer';
        if (typeof this._channel.bufferedAmountLowThreshold === 'number') this._channel.bufferedAmountLowThreshold = MAX_BUFFERED_AMOUNT;
        this.channelName = this._channel.label;
        this._channel.onmessage = (event)=>{
            this._onChannelMessage(event);
        };
        this._channel.onbufferedamountlow = ()=>{
            this._onChannelBufferedAmountLow();
        };
        this._channel.onopen = ()=>{
            this._onChannelOpen();
        };
        this._channel.onclose = ()=>{
            this._onChannelClose();
        };
        this._channel.onerror = (err)=>{
            this.destroy(errCode(err, 'ERR_DATA_CHANNEL'));
        };
        // HACK: Chrome will sometimes get stuck in readyState "closing", let's check for this condition
        // https://bugs.chromium.org/p/chromium/issues/detail?id=882743
        var isClosing = false;
        this._closingInterval = setInterval(()=>{
            if (this._channel && this._channel.readyState === 'closing') {
                if (isClosing) this._onChannelClose() // closing timed out: equivalent to onclose firing
                ;
                isClosing = true;
            } else isClosing = false;
        }, CHANNEL_CLOSING_TIMEOUT);
    }
    _read() {
    }
    _write(chunk1, encoding, cb1) {
        if (this.destroyed) return cb1(errCode(new Error('cannot write after peer is destroyed'), 'ERR_DATA_CHANNEL'));
        if (this._connected) {
            try {
                this.send(chunk1);
            } catch (err) {
                return this.destroy(errCode(err, 'ERR_DATA_CHANNEL'));
            }
            if (this._channel.bufferedAmount > MAX_BUFFERED_AMOUNT) {
                this._debug('start backpressure: bufferedAmount %d', this._channel.bufferedAmount);
                this._cb = cb1;
            } else cb1(null);
        } else {
            this._debug('write before connect');
            this._chunk = chunk1;
            this._cb = cb1;
        }
    }
    // When stream finishes writing, close socket. Half open connections are not
    // supported.
    _onFinish() {
        if (this.destroyed) return;
        // Wait a bit before destroying so the socket flushes.
        // TODO: is there a more reliable way to accomplish this?
        const destroySoon = ()=>{
            setTimeout(()=>this.destroy()
            , 1000);
        };
        if (this._connected) destroySoon();
        else this.once('connect', destroySoon);
    }
    _startIceCompleteTimeout() {
        if (this.destroyed) return;
        if (this._iceCompleteTimer) return;
        this._debug('started iceComplete timeout');
        this._iceCompleteTimer = setTimeout(()=>{
            if (!this._iceComplete) {
                this._iceComplete = true;
                this._debug('iceComplete timeout completed');
                this.emit('iceTimeout');
                this.emit('_iceComplete');
            }
        }, this.iceCompleteTimeout);
    }
    _createOffer() {
        if (this.destroyed) return;
        this._pc.createOffer(this.offerOptions).then((offer)=>{
            if (this.destroyed) return;
            if (!this.trickle && !this.allowHalfTrickle) offer.sdp = filterTrickle(offer.sdp);
            offer.sdp = this.sdpTransform(offer.sdp);
            const sendOffer = ()=>{
                if (this.destroyed) return;
                var signal = this._pc.localDescription || offer;
                this._debug('signal');
                this.emit('signal', {
                    type: signal.type,
                    sdp: signal.sdp
                });
            };
            const onSuccess = ()=>{
                this._debug('createOffer success');
                if (this.destroyed) return;
                if (this.trickle || this._iceComplete) sendOffer();
                else this.once('_iceComplete', sendOffer) // wait for candidates
                ;
            };
            const onError = (err)=>{
                this.destroy(errCode(err, 'ERR_SET_LOCAL_DESCRIPTION'));
            };
            this._pc.setLocalDescription(offer).then(onSuccess).catch(onError);
        }).catch((err)=>{
            this.destroy(errCode(err, 'ERR_CREATE_OFFER'));
        });
    }
    _requestMissingTransceivers() {
        if (this._pc.getTransceivers) this._pc.getTransceivers().forEach((transceiver)=>{
            if (!transceiver.mid && transceiver.sender.track && !transceiver.requested) {
                transceiver.requested = true // HACK: Safari returns negotiated transceivers with a null mid
                ;
                this.addTransceiver(transceiver.sender.track.kind);
            }
        });
    }
    _createAnswer() {
        if (this.destroyed) return;
        this._pc.createAnswer(this.answerOptions).then((answer)=>{
            if (this.destroyed) return;
            if (!this.trickle && !this.allowHalfTrickle) answer.sdp = filterTrickle(answer.sdp);
            answer.sdp = this.sdpTransform(answer.sdp);
            const sendAnswer = ()=>{
                if (this.destroyed) return;
                var signal = this._pc.localDescription || answer;
                this._debug('signal');
                this.emit('signal', {
                    type: signal.type,
                    sdp: signal.sdp
                });
                if (!this.initiator) this._requestMissingTransceivers();
            };
            const onSuccess = ()=>{
                if (this.destroyed) return;
                if (this.trickle || this._iceComplete) sendAnswer();
                else this.once('_iceComplete', sendAnswer);
            };
            const onError = (err)=>{
                this.destroy(errCode(err, 'ERR_SET_LOCAL_DESCRIPTION'));
            };
            this._pc.setLocalDescription(answer).then(onSuccess).catch(onError);
        }).catch((err)=>{
            this.destroy(errCode(err, 'ERR_CREATE_ANSWER'));
        });
    }
    _onConnectionStateChange() {
        if (this.destroyed) return;
        if (this._pc.connectionState === 'failed') this.destroy(errCode(new Error('Connection failed.'), 'ERR_CONNECTION_FAILURE'));
    }
    _onIceStateChange() {
        if (this.destroyed) return;
        var iceConnectionState = this._pc.iceConnectionState;
        var iceGatheringState = this._pc.iceGatheringState;
        this._debug('iceStateChange (connection: %s) (gathering: %s)', iceConnectionState, iceGatheringState);
        this.emit('iceStateChange', iceConnectionState, iceGatheringState);
        if (iceConnectionState === 'connected' || iceConnectionState === 'completed') {
            this._pcReady = true;
            this._maybeReady();
        }
        if (iceConnectionState === 'failed') this.destroy(errCode(new Error('Ice connection failed.'), 'ERR_ICE_CONNECTION_FAILURE'));
        if (iceConnectionState === 'closed') this.destroy(errCode(new Error('Ice connection closed.'), 'ERR_ICE_CONNECTION_CLOSED'));
    }
    getStats(cb2) {
        // statreports can come with a value array instead of properties
        const flattenValues = (report)=>{
            if (Object.prototype.toString.call(report.values) === '[object Array]') report.values.forEach((value)=>{
                Object.assign(report, value);
            });
            return report;
        };
        // Promise-based getStats() (standard)
        if (this._pc.getStats.length === 0 || this._isReactNativeWebrtc) this._pc.getStats().then((res)=>{
            var reports = [];
            res.forEach((report)=>{
                reports.push(flattenValues(report));
            });
            cb2(null, reports);
        }, (err)=>cb2(err)
        );
        else if (this._pc.getStats.length > 0) this._pc.getStats((res)=>{
            // If we destroy connection in `connect` callback this code might happen to run when actual connection is already closed
            if (this.destroyed) return;
            var reports = [];
            res.result().forEach((result)=>{
                var report = {
                };
                result.names().forEach((name)=>{
                    report[name] = result.stat(name);
                });
                report.id = result.id;
                report.type = result.type;
                report.timestamp = result.timestamp;
                reports.push(flattenValues(report));
            });
            cb2(null, reports);
        }, (err)=>cb2(err)
        );
        else cb2(null, []);
    }
    _maybeReady() {
        this._debug('maybeReady pc %s channel %s', this._pcReady, this._channelReady);
        if (this._connected || this._connecting || !this._pcReady || !this._channelReady) return;
        this._connecting = true;
        // HACK: We can't rely on order here, for details see https://github.com/js-platform/node-webrtc/issues/339
        const findCandidatePair = ()=>{
            if (this.destroyed) return;
            this.getStats((err, items)=>{
                if (this.destroyed) return;
                // Treat getStats error as non-fatal. It's not essential.
                if (err) items = [];
                var remoteCandidates = {
                };
                var localCandidates = {
                };
                var candidatePairs = {
                };
                var foundSelectedCandidatePair = false;
                items.forEach((item)=>{
                    // TODO: Once all browsers support the hyphenated stats report types, remove
                    // the non-hypenated ones
                    if (item.type === 'remotecandidate' || item.type === 'remote-candidate') remoteCandidates[item.id] = item;
                    if (item.type === 'localcandidate' || item.type === 'local-candidate') localCandidates[item.id] = item;
                    if (item.type === 'candidatepair' || item.type === 'candidate-pair') candidatePairs[item.id] = item;
                });
                const setSelectedCandidatePair = (selectedCandidatePair)=>{
                    foundSelectedCandidatePair = true;
                    var local = localCandidates[selectedCandidatePair.localCandidateId];
                    if (local && (local.ip || local.address)) {
                        // Spec
                        this.localAddress = local.ip || local.address;
                        this.localPort = Number(local.port);
                    } else if (local && local.ipAddress) {
                        // Firefox
                        this.localAddress = local.ipAddress;
                        this.localPort = Number(local.portNumber);
                    } else if (typeof selectedCandidatePair.googLocalAddress === 'string') {
                        // TODO: remove this once Chrome 58 is released
                        local = selectedCandidatePair.googLocalAddress.split(':');
                        this.localAddress = local[0];
                        this.localPort = Number(local[1]);
                    }
                    if (this.localAddress) this.localFamily = this.localAddress.includes(':') ? 'IPv6' : 'IPv4';
                    var remote = remoteCandidates[selectedCandidatePair.remoteCandidateId];
                    if (remote && (remote.ip || remote.address)) {
                        // Spec
                        this.remoteAddress = remote.ip || remote.address;
                        this.remotePort = Number(remote.port);
                    } else if (remote && remote.ipAddress) {
                        // Firefox
                        this.remoteAddress = remote.ipAddress;
                        this.remotePort = Number(remote.portNumber);
                    } else if (typeof selectedCandidatePair.googRemoteAddress === 'string') {
                        // TODO: remove this once Chrome 58 is released
                        remote = selectedCandidatePair.googRemoteAddress.split(':');
                        this.remoteAddress = remote[0];
                        this.remotePort = Number(remote[1]);
                    }
                    if (this.remoteAddress) this.remoteFamily = this.remoteAddress.includes(':') ? 'IPv6' : 'IPv4';
                    this._debug('connect local: %s:%s remote: %s:%s', this.localAddress, this.localPort, this.remoteAddress, this.remotePort);
                };
                items.forEach((item)=>{
                    // Spec-compliant
                    if (item.type === 'transport' && item.selectedCandidatePairId) setSelectedCandidatePair(candidatePairs[item.selectedCandidatePairId]);
                    // Old implementations
                    if (item.type === 'googCandidatePair' && item.googActiveConnection === 'true' || (item.type === 'candidatepair' || item.type === 'candidate-pair') && item.selected) setSelectedCandidatePair(item);
                });
                // Ignore candidate pair selection in browsers like Safari 11 that do not have any local or remote candidates
                // But wait until at least 1 candidate pair is available
                if (!foundSelectedCandidatePair && (!Object.keys(candidatePairs).length || Object.keys(localCandidates).length)) {
                    setTimeout(findCandidatePair, 100);
                    return;
                } else {
                    this._connecting = false;
                    this._connected = true;
                }
                if (this._chunk) {
                    try {
                        this.send(this._chunk);
                    } catch (err) {
                        return this.destroy(errCode(err, 'ERR_DATA_CHANNEL'));
                    }
                    this._chunk = null;
                    this._debug('sent chunk from "write before connect"');
                    var cb = this._cb;
                    this._cb = null;
                    cb(null);
                }
                // If `bufferedAmountLowThreshold` and 'onbufferedamountlow' are unsupported,
                // fallback to using setInterval to implement backpressure.
                if (typeof this._channel.bufferedAmountLowThreshold !== 'number') {
                    this._interval = setInterval(()=>this._onInterval()
                    , 150);
                    if (this._interval.unref) this._interval.unref();
                }
                this._debug('connect');
                this.emit('connect');
            });
        };
        findCandidatePair();
    }
    _onInterval() {
        if (!this._cb || !this._channel || this._channel.bufferedAmount > MAX_BUFFERED_AMOUNT) return;
        this._onChannelBufferedAmountLow();
    }
    _onSignalingStateChange() {
        if (this.destroyed) return;
        if (this._pc.signalingState === 'stable' && !this._firstStable) {
            this._isNegotiating = false;
            // HACK: Firefox doesn't yet support removing tracks when signalingState !== 'stable'
            this._debug('flushing sender queue', this._sendersAwaitingStable);
            this._sendersAwaitingStable.forEach((sender)=>{
                this._pc.removeTrack(sender);
                this._queuedNegotiation = true;
            });
            this._sendersAwaitingStable = [];
            if (this._queuedNegotiation) {
                this._debug('flushing negotiation queue');
                this._queuedNegotiation = false;
                this._needsNegotiation() // negotiate again
                ;
            }
            this._debug('negotiate');
            this.emit('negotiate');
        }
        this._firstStable = false;
        this._debug('signalingStateChange %s', this._pc.signalingState);
        this.emit('signalingStateChange', this._pc.signalingState);
    }
    _onIceCandidate(event) {
        if (this.destroyed) return;
        if (event.candidate && this.trickle) this.emit('signal', {
            candidate: {
                candidate: event.candidate.candidate,
                sdpMLineIndex: event.candidate.sdpMLineIndex,
                sdpMid: event.candidate.sdpMid
            }
        });
        else if (!event.candidate && !this._iceComplete) {
            this._iceComplete = true;
            this.emit('_iceComplete');
        }
        // as soon as we've received one valid candidate start timeout
        if (event.candidate) this._startIceCompleteTimeout();
    }
    _onChannelMessage(event2) {
        if (this.destroyed) return;
        var data = event2.data;
        if (data instanceof ArrayBuffer) data = new Uint8Array(data);
        this.push(data);
    }
    _onChannelBufferedAmountLow() {
        if (this.destroyed || !this._cb) return;
        this._debug('ending backpressure: bufferedAmount %d', this._channel.bufferedAmount);
        var cb = this._cb;
        this._cb = null;
        cb(null);
    }
    _onChannelOpen() {
        if (this._connected || this.destroyed) return;
        this._debug('on channel open');
        this._channelReady = true;
        this._maybeReady();
    }
    _onChannelClose() {
        if (this.destroyed) return;
        this._debug('on channel close');
        this.destroy();
    }
    _onTrack(event3) {
        if (this.destroyed) return;
        event3.streams.forEach((eventStream)=>{
            this._debug('on track');
            this.emit('track', event3.track, eventStream);
            this._remoteTracks.push({
                track: event3.track,
                stream: eventStream
            });
            if (this._remoteStreams.some((remoteStream)=>{
                return remoteStream.id === eventStream.id;
            })) return; // Only fire one 'stream' event, even though there may be multiple tracks per stream
            this._remoteStreams.push(eventStream);
            queueMicrotask(()=>{
                this.emit('stream', eventStream) // ensure all tracks have been added
                ;
            });
        });
    }
    _debug() {
        var args = [].slice.call(arguments);
        args[0] = '[' + this._id + '] ' + args[0];
        debug.apply(null, args);
    }
}
Peer.WEBRTC_SUPPORT = !!getBrowserRTC();
/**
 * Expose peer and data channel config for overriding all Peer
 * instances. Otherwise, just set opts.config or opts.channelConfig
 * when constructing a Peer.
 */ Peer.config = {
    iceServers: [
        {
            urls: [
                'stun:stun.l.google.com:19302',
                'stun:global.stun.twilio.com:3478'
            ]
        }
    ],
    sdpSemantics: 'unified-plan'
};
Peer.channelConfig = {
};
module.exports = Peer;

},{"debug":"lWlU4","get-browser-rtc":"1oNT2","randombytes":"hkZOB","readable-stream":"dDZDY","queue-microtask":"9M7Vw","err-code":"8sLlj"}],"1oNT2":[function(require,module,exports) {
// originally pulled out of simple-peer
module.exports = function getBrowserRTC() {
    if (typeof globalThis === 'undefined') return null;
    var wrtc = {
        RTCPeerConnection: globalThis.RTCPeerConnection || globalThis.mozRTCPeerConnection || globalThis.webkitRTCPeerConnection,
        RTCSessionDescription: globalThis.RTCSessionDescription || globalThis.mozRTCSessionDescription || globalThis.webkitRTCSessionDescription,
        RTCIceCandidate: globalThis.RTCIceCandidate || globalThis.mozRTCIceCandidate || globalThis.webkitRTCIceCandidate
    };
    if (!wrtc.RTCPeerConnection) return null;
    return wrtc;
};

},{}],"hkZOB":[function(require,module,exports) {
var process = require("process");
var global = arguments[3];
'use strict';
// limit of Crypto.getRandomValues()
// https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues
var MAX_BYTES = 65536;
// Node supports requesting up to this number of bytes
// https://github.com/nodejs/node/blob/master/lib/internal/crypto/random.js#L48
var MAX_UINT32 = 4294967295;
function oldBrowser() {
    throw new Error('Secure random number generation is not supported by this browser.\nUse Chrome, Firefox or Internet Explorer 11');
}
var Buffer = require('safe-buffer').Buffer;
var crypto = global.crypto || global.msCrypto;
if (crypto && crypto.getRandomValues) module.exports = randomBytes;
else module.exports = oldBrowser;
function randomBytes(size, cb) {
    // phantomjs needs to throw
    if (size > MAX_UINT32) throw new RangeError('requested too many random bytes');
    var bytes = Buffer.allocUnsafe(size);
    if (size > 0) {
        if (size > MAX_BYTES) // can do at once see https://developer.mozilla.org/en-US/docs/Web/API/window.crypto.getRandomValues
        for(var generated = 0; generated < size; generated += MAX_BYTES)// buffer.slice automatically checks if the end is past the end of
        // the buffer so we don't have to here
        crypto.getRandomValues(bytes.slice(generated, generated + MAX_BYTES));
        else crypto.getRandomValues(bytes);
    }
    if (typeof cb === 'function') return process.nextTick(function() {
        cb(null, bytes);
    });
    return bytes;
}

},{"process":"lDnB8","safe-buffer":"hZf9b"}],"hZf9b":[function(require,module,exports) {
/* eslint-disable node/no-deprecated-api */ var buffer = require('buffer');
var Buffer = buffer.Buffer;
// alternative to using Object.keys for old browsers
function copyProps(src, dst) {
    for(var key in src)dst[key] = src[key];
}
if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) module.exports = buffer;
else {
    // Copy properties from require('buffer')
    copyProps(buffer, exports);
    exports.Buffer = SafeBuffer;
}
function SafeBuffer(arg, encodingOrOffset, length) {
    return Buffer(arg, encodingOrOffset, length);
}
// Copy static methods from Buffer
copyProps(Buffer, SafeBuffer);
SafeBuffer.from = function(arg, encodingOrOffset, length) {
    if (typeof arg === 'number') throw new TypeError('Argument must not be a number');
    return Buffer(arg, encodingOrOffset, length);
};
SafeBuffer.alloc = function(size, fill, encoding) {
    if (typeof size !== 'number') throw new TypeError('Argument must be a number');
    var buf = Buffer(size);
    if (fill !== undefined) {
        if (typeof encoding === 'string') buf.fill(fill, encoding);
        else buf.fill(fill);
    } else buf.fill(0);
    return buf;
};
SafeBuffer.allocUnsafe = function(size) {
    if (typeof size !== 'number') throw new TypeError('Argument must be a number');
    return Buffer(size);
};
SafeBuffer.allocUnsafeSlow = function(size) {
    if (typeof size !== 'number') throw new TypeError('Argument must be a number');
    return buffer.SlowBuffer(size);
};

},{"buffer":"eKea5"}],"8sLlj":[function(require,module,exports) {
'use strict';
function assign(obj, props) {
    for(const key in props)Object.defineProperty(obj, key, {
        value: props[key],
        enumerable: true,
        configurable: true
    });
    return obj;
}
function createError(err, code, props) {
    if (!err || typeof err === 'string') throw new TypeError('Please pass an Error to err-code');
    if (!props) props = {
    };
    if (typeof code === 'object') {
        props = code;
        code = undefined;
    }
    if (code != null) props.code = code;
    try {
        return assign(err, props);
    } catch (_) {
        props.message = err.message;
        props.stack = err.stack;
        const ErrClass = function() {
        };
        ErrClass.prototype = Object.create(Object.getPrototypeOf(err));
        return assign(new ErrClass(), props);
    }
}
module.exports = createError;

},{}],"J54xM":[function(require,module,exports) {
'use strict';
module.exports = {
    // in React Native: global === window === self
    supportsFileReader: typeof self !== 'undefined' && 'FileReader' in self,
    supportsWebRTC: 'RTCPeerConnection' in globalThis && typeof navigator !== 'undefined' && typeof navigator.mediaDevices !== 'undefined' && 'getUserMedia' in navigator.mediaDevices,
    supportsWebRTCDataChannels: 'RTCPeerConnection' in globalThis
};

},{}],"avCUo":[function(require,module,exports) {
'use strict';
// p2p multi-address code
exports.CODE_P2P = 421;
exports.CODE_CIRCUIT = 290;
// Time to wait for a connection to close gracefully before destroying it manually
exports.CLOSE_TIMEOUT = 2000;

},{}],"f01S2":[function(require,module,exports) {
'use strict';
const EventEmitter = require('events');
const debug = require('debug');
const log = debug('libp2p:webrtc-star:listener');
log.error = debug('libp2p:webrtc-star:listener:error');
const errCode = require('err-code');
const io = require('socket.io-client');
const SimplePeer = require('libp2p-webrtc-peer');
const pDefer = require('p-defer');
const toConnection = require('./socket-to-conn');
const { cleanUrlSIO  } = require('./utils');
const { CODE_P2P  } = require('./constants');
const sioOptions = {
    transports: [
        'websocket'
    ],
    'force new connection': true,
    path: '/socket.io-next/' // This should be removed when socket.io@2 support is removed
};
module.exports = ({ handler , upgrader  }, WebRTCStar, options = {
})=>{
    const listener = new EventEmitter();
    let listeningAddr;
    let signallingUrl;
    listener.__connections = [];
    listener.__spChannels = new Map();
    listener.__pendingIntents = new Map();
    listener.listen = (ma)=>{
        // Should only be used if not already listening
        if (listeningAddr) throw errCode(new Error('listener already in use'), 'ERR_ALREADY_LISTENING');
        const defer = pDefer();
        // Should be kept unmodified
        listeningAddr = ma;
        let signallingAddr;
        if (!ma.protoCodes().includes(CODE_P2P) && upgrader.localPeer) signallingAddr = ma.encapsulate(`/p2p/${upgrader.localPeer.toB58String()}`);
        else signallingAddr = ma;
        listener.on('error', ()=>defer.reject()
        );
        signallingUrl = cleanUrlSIO(ma);
        log('Dialing to Signalling Server on: ' + signallingUrl);
        listener.io = io.connect(signallingUrl, sioOptions);
        const incomingDial = (offer)=>{
            if (offer.answer || offer.err || !offer.intentId) return;
            const intentId = offer.intentId;
            let pendings = listener.__pendingIntents.get(intentId);
            if (!pendings) {
                pendings = [];
                listener.__pendingIntents.set(intentId, pendings);
            }
            let channel = listener.__spChannels.get(intentId);
            if (channel) {
                channel.signal(offer.signal);
                return;
            } else if (offer.signal.type !== 'offer') {
                pendings.push(offer);
                return;
            }
            const spOptions = {
                trickle: false,
                ...options
            };
            // Use custom WebRTC implementation
            if (WebRTCStar.wrtc) spOptions.wrtc = WebRTCStar.wrtc;
            channel = new SimplePeer(spOptions);
            const onError = (err)=>{
                log.error('incoming connection errored', err);
            };
            channel.on('error', onError);
            channel.once('close', (...args)=>{
                channel.removeListener('error', onError);
            });
            channel.on('signal', (signal)=>{
                offer.signal = signal;
                offer.answer = true;
                listener.io.emit('ss-handshake', offer);
            });
            channel.signal(offer.signal);
            for (const pendingOffer of pendings)channel.signal(pendingOffer.signal);
            listener.__pendingIntents.set(intentId, []);
            channel.once('connect', async ()=>{
                const maConn = toConnection(channel);
                log('new inbound connection %s', maConn.remoteAddr);
                let conn;
                try {
                    conn = await upgrader.upgradeInbound(maConn);
                } catch (err) {
                    log.error('inbound connection failed to upgrade', err);
                    return maConn.close();
                }
                if (!conn.remoteAddr) try {
                    conn.remoteAddr = ma.decapsulateCode(CODE_P2P).encapsulate(`/p2p/${conn.remotePeer.toB58String()}`);
                } catch (err1) {
                    log.error('could not determine remote address', err1);
                }
                log('inbound connection %s upgraded', maConn.remoteAddr);
                trackConn(listener, maConn, intentId);
                listener.emit('connection', conn);
                handler(conn);
            });
            listener.__spChannels.set(intentId, channel);
        };
        listener.io.once('connect_error', (err)=>defer.reject(err)
        );
        listener.io.once('error', (err)=>{
            listener.emit('error', err);
            listener.emit('close');
        });
        listener.io.on('ws-handshake', incomingDial);
        listener.io.on('ws-peer', WebRTCStar._peerDiscovered);
        listener.io.on('connect', ()=>{
            listener.io.emit('ss-join', signallingAddr.toString());
        });
        listener.io.once('connect', ()=>{
            listener.emit('listening');
            defer.resolve();
        });
        // Store listen and signal reference addresses
        WebRTCStar.sigReferences.set(signallingUrl, {
            listener,
            signallingAddr
        });
        return defer.promise;
    };
    listener.close = async ()=>{
        // Close listener
        const ref = WebRTCStar.sigReferences.get(signallingUrl);
        if (ref && ref.listener.io) {
            ref.listener.io.emit('ss-leave');
            ref.listener.io.close();
        }
        await Promise.all(listener.__connections.map((maConn)=>maConn.close()
        ));
        listener.emit('close');
        listener.removeAllListeners();
        // Reset state
        listeningAddr = undefined;
        WebRTCStar.sigReferences.delete(signallingUrl);
    };
    listener.getAddrs = ()=>{
        return [
            listeningAddr
        ];
    };
    return listener;
};
function trackConn(listener, maConn, intentId) {
    listener.__connections.push(maConn);
    const untrackConn = ()=>{
        listener.__connections = listener.__connections.filter((c)=>c !== maConn
        );
        listener.__spChannels.delete(intentId);
        listener.__pendingIntents.delete(intentId);
    };
    maConn.conn.once('close', untrackConn);
}

},{"events":"bHM3D","debug":"lWlU4","err-code":"eQvyh","socket.io-client":"7GwBM","libp2p-webrtc-peer":"f7Q78","p-defer":"gZqcC","./socket-to-conn":"9tZ4u","./utils":"cPlDM","./constants":"avCUo"}],"7GwBM":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
/**
 * Protocol version.
 *
 * @public
 */ parcelHelpers.export(exports, "protocol", ()=>_socketIoParser.protocol
);
/**
 * Expose constructors for standalone build.
 *
 * @public
 */ parcelHelpers.export(exports, "Manager", ()=>_managerJs.Manager
);
parcelHelpers.export(exports, "Socket", ()=>_socketJs.Socket
);
parcelHelpers.export(exports, "io", ()=>lookup
);
parcelHelpers.export(exports, "connect", ()=>lookup
);
parcelHelpers.export(exports, "default", ()=>lookup
);
var _urlJs = require("./url.js");
var _managerJs = require("./manager.js");
var _socketJs = require("./socket.js");
var _socketIoParser = require("socket.io-parser");
/**
 * Managers cache.
 */ const cache = {
};
function lookup(uri, opts) {
    if (typeof uri === "object") {
        opts = uri;
        uri = undefined;
    }
    opts = opts || {
    };
    const parsed = _urlJs.url(uri, opts.path || "/socket.io");
    const source = parsed.source;
    const id = parsed.id;
    const path = parsed.path;
    const sameNamespace = cache[id] && path in cache[id]["nsps"];
    const newConnection = opts.forceNew || opts["force new connection"] || false === opts.multiplex || sameNamespace;
    let io;
    if (newConnection) io = new _managerJs.Manager(source, opts);
    else {
        if (!cache[id]) cache[id] = new _managerJs.Manager(source, opts);
        io = cache[id];
    }
    if (parsed.query && !opts.query) opts.query = parsed.queryKey;
    return io.socket(parsed.path, opts);
}
// so that "lookup" can be used both as a function (e.g. `io(...)`) and as a
// namespace (e.g. `io.connect(...)`), for backward compatibility
Object.assign(lookup, {
    Manager: _managerJs.Manager,
    Socket: _socketJs.Socket,
    io: lookup,
    connect: lookup
});

},{"./url.js":"4ur6q","./manager.js":"bLkMx","./socket.js":"31FZk","socket.io-parser":"37ak3","@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"4ur6q":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
/**
 * URL parser.
 *
 * @param uri - url
 * @param path - the request path of the connection
 * @param loc - An object meant to mimic window.location.
 *        Defaults to window.location.
 * @public
 */ parcelHelpers.export(exports, "url", ()=>url
);
var _parseuri = require("parseuri");
var _parseuriDefault = parcelHelpers.interopDefault(_parseuri);
function url(uri, path = "", loc) {
    let obj = uri;
    // default to window.location
    loc = loc || typeof location !== "undefined" && location;
    if (null == uri) uri = loc.protocol + "//" + loc.host;
    // relative path support
    if (typeof uri === "string") {
        if ("/" === uri.charAt(0)) {
            if ("/" === uri.charAt(1)) uri = loc.protocol + uri;
            else uri = loc.host + uri;
        }
        if (!/^(https?|wss?):\/\//.test(uri)) {
            if ("undefined" !== typeof loc) uri = loc.protocol + "//" + uri;
            else uri = "https://" + uri;
        }
        // parse
        obj = _parseuriDefault.default(uri);
    }
    // make sure we treat `localhost:80` and `localhost` equally
    if (!obj.port) {
        if (/^(http|ws)$/.test(obj.protocol)) obj.port = "80";
        else if (/^(http|ws)s$/.test(obj.protocol)) obj.port = "443";
    }
    obj.path = obj.path || "/";
    const ipv6 = obj.host.indexOf(":") !== -1;
    const host = ipv6 ? "[" + obj.host + "]" : obj.host;
    // define unique id
    obj.id = obj.protocol + "://" + host + ":" + obj.port + path;
    // define href
    obj.href = obj.protocol + "://" + host + (loc && loc.port === obj.port ? "" : ":" + obj.port);
    return obj;
}

},{"parseuri":"3wsji","@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"3wsji":[function(require,module,exports) {
/**
 * Parses an URI
 *
 * @author Steven Levithan <stevenlevithan.com> (MIT license)
 * @api private
 */ var re = /^(?:(?![^:@]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;
var parts = [
    'source',
    'protocol',
    'authority',
    'userInfo',
    'user',
    'password',
    'host',
    'port',
    'relative',
    'path',
    'directory',
    'file',
    'query',
    'anchor'
];
module.exports = function parseuri(str) {
    var src = str, b = str.indexOf('['), e = str.indexOf(']');
    if (b != -1 && e != -1) str = str.substring(0, b) + str.substring(b, e).replace(/:/g, ';') + str.substring(e, str.length);
    var m = re.exec(str || ''), uri = {
    }, i = 14;
    while(i--)uri[parts[i]] = m[i] || '';
    if (b != -1 && e != -1) {
        uri.source = src;
        uri.host = uri.host.substring(1, uri.host.length - 1).replace(/;/g, ':');
        uri.authority = uri.authority.replace('[', '').replace(']', '').replace(/;/g, ':');
        uri.ipv6uri = true;
    }
    uri.pathNames = pathNames(uri, uri['path']);
    uri.queryKey = queryKey(uri, uri['query']);
    return uri;
};
function pathNames(obj, path) {
    var regx = /\/{2,9}/g, names = path.replace(regx, "/").split("/");
    if (path.substr(0, 1) == '/' || path.length === 0) names.splice(0, 1);
    if (path.substr(path.length - 1, 1) == '/') names.splice(names.length - 1, 1);
    return names;
}
function queryKey(uri, query) {
    var data = {
    };
    query.replace(/(?:^|&)([^&=]*)=?([^&]*)/g, function($0, $1, $2) {
        if ($1) data[$1] = $2;
    });
    return data;
}

},{}],"bLkMx":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "Manager", ()=>Manager
);
var _engineIoClient = require("engine.io-client");
var _socketJs = require("./socket.js");
var _socketIoParser = require("socket.io-parser");
var _onJs = require("./on.js");
var _backo2 = require("backo2");
var _backo2Default = parcelHelpers.interopDefault(_backo2);
var _componentEmitter = require("@socket.io/component-emitter");
class Manager extends _componentEmitter.Emitter {
    constructor(uri, opts){
        var _a;
        super();
        this.nsps = {
        };
        this.subs = [];
        if (uri && "object" === typeof uri) {
            opts = uri;
            uri = undefined;
        }
        opts = opts || {
        };
        opts.path = opts.path || "/socket.io";
        this.opts = opts;
        _engineIoClient.installTimerFunctions(this, opts);
        this.reconnection(opts.reconnection !== false);
        this.reconnectionAttempts(opts.reconnectionAttempts || Infinity);
        this.reconnectionDelay(opts.reconnectionDelay || 1000);
        this.reconnectionDelayMax(opts.reconnectionDelayMax || 5000);
        this.randomizationFactor((_a = opts.randomizationFactor) !== null && _a !== void 0 ? _a : 0.5);
        this.backoff = new _backo2Default.default({
            min: this.reconnectionDelay(),
            max: this.reconnectionDelayMax(),
            jitter: this.randomizationFactor()
        });
        this.timeout(null == opts.timeout ? 20000 : opts.timeout);
        this._readyState = "closed";
        this.uri = uri;
        const _parser = opts.parser || _socketIoParser;
        this.encoder = new _parser.Encoder();
        this.decoder = new _parser.Decoder();
        this._autoConnect = opts.autoConnect !== false;
        if (this._autoConnect) this.open();
    }
    reconnection(v) {
        if (!arguments.length) return this._reconnection;
        this._reconnection = !!v;
        return this;
    }
    reconnectionAttempts(v1) {
        if (v1 === undefined) return this._reconnectionAttempts;
        this._reconnectionAttempts = v1;
        return this;
    }
    reconnectionDelay(v2) {
        var _a;
        if (v2 === undefined) return this._reconnectionDelay;
        this._reconnectionDelay = v2;
        (_a = this.backoff) === null || _a === void 0 || _a.setMin(v2);
        return this;
    }
    randomizationFactor(v3) {
        var _a;
        if (v3 === undefined) return this._randomizationFactor;
        this._randomizationFactor = v3;
        (_a = this.backoff) === null || _a === void 0 || _a.setJitter(v3);
        return this;
    }
    reconnectionDelayMax(v4) {
        var _a;
        if (v4 === undefined) return this._reconnectionDelayMax;
        this._reconnectionDelayMax = v4;
        (_a = this.backoff) === null || _a === void 0 || _a.setMax(v4);
        return this;
    }
    timeout(v5) {
        if (!arguments.length) return this._timeout;
        this._timeout = v5;
        return this;
    }
    /**
     * Starts trying to reconnect if reconnection is enabled and we have not
     * started reconnecting yet
     *
     * @private
     */ maybeReconnectOnOpen() {
        // Only try to reconnect if it's the first time we're connecting
        if (!this._reconnecting && this._reconnection && this.backoff.attempts === 0) // keeps reconnection from firing twice for the same reconnection loop
        this.reconnect();
    }
    /**
     * Sets the current transport `socket`.
     *
     * @param {Function} fn - optional, callback
     * @return self
     * @public
     */ open(fn) {
        if (~this._readyState.indexOf("open")) return this;
        this.engine = new _engineIoClient.Socket(this.uri, this.opts);
        const socket = this.engine;
        const self = this;
        this._readyState = "opening";
        this.skipReconnect = false;
        // emit `open`
        const openSubDestroy = _onJs.on(socket, "open", function() {
            self.onopen();
            fn && fn();
        });
        // emit `error`
        const errorSub = _onJs.on(socket, "error", (err)=>{
            self.cleanup();
            self._readyState = "closed";
            this.emitReserved("error", err);
            if (fn) fn(err);
            else // Only do this if there is no fn to handle the error
            self.maybeReconnectOnOpen();
        });
        if (false !== this._timeout) {
            const timeout = this._timeout;
            if (timeout === 0) openSubDestroy(); // prevents a race condition with the 'open' event
            // set timer
            const timer = this.setTimeoutFn(()=>{
                openSubDestroy();
                socket.close();
                // @ts-ignore
                socket.emit("error", new Error("timeout"));
            }, timeout);
            if (this.opts.autoUnref) timer.unref();
            this.subs.push(function subDestroy() {
                clearTimeout(timer);
            });
        }
        this.subs.push(openSubDestroy);
        this.subs.push(errorSub);
        return this;
    }
    /**
     * Alias for open()
     *
     * @return self
     * @public
     */ connect(fn1) {
        return this.open(fn1);
    }
    /**
     * Called upon transport open.
     *
     * @private
     */ onopen() {
        // clear old subs
        this.cleanup();
        // mark as open
        this._readyState = "open";
        this.emitReserved("open");
        // add new subs
        const socket = this.engine;
        this.subs.push(_onJs.on(socket, "ping", this.onping.bind(this)), _onJs.on(socket, "data", this.ondata.bind(this)), _onJs.on(socket, "error", this.onerror.bind(this)), _onJs.on(socket, "close", this.onclose.bind(this)), _onJs.on(this.decoder, "decoded", this.ondecoded.bind(this)));
    }
    /**
     * Called upon a ping.
     *
     * @private
     */ onping() {
        this.emitReserved("ping");
    }
    /**
     * Called with data.
     *
     * @private
     */ ondata(data) {
        this.decoder.add(data);
    }
    /**
     * Called when parser fully decodes a packet.
     *
     * @private
     */ ondecoded(packet) {
        this.emitReserved("packet", packet);
    }
    /**
     * Called upon socket error.
     *
     * @private
     */ onerror(err1) {
        this.emitReserved("error", err1);
    }
    /**
     * Creates a new socket for the given `nsp`.
     *
     * @return {Socket}
     * @public
     */ socket(nsp, opts1) {
        let socket = this.nsps[nsp];
        if (!socket) {
            socket = new _socketJs.Socket(this, nsp, opts1);
            this.nsps[nsp] = socket;
        }
        return socket;
    }
    /**
     * Called upon a socket close.
     *
     * @param socket
     * @private
     */ _destroy(socket) {
        const nsps = Object.keys(this.nsps);
        for (const nsp of nsps){
            const socket = this.nsps[nsp];
            if (socket.active) return;
        }
        this._close();
    }
    /**
     * Writes a packet.
     *
     * @param packet
     * @private
     */ _packet(packet1) {
        const encodedPackets = this.encoder.encode(packet1);
        for(let i = 0; i < encodedPackets.length; i++)this.engine.write(encodedPackets[i], packet1.options);
    }
    /**
     * Clean up transport subscriptions and packet buffer.
     *
     * @private
     */ cleanup() {
        this.subs.forEach((subDestroy)=>subDestroy()
        );
        this.subs.length = 0;
        this.decoder.destroy();
    }
    /**
     * Close the current socket.
     *
     * @private
     */ _close() {
        this.skipReconnect = true;
        this._reconnecting = false;
        this.onclose("forced close");
        if (this.engine) this.engine.close();
    }
    /**
     * Alias for close()
     *
     * @private
     */ disconnect() {
        return this._close();
    }
    /**
     * Called upon engine close.
     *
     * @private
     */ onclose(reason) {
        this.cleanup();
        this.backoff.reset();
        this._readyState = "closed";
        this.emitReserved("close", reason);
        if (this._reconnection && !this.skipReconnect) this.reconnect();
    }
    /**
     * Attempt a reconnection.
     *
     * @private
     */ reconnect() {
        if (this._reconnecting || this.skipReconnect) return this;
        const self = this;
        if (this.backoff.attempts >= this._reconnectionAttempts) {
            this.backoff.reset();
            this.emitReserved("reconnect_failed");
            this._reconnecting = false;
        } else {
            const delay = this.backoff.duration();
            this._reconnecting = true;
            const timer = this.setTimeoutFn(()=>{
                if (self.skipReconnect) return;
                this.emitReserved("reconnect_attempt", self.backoff.attempts);
                // check again for the case socket closed in above events
                if (self.skipReconnect) return;
                self.open((err)=>{
                    if (err) {
                        self._reconnecting = false;
                        self.reconnect();
                        this.emitReserved("reconnect_error", err);
                    } else self.onreconnect();
                });
            }, delay);
            if (this.opts.autoUnref) timer.unref();
            this.subs.push(function subDestroy() {
                clearTimeout(timer);
            });
        }
    }
    /**
     * Called upon successful reconnect.
     *
     * @private
     */ onreconnect() {
        const attempt = this.backoff.attempts;
        this._reconnecting = false;
        this.backoff.reset();
        this.emitReserved("reconnect", attempt);
    }
}

},{"engine.io-client":"kQeoz","./socket.js":"31FZk","socket.io-parser":"37ak3","./on.js":"foI8Q","backo2":"antcs","@socket.io/component-emitter":"kgnXr","@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"kQeoz":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "Socket", ()=>_socketJs.Socket
);
parcelHelpers.export(exports, "protocol", ()=>protocol
);
parcelHelpers.export(exports, "Transport", ()=>_transportJs.Transport
);
parcelHelpers.export(exports, "transports", ()=>_indexJs.transports
);
parcelHelpers.export(exports, "installTimerFunctions", ()=>_utilJs.installTimerFunctions
);
var _socketJs = require("./socket.js");
var _transportJs = require("./transport.js");
var _indexJs = require("./transports/index.js");
var _utilJs = require("./util.js");
const protocol = _socketJs.Socket.protocol;

},{"./socket.js":"59l3f","./transport.js":"heRxf","./transports/index.js":"ltUaM","./util.js":"d3Esz","@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"59l3f":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "Socket", ()=>Socket
);
var _indexJs = require("./transports/index.js");
var _utilJs = require("./util.js");
var _parseqs = require("parseqs");
var _parseqsDefault = parcelHelpers.interopDefault(_parseqs);
var _parseuri = require("parseuri");
var _parseuriDefault = parcelHelpers.interopDefault(_parseuri);
var _componentEmitter = require("@socket.io/component-emitter");
var _engineIoParser = require("engine.io-parser");
class Socket extends _componentEmitter.Emitter {
    /**
     * Socket constructor.
     *
     * @param {String|Object} uri or options
     * @param {Object} opts - options
     * @api public
     */ constructor(uri, opts = {
    }){
        super();
        if (uri && "object" === typeof uri) {
            opts = uri;
            uri = null;
        }
        if (uri) {
            uri = _parseuriDefault.default(uri);
            opts.hostname = uri.host;
            opts.secure = uri.protocol === "https" || uri.protocol === "wss";
            opts.port = uri.port;
            if (uri.query) opts.query = uri.query;
        } else if (opts.host) opts.hostname = _parseuriDefault.default(opts.host).host;
        _utilJs.installTimerFunctions(this, opts);
        this.secure = null != opts.secure ? opts.secure : typeof location !== "undefined" && "https:" === location.protocol;
        if (opts.hostname && !opts.port) // if no port is specified manually, use the protocol default
        opts.port = this.secure ? "443" : "80";
        this.hostname = opts.hostname || (typeof location !== "undefined" ? location.hostname : "localhost");
        this.port = opts.port || (typeof location !== "undefined" && location.port ? location.port : this.secure ? "443" : "80");
        this.transports = opts.transports || [
            "polling",
            "websocket"
        ];
        this.readyState = "";
        this.writeBuffer = [];
        this.prevBufferLen = 0;
        this.opts = Object.assign({
            path: "/engine.io",
            agent: false,
            withCredentials: false,
            upgrade: true,
            timestampParam: "t",
            rememberUpgrade: false,
            rejectUnauthorized: true,
            perMessageDeflate: {
                threshold: 1024
            },
            transportOptions: {
            },
            closeOnBeforeunload: true
        }, opts);
        this.opts.path = this.opts.path.replace(/\/$/, "") + "/";
        if (typeof this.opts.query === "string") this.opts.query = _parseqsDefault.default.decode(this.opts.query);
        // set on handshake
        this.id = null;
        this.upgrades = null;
        this.pingInterval = null;
        this.pingTimeout = null;
        // set on heartbeat
        this.pingTimeoutTimer = null;
        if (typeof addEventListener === "function") {
            if (this.opts.closeOnBeforeunload) // Firefox closes the connection when the "beforeunload" event is emitted but not Chrome. This event listener
            // ensures every browser behaves the same (no "disconnect" event at the Socket.IO level when the page is
            // closed/reloaded)
            addEventListener("beforeunload", ()=>{
                if (this.transport) {
                    // silently close the transport
                    this.transport.removeAllListeners();
                    this.transport.close();
                }
            }, false);
            if (this.hostname !== "localhost") {
                this.offlineEventListener = ()=>{
                    this.onClose("transport close");
                };
                addEventListener("offline", this.offlineEventListener, false);
            }
        }
        this.open();
    }
    /**
     * Creates transport of the given type.
     *
     * @param {String} transport name
     * @return {Transport}
     * @api private
     */ createTransport(name) {
        const query = clone(this.opts.query);
        // append engine.io protocol identifier
        query.EIO = _engineIoParser.protocol;
        // transport name
        query.transport = name;
        // session id if we already have one
        if (this.id) query.sid = this.id;
        const opts = Object.assign({
        }, this.opts.transportOptions[name], this.opts, {
            query,
            socket: this,
            hostname: this.hostname,
            secure: this.secure,
            port: this.port
        });
        return new _indexJs.transports[name](opts);
    }
    /**
     * Initializes transport to use and starts probe.
     *
     * @api private
     */ open() {
        let transport;
        if (this.opts.rememberUpgrade && Socket.priorWebsocketSuccess && this.transports.indexOf("websocket") !== -1) transport = "websocket";
        else if (0 === this.transports.length) {
            // Emit error on next tick so it can be listened to
            this.setTimeoutFn(()=>{
                this.emitReserved("error", "No transports available");
            }, 0);
            return;
        } else transport = this.transports[0];
        this.readyState = "opening";
        // Retry with the next transport if the transport is disabled (jsonp: false)
        try {
            transport = this.createTransport(transport);
        } catch (e) {
            this.transports.shift();
            this.open();
            return;
        }
        transport.open();
        this.setTransport(transport);
    }
    /**
     * Sets the current transport. Disables the existing one (if any).
     *
     * @api private
     */ setTransport(transport) {
        if (this.transport) this.transport.removeAllListeners();
        // set up transport
        this.transport = transport;
        // set up transport listeners
        transport.on("drain", this.onDrain.bind(this)).on("packet", this.onPacket.bind(this)).on("error", this.onError.bind(this)).on("close", ()=>{
            this.onClose("transport close");
        });
    }
    /**
     * Probes a transport.
     *
     * @param {String} transport name
     * @api private
     */ probe(name1) {
        let transport = this.createTransport(name1);
        let failed = false;
        Socket.priorWebsocketSuccess = false;
        const onTransportOpen = ()=>{
            if (failed) return;
            transport.send([
                {
                    type: "ping",
                    data: "probe"
                }
            ]);
            transport.once("packet", (msg)=>{
                if (failed) return;
                if ("pong" === msg.type && "probe" === msg.data) {
                    this.upgrading = true;
                    this.emitReserved("upgrading", transport);
                    if (!transport) return;
                    Socket.priorWebsocketSuccess = "websocket" === transport.name;
                    this.transport.pause(()=>{
                        if (failed) return;
                        if ("closed" === this.readyState) return;
                        cleanup();
                        this.setTransport(transport);
                        transport.send([
                            {
                                type: "upgrade"
                            }
                        ]);
                        this.emitReserved("upgrade", transport);
                        transport = null;
                        this.upgrading = false;
                        this.flush();
                    });
                } else {
                    const err = new Error("probe error");
                    // @ts-ignore
                    err.transport = transport.name;
                    this.emitReserved("upgradeError", err);
                }
            });
        };
        function freezeTransport() {
            if (failed) return;
            // Any callback called by transport should be ignored since now
            failed = true;
            cleanup();
            transport.close();
            transport = null;
        }
        // Handle any error that happens while probing
        const onerror = (err)=>{
            const error = new Error("probe error: " + err);
            // @ts-ignore
            error.transport = transport.name;
            freezeTransport();
            this.emitReserved("upgradeError", error);
        };
        function onTransportClose() {
            onerror("transport closed");
        }
        // When the socket is closed while we're probing
        function onclose() {
            onerror("socket closed");
        }
        // When the socket is upgraded while we're probing
        function onupgrade(to) {
            if (transport && to.name !== transport.name) freezeTransport();
        }
        // Remove all listeners on the transport and on self
        const cleanup = ()=>{
            transport.removeListener("open", onTransportOpen);
            transport.removeListener("error", onerror);
            transport.removeListener("close", onTransportClose);
            this.off("close", onclose);
            this.off("upgrading", onupgrade);
        };
        transport.once("open", onTransportOpen);
        transport.once("error", onerror);
        transport.once("close", onTransportClose);
        this.once("close", onclose);
        this.once("upgrading", onupgrade);
        transport.open();
    }
    /**
     * Called when connection is deemed open.
     *
     * @api private
     */ onOpen() {
        this.readyState = "open";
        Socket.priorWebsocketSuccess = "websocket" === this.transport.name;
        this.emitReserved("open");
        this.flush();
        // we check for `readyState` in case an `open`
        // listener already closed the socket
        if ("open" === this.readyState && this.opts.upgrade && this.transport.pause) {
            let i = 0;
            const l = this.upgrades.length;
            for(; i < l; i++)this.probe(this.upgrades[i]);
        }
    }
    /**
     * Handles a packet.
     *
     * @api private
     */ onPacket(packet) {
        if ("opening" === this.readyState || "open" === this.readyState || "closing" === this.readyState) {
            this.emitReserved("packet", packet);
            // Socket is live - any packet counts
            this.emitReserved("heartbeat");
            switch(packet.type){
                case "open":
                    this.onHandshake(JSON.parse(packet.data));
                    break;
                case "ping":
                    this.resetPingTimeout();
                    this.sendPacket("pong");
                    this.emitReserved("ping");
                    this.emitReserved("pong");
                    break;
                case "error":
                    const err = new Error("server error");
                    // @ts-ignore
                    err.code = packet.data;
                    this.onError(err);
                    break;
                case "message":
                    this.emitReserved("data", packet.data);
                    this.emitReserved("message", packet.data);
                    break;
            }
        }
    }
    /**
     * Called upon handshake completion.
     *
     * @param {Object} data - handshake obj
     * @api private
     */ onHandshake(data) {
        this.emitReserved("handshake", data);
        this.id = data.sid;
        this.transport.query.sid = data.sid;
        this.upgrades = this.filterUpgrades(data.upgrades);
        this.pingInterval = data.pingInterval;
        this.pingTimeout = data.pingTimeout;
        this.onOpen();
        // In case open handler closes socket
        if ("closed" === this.readyState) return;
        this.resetPingTimeout();
    }
    /**
     * Sets and resets ping timeout timer based on server pings.
     *
     * @api private
     */ resetPingTimeout() {
        this.clearTimeoutFn(this.pingTimeoutTimer);
        this.pingTimeoutTimer = this.setTimeoutFn(()=>{
            this.onClose("ping timeout");
        }, this.pingInterval + this.pingTimeout);
        if (this.opts.autoUnref) this.pingTimeoutTimer.unref();
    }
    /**
     * Called on `drain` event
     *
     * @api private
     */ onDrain() {
        this.writeBuffer.splice(0, this.prevBufferLen);
        // setting prevBufferLen = 0 is very important
        // for example, when upgrading, upgrade packet is sent over,
        // and a nonzero prevBufferLen could cause problems on `drain`
        this.prevBufferLen = 0;
        if (0 === this.writeBuffer.length) this.emitReserved("drain");
        else this.flush();
    }
    /**
     * Flush write buffers.
     *
     * @api private
     */ flush() {
        if ("closed" !== this.readyState && this.transport.writable && !this.upgrading && this.writeBuffer.length) {
            this.transport.send(this.writeBuffer);
            // keep track of current length of writeBuffer
            // splice writeBuffer and callbackBuffer on `drain`
            this.prevBufferLen = this.writeBuffer.length;
            this.emitReserved("flush");
        }
    }
    /**
     * Sends a message.
     *
     * @param {String} message.
     * @param {Function} callback function.
     * @param {Object} options.
     * @return {Socket} for chaining.
     * @api public
     */ write(msg, options, fn) {
        this.sendPacket("message", msg, options, fn);
        return this;
    }
    send(msg1, options1, fn1) {
        this.sendPacket("message", msg1, options1, fn1);
        return this;
    }
    /**
     * Sends a packet.
     *
     * @param {String} packet type.
     * @param {String} data.
     * @param {Object} options.
     * @param {Function} callback function.
     * @api private
     */ sendPacket(type, data1, options2, fn2) {
        if ("function" === typeof data1) {
            fn2 = data1;
            data1 = undefined;
        }
        if ("function" === typeof options2) {
            fn2 = options2;
            options2 = null;
        }
        if ("closing" === this.readyState || "closed" === this.readyState) return;
        options2 = options2 || {
        };
        options2.compress = false !== options2.compress;
        const packet = {
            type: type,
            data: data1,
            options: options2
        };
        this.emitReserved("packetCreate", packet);
        this.writeBuffer.push(packet);
        if (fn2) this.once("flush", fn2);
        this.flush();
    }
    /**
     * Closes the connection.
     *
     * @api public
     */ close() {
        const close = ()=>{
            this.onClose("forced close");
            this.transport.close();
        };
        const cleanupAndClose = ()=>{
            this.off("upgrade", cleanupAndClose);
            this.off("upgradeError", cleanupAndClose);
            close();
        };
        const waitForUpgrade = ()=>{
            // wait for upgrade to finish since we can't send packets while pausing a transport
            this.once("upgrade", cleanupAndClose);
            this.once("upgradeError", cleanupAndClose);
        };
        if ("opening" === this.readyState || "open" === this.readyState) {
            this.readyState = "closing";
            if (this.writeBuffer.length) this.once("drain", ()=>{
                if (this.upgrading) waitForUpgrade();
                else close();
            });
            else if (this.upgrading) waitForUpgrade();
            else close();
        }
        return this;
    }
    /**
     * Called upon transport error
     *
     * @api private
     */ onError(err) {
        Socket.priorWebsocketSuccess = false;
        this.emitReserved("error", err);
        this.onClose("transport error", err);
    }
    /**
     * Called upon transport close.
     *
     * @api private
     */ onClose(reason, desc) {
        if ("opening" === this.readyState || "open" === this.readyState || "closing" === this.readyState) {
            // clear timers
            this.clearTimeoutFn(this.pingTimeoutTimer);
            // stop event from firing again for transport
            this.transport.removeAllListeners("close");
            // ensure transport won't stay open
            this.transport.close();
            // ignore further transport communication
            this.transport.removeAllListeners();
            if (typeof removeEventListener === "function") removeEventListener("offline", this.offlineEventListener, false);
            // set ready state
            this.readyState = "closed";
            // clear session id
            this.id = null;
            // emit close event
            this.emitReserved("close", reason, desc);
            // clean buffers after, so users can still
            // grab the buffers on `close` event
            this.writeBuffer = [];
            this.prevBufferLen = 0;
        }
    }
    /**
     * Filters upgrades, returning only those matching client transports.
     *
     * @param {Array} server upgrades
     * @api private
     *
     */ filterUpgrades(upgrades) {
        const filteredUpgrades = [];
        let i = 0;
        const j = upgrades.length;
        for(; i < j; i++)if (~this.transports.indexOf(upgrades[i])) filteredUpgrades.push(upgrades[i]);
        return filteredUpgrades;
    }
}
Socket.protocol = _engineIoParser.protocol;
function clone(obj) {
    const o = {
    };
    for(let i in obj)if (obj.hasOwnProperty(i)) o[i] = obj[i];
    return o;
}

},{"./transports/index.js":"ltUaM","./util.js":"d3Esz","parseqs":"9ozfP","parseuri":"3wsji","@socket.io/component-emitter":"kgnXr","engine.io-parser":"1k1e7","@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"ltUaM":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "transports", ()=>transports
);
var _pollingXhrJs = require("./polling-xhr.js");
var _websocketJs = require("./websocket.js");
const transports = {
    websocket: _websocketJs.WS,
    polling: _pollingXhrJs.XHR
};

},{"./polling-xhr.js":"1bHFr","./websocket.js":"2R4hk","@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"1bHFr":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "XHR", ()=>XHR
);
parcelHelpers.export(exports, "Request", ()=>Request
);
/* global attachEvent */ var _xmlhttprequestJs = require("./xmlhttprequest.js");
var _xmlhttprequestJsDefault = parcelHelpers.interopDefault(_xmlhttprequestJs);
var _globalThisJs = require("../globalThis.js");
var _globalThisJsDefault = parcelHelpers.interopDefault(_globalThisJs);
var _utilJs = require("../util.js");
var _componentEmitter = require("@socket.io/component-emitter");
var _pollingJs = require("./polling.js");
/**
 * Empty function
 */ function empty() {
}
const hasXHR2 = function() {
    const xhr = new _xmlhttprequestJsDefault.default({
        xdomain: false
    });
    return null != xhr.responseType;
}();
class XHR extends _pollingJs.Polling {
    /**
     * XHR Polling constructor.
     *
     * @param {Object} opts
     * @api public
     */ constructor(opts){
        super(opts);
        if (typeof location !== "undefined") {
            const isSSL = "https:" === location.protocol;
            let port = location.port;
            // some user agents have empty `location.port`
            if (!port) port = isSSL ? "443" : "80";
            this.xd = typeof location !== "undefined" && opts.hostname !== location.hostname || port !== opts.port;
            this.xs = opts.secure !== isSSL;
        }
        /**
         * XHR supports binary
         */ const forceBase64 = opts && opts.forceBase64;
        this.supportsBinary = hasXHR2 && !forceBase64;
    }
    /**
     * Creates a request.
     *
     * @param {String} method
     * @api private
     */ request(opts1 = {
    }) {
        Object.assign(opts1, {
            xd: this.xd,
            xs: this.xs
        }, this.opts);
        return new Request(this.uri(), opts1);
    }
    /**
     * Sends data.
     *
     * @param {String} data to send.
     * @param {Function} called upon flush.
     * @api private
     */ doWrite(data, fn) {
        const req = this.request({
            method: "POST",
            data: data
        });
        req.on("success", fn);
        req.on("error", (err)=>{
            this.onError("xhr post error", err);
        });
    }
    /**
     * Starts a poll cycle.
     *
     * @api private
     */ doPoll() {
        const req = this.request();
        req.on("data", this.onData.bind(this));
        req.on("error", (err)=>{
            this.onError("xhr poll error", err);
        });
        this.pollXhr = req;
    }
}
class Request extends _componentEmitter.Emitter {
    /**
     * Request constructor
     *
     * @param {Object} options
     * @api public
     */ constructor(uri, opts2){
        super();
        _utilJs.installTimerFunctions(this, opts2);
        this.opts = opts2;
        this.method = opts2.method || "GET";
        this.uri = uri;
        this.async = false !== opts2.async;
        this.data = undefined !== opts2.data ? opts2.data : null;
        this.create();
    }
    /**
     * Creates the XHR object and sends the request.
     *
     * @api private
     */ create() {
        const opts = _utilJs.pick(this.opts, "agent", "pfx", "key", "passphrase", "cert", "ca", "ciphers", "rejectUnauthorized", "autoUnref");
        opts.xdomain = !!this.opts.xd;
        opts.xscheme = !!this.opts.xs;
        const xhr = this.xhr = new _xmlhttprequestJsDefault.default(opts);
        try {
            xhr.open(this.method, this.uri, this.async);
            try {
                if (this.opts.extraHeaders) {
                    xhr.setDisableHeaderCheck && xhr.setDisableHeaderCheck(true);
                    for(let i in this.opts.extraHeaders)if (this.opts.extraHeaders.hasOwnProperty(i)) xhr.setRequestHeader(i, this.opts.extraHeaders[i]);
                }
            } catch (e) {
            }
            if ("POST" === this.method) try {
                xhr.setRequestHeader("Content-type", "text/plain;charset=UTF-8");
            } catch (e1) {
            }
            try {
                xhr.setRequestHeader("Accept", "*/*");
            } catch (e2) {
            }
            // ie6 check
            if ("withCredentials" in xhr) xhr.withCredentials = this.opts.withCredentials;
            if (this.opts.requestTimeout) xhr.timeout = this.opts.requestTimeout;
            xhr.onreadystatechange = ()=>{
                if (4 !== xhr.readyState) return;
                if (200 === xhr.status || 1223 === xhr.status) this.onLoad();
                else // make sure the `error` event handler that's user-set
                // does not throw in the same tick and gets caught here
                this.setTimeoutFn(()=>{
                    this.onError(typeof xhr.status === "number" ? xhr.status : 0);
                }, 0);
            };
            xhr.send(this.data);
        } catch (e) {
            // Need to defer since .create() is called directly from the constructor
            // and thus the 'error' event can only be only bound *after* this exception
            // occurs.  Therefore, also, we cannot throw here at all.
            this.setTimeoutFn(()=>{
                this.onError(e);
            }, 0);
            return;
        }
        if (typeof document !== "undefined") {
            this.index = Request.requestsCount++;
            Request.requests[this.index] = this;
        }
    }
    /**
     * Called upon successful response.
     *
     * @api private
     */ onSuccess() {
        this.emit("success");
        this.cleanup();
    }
    /**
     * Called if we have data.
     *
     * @api private
     */ onData(data1) {
        this.emit("data", data1);
        this.onSuccess();
    }
    /**
     * Called upon error.
     *
     * @api private
     */ onError(err) {
        this.emit("error", err);
        this.cleanup(true);
    }
    /**
     * Cleans up house.
     *
     * @api private
     */ cleanup(fromError) {
        if ("undefined" === typeof this.xhr || null === this.xhr) return;
        this.xhr.onreadystatechange = empty;
        if (fromError) try {
            this.xhr.abort();
        } catch (e) {
        }
        if (typeof document !== "undefined") delete Request.requests[this.index];
        this.xhr = null;
    }
    /**
     * Called upon load.
     *
     * @api private
     */ onLoad() {
        const data = this.xhr.responseText;
        if (data !== null) this.onData(data);
    }
    /**
     * Aborts the request.
     *
     * @api public
     */ abort() {
        this.cleanup();
    }
}
Request.requestsCount = 0;
Request.requests = {
};
/**
 * Aborts pending requests when unloading the window. This is needed to prevent
 * memory leaks (e.g. when using IE) and to ensure that no spurious error is
 * emitted.
 */ if (typeof document !== "undefined") {
    // @ts-ignore
    if (typeof attachEvent === "function") // @ts-ignore
    attachEvent("onunload", unloadHandler);
    else if (typeof addEventListener === "function") {
        const terminationEvent = "onpagehide" in _globalThisJsDefault.default ? "pagehide" : "unload";
        addEventListener(terminationEvent, unloadHandler, false);
    }
}
function unloadHandler() {
    for(let i in Request.requests)if (Request.requests.hasOwnProperty(i)) Request.requests[i].abort();
}

},{"./xmlhttprequest.js":"835QK","../globalThis.js":"gdRVd","../util.js":"d3Esz","@socket.io/component-emitter":"kgnXr","./polling.js":"9pBIv","@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"835QK":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
// browser shim for xmlhttprequest module
var _hasCors = require("has-cors");
var _hasCorsDefault = parcelHelpers.interopDefault(_hasCors);
var _globalThisJs = require("../globalThis.js");
var _globalThisJsDefault = parcelHelpers.interopDefault(_globalThisJs);
exports.default = function(opts) {
    const xdomain = opts.xdomain;
    // XMLHttpRequest can be disabled on IE
    try {
        if ("undefined" !== typeof XMLHttpRequest && (!xdomain || _hasCorsDefault.default)) return new XMLHttpRequest();
    } catch (e) {
    }
    if (!xdomain) try {
        return new _globalThisJsDefault.default[[
            "Active"
        ].concat("Object").join("X")]("Microsoft.XMLHTTP");
    } catch (e1) {
    }
};

},{"has-cors":"hESuY","../globalThis.js":"gdRVd","@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"hESuY":[function(require,module,exports) {
/**
 * Module exports.
 *
 * Logic borrowed from Modernizr:
 *
 *   - https://github.com/Modernizr/Modernizr/blob/master/feature-detects/cors.js
 */ try {
    module.exports = typeof XMLHttpRequest !== 'undefined' && 'withCredentials' in new XMLHttpRequest();
} catch (err) {
    // if XMLHttp support is disabled in IE then it will throw
    // when trying to create
    module.exports = false;
}

},{}],"gdRVd":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
exports.default = (()=>{
    if (typeof self !== "undefined") return self;
    else if (typeof window !== "undefined") return window;
    else return Function("return this")();
})();

},{"@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"d3Esz":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "pick", ()=>pick
);
parcelHelpers.export(exports, "installTimerFunctions", ()=>installTimerFunctions
);
var _globalThisJs = require("./globalThis.js");
var _globalThisJsDefault = parcelHelpers.interopDefault(_globalThisJs);
function pick(obj, ...attr) {
    return attr.reduce((acc, k)=>{
        if (obj.hasOwnProperty(k)) acc[k] = obj[k];
        return acc;
    }, {
    });
}
// Keep a reference to the real timeout functions so they can be used when overridden
const NATIVE_SET_TIMEOUT = setTimeout;
const NATIVE_CLEAR_TIMEOUT = clearTimeout;
function installTimerFunctions(obj, opts) {
    if (opts.useNativeTimers) {
        obj.setTimeoutFn = NATIVE_SET_TIMEOUT.bind(_globalThisJsDefault.default);
        obj.clearTimeoutFn = NATIVE_CLEAR_TIMEOUT.bind(_globalThisJsDefault.default);
    } else {
        obj.setTimeoutFn = setTimeout.bind(_globalThisJsDefault.default);
        obj.clearTimeoutFn = clearTimeout.bind(_globalThisJsDefault.default);
    }
}

},{"./globalThis.js":"gdRVd","@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"kgnXr":[function(require,module,exports) {
/**
 * Expose `Emitter`.
 */ exports.Emitter = Emitter;
/**
 * Initialize a new `Emitter`.
 *
 * @api public
 */ function Emitter(obj) {
    if (obj) return mixin(obj);
}
/**
 * Mixin the emitter properties.
 *
 * @param {Object} obj
 * @return {Object}
 * @api private
 */ function mixin(obj) {
    for(var key in Emitter.prototype)obj[key] = Emitter.prototype[key];
    return obj;
}
/**
 * Listen on the given `event` with `fn`.
 *
 * @param {String} event
 * @param {Function} fn
 * @return {Emitter}
 * @api public
 */ Emitter.prototype.on = Emitter.prototype.addEventListener = function(event, fn) {
    this._callbacks = this._callbacks || {
    };
    (this._callbacks['$' + event] = this._callbacks['$' + event] || []).push(fn);
    return this;
};
/**
 * Adds an `event` listener that will be invoked a single
 * time then automatically removed.
 *
 * @param {String} event
 * @param {Function} fn
 * @return {Emitter}
 * @api public
 */ Emitter.prototype.once = function(event, fn) {
    function on() {
        this.off(event, on);
        fn.apply(this, arguments);
    }
    on.fn = fn;
    this.on(event, on);
    return this;
};
/**
 * Remove the given callback for `event` or all
 * registered callbacks.
 *
 * @param {String} event
 * @param {Function} fn
 * @return {Emitter}
 * @api public
 */ Emitter.prototype.off = Emitter.prototype.removeListener = Emitter.prototype.removeAllListeners = Emitter.prototype.removeEventListener = function(event, fn) {
    this._callbacks = this._callbacks || {
    };
    // all
    if (0 == arguments.length) {
        this._callbacks = {
        };
        return this;
    }
    // specific event
    var callbacks = this._callbacks['$' + event];
    if (!callbacks) return this;
    // remove all handlers
    if (1 == arguments.length) {
        delete this._callbacks['$' + event];
        return this;
    }
    // remove specific handler
    var cb;
    for(var i = 0; i < callbacks.length; i++){
        cb = callbacks[i];
        if (cb === fn || cb.fn === fn) {
            callbacks.splice(i, 1);
            break;
        }
    }
    // Remove event specific arrays for event types that no
    // one is subscribed for to avoid memory leak.
    if (callbacks.length === 0) delete this._callbacks['$' + event];
    return this;
};
/**
 * Emit `event` with the given args.
 *
 * @param {String} event
 * @param {Mixed} ...
 * @return {Emitter}
 */ Emitter.prototype.emit = function(event) {
    this._callbacks = this._callbacks || {
    };
    var args = new Array(arguments.length - 1), callbacks = this._callbacks['$' + event];
    for(var i = 1; i < arguments.length; i++)args[i - 1] = arguments[i];
    if (callbacks) {
        callbacks = callbacks.slice(0);
        for(var i = 0, len = callbacks.length; i < len; ++i)callbacks[i].apply(this, args);
    }
    return this;
};
// alias used for reserved events (protected method)
Emitter.prototype.emitReserved = Emitter.prototype.emit;
/**
 * Return array of callbacks for `event`.
 *
 * @param {String} event
 * @return {Array}
 * @api public
 */ Emitter.prototype.listeners = function(event) {
    this._callbacks = this._callbacks || {
    };
    return this._callbacks['$' + event] || [];
};
/**
 * Check if this emitter has `event` handlers.
 *
 * @param {String} event
 * @return {Boolean}
 * @api public
 */ Emitter.prototype.hasListeners = function(event) {
    return !!this.listeners(event).length;
};

},{}],"9pBIv":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "Polling", ()=>Polling
);
var _transportJs = require("../transport.js");
var _yeast = require("yeast");
var _yeastDefault = parcelHelpers.interopDefault(_yeast);
var _parseqs = require("parseqs");
var _parseqsDefault = parcelHelpers.interopDefault(_parseqs);
var _engineIoParser = require("engine.io-parser");
class Polling extends _transportJs.Transport {
    constructor(){
        super(...arguments);
        this.polling = false;
    }
    /**
     * Transport name.
     */ get name() {
        return "polling";
    }
    /**
     * Opens the socket (triggers polling). We write a PING message to determine
     * when the transport is open.
     *
     * @api private
     */ doOpen() {
        this.poll();
    }
    /**
     * Pauses polling.
     *
     * @param {Function} callback upon buffers are flushed and transport is paused
     * @api private
     */ pause(onPause) {
        this.readyState = "pausing";
        const pause = ()=>{
            this.readyState = "paused";
            onPause();
        };
        if (this.polling || !this.writable) {
            let total = 0;
            if (this.polling) {
                total++;
                this.once("pollComplete", function() {
                    --total || pause();
                });
            }
            if (!this.writable) {
                total++;
                this.once("drain", function() {
                    --total || pause();
                });
            }
        } else pause();
    }
    /**
     * Starts polling cycle.
     *
     * @api public
     */ poll() {
        this.polling = true;
        this.doPoll();
        this.emit("poll");
    }
    /**
     * Overloads onData to detect payloads.
     *
     * @api private
     */ onData(data1) {
        const callback = (packet)=>{
            // if its the first message we consider the transport open
            if ("opening" === this.readyState && packet.type === "open") this.onOpen();
            // if its a close packet, we close the ongoing requests
            if ("close" === packet.type) {
                this.onClose();
                return false;
            }
            // otherwise bypass onData and handle the message
            this.onPacket(packet);
        };
        // decode payload
        _engineIoParser.decodePayload(data1, this.socket.binaryType).forEach(callback);
        // if an event did not trigger closing
        if ("closed" !== this.readyState) {
            // if we got data we're not polling
            this.polling = false;
            this.emit("pollComplete");
            if ("open" === this.readyState) this.poll();
        }
    }
    /**
     * For polling, send a close packet.
     *
     * @api private
     */ doClose() {
        const close = ()=>{
            this.write([
                {
                    type: "close"
                }
            ]);
        };
        if ("open" === this.readyState) close();
        else // in case we're trying to close while
        // handshaking is in progress (GH-164)
        this.once("open", close);
    }
    /**
     * Writes a packets payload.
     *
     * @param {Array} data packets
     * @param {Function} drain callback
     * @api private
     */ write(packets) {
        this.writable = false;
        _engineIoParser.encodePayload(packets, (data)=>{
            this.doWrite(data, ()=>{
                this.writable = true;
                this.emit("drain");
            });
        });
    }
    /**
     * Generates uri for connection.
     *
     * @api private
     */ uri() {
        let query = this.query || {
        };
        const schema = this.opts.secure ? "https" : "http";
        let port = "";
        // cache busting is forced
        if (false !== this.opts.timestampRequests) query[this.opts.timestampParam] = _yeastDefault.default();
        if (!this.supportsBinary && !query.sid) query.b64 = 1;
        // avoid port if default for schema
        if (this.opts.port && ("https" === schema && Number(this.opts.port) !== 443 || "http" === schema && Number(this.opts.port) !== 80)) port = ":" + this.opts.port;
        const encodedQuery = _parseqsDefault.default.encode(query);
        const ipv6 = this.opts.hostname.indexOf(":") !== -1;
        return schema + "://" + (ipv6 ? "[" + this.opts.hostname + "]" : this.opts.hostname) + port + this.opts.path + (encodedQuery.length ? "?" + encodedQuery : "");
    }
}

},{"../transport.js":"heRxf","yeast":"f8fLx","parseqs":"9ozfP","engine.io-parser":"1k1e7","@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"heRxf":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "Transport", ()=>Transport
);
var _engineIoParser = require("engine.io-parser");
var _componentEmitter = require("@socket.io/component-emitter");
var _utilJs = require("./util.js");
class Transport extends _componentEmitter.Emitter {
    /**
     * Transport abstract constructor.
     *
     * @param {Object} options.
     * @api private
     */ constructor(opts){
        super();
        this.writable = false;
        _utilJs.installTimerFunctions(this, opts);
        this.opts = opts;
        this.query = opts.query;
        this.readyState = "";
        this.socket = opts.socket;
    }
    /**
     * Emits an error.
     *
     * @param {String} str
     * @return {Transport} for chaining
     * @api protected
     */ onError(msg, desc) {
        const err = new Error(msg);
        // @ts-ignore
        err.type = "TransportError";
        // @ts-ignore
        err.description = desc;
        super.emit("error", err);
        return this;
    }
    /**
     * Opens the transport.
     *
     * @api public
     */ open() {
        if ("closed" === this.readyState || "" === this.readyState) {
            this.readyState = "opening";
            this.doOpen();
        }
        return this;
    }
    /**
     * Closes the transport.
     *
     * @api public
     */ close() {
        if ("opening" === this.readyState || "open" === this.readyState) {
            this.doClose();
            this.onClose();
        }
        return this;
    }
    /**
     * Sends multiple packets.
     *
     * @param {Array} packets
     * @api public
     */ send(packets) {
        if ("open" === this.readyState) this.write(packets);
    }
    /**
     * Called upon open
     *
     * @api protected
     */ onOpen() {
        this.readyState = "open";
        this.writable = true;
        super.emit("open");
    }
    /**
     * Called with data.
     *
     * @param {String} data
     * @api protected
     */ onData(data) {
        const packet = _engineIoParser.decodePacket(data, this.socket.binaryType);
        this.onPacket(packet);
    }
    /**
     * Called with a decoded packet.
     *
     * @api protected
     */ onPacket(packet) {
        super.emit("packet", packet);
    }
    /**
     * Called upon close.
     *
     * @api protected
     */ onClose() {
        this.readyState = "closed";
        super.emit("close");
    }
}

},{"engine.io-parser":"1k1e7","@socket.io/component-emitter":"kgnXr","./util.js":"d3Esz","@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"1k1e7":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "protocol", ()=>protocol
);
parcelHelpers.export(exports, "encodePacket", ()=>_encodePacketJsDefault.default
);
parcelHelpers.export(exports, "encodePayload", ()=>encodePayload
);
parcelHelpers.export(exports, "decodePacket", ()=>_decodePacketJsDefault.default
);
parcelHelpers.export(exports, "decodePayload", ()=>decodePayload
);
var _encodePacketJs = require("./encodePacket.js");
var _encodePacketJsDefault = parcelHelpers.interopDefault(_encodePacketJs);
var _decodePacketJs = require("./decodePacket.js");
var _decodePacketJsDefault = parcelHelpers.interopDefault(_decodePacketJs);
const SEPARATOR = String.fromCharCode(30); // see https://en.wikipedia.org/wiki/Delimiter#ASCII_delimited_text
const encodePayload = (packets, callback)=>{
    // some packets may be added to the array while encoding, so the initial length must be saved
    const length = packets.length;
    const encodedPackets = new Array(length);
    let count = 0;
    packets.forEach((packet, i)=>{
        // force base64 encoding for binary packets
        _encodePacketJsDefault.default(packet, false, (encodedPacket)=>{
            encodedPackets[i] = encodedPacket;
            if (++count === length) callback(encodedPackets.join(SEPARATOR));
        });
    });
};
const decodePayload = (encodedPayload, binaryType)=>{
    const encodedPackets = encodedPayload.split(SEPARATOR);
    const packets = [];
    for(let i = 0; i < encodedPackets.length; i++){
        const decodedPacket = _decodePacketJsDefault.default(encodedPackets[i], binaryType);
        packets.push(decodedPacket);
        if (decodedPacket.type === "error") break;
    }
    return packets;
};
const protocol = 4;

},{"./encodePacket.js":"k2Mjc","./decodePacket.js":"gFioO","@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"k2Mjc":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
var _commonsJs = require("./commons.js");
const withNativeBlob = typeof Blob === "function" || typeof Blob !== "undefined" && Object.prototype.toString.call(Blob) === "[object BlobConstructor]";
const withNativeArrayBuffer = typeof ArrayBuffer === "function";
// ArrayBuffer.isView method is not defined in IE10
const isView = (obj)=>{
    return typeof ArrayBuffer.isView === "function" ? ArrayBuffer.isView(obj) : obj && obj.buffer instanceof ArrayBuffer;
};
const encodePacket = ({ type , data  }, supportsBinary, callback)=>{
    if (withNativeBlob && data instanceof Blob) {
        if (supportsBinary) return callback(data);
        else return encodeBlobAsBase64(data, callback);
    } else if (withNativeArrayBuffer && (data instanceof ArrayBuffer || isView(data))) {
        if (supportsBinary) return callback(data);
        else return encodeBlobAsBase64(new Blob([
            data
        ]), callback);
    }
    // plain string
    return callback(_commonsJs.PACKET_TYPES[type] + (data || ""));
};
const encodeBlobAsBase64 = (data, callback)=>{
    const fileReader = new FileReader();
    fileReader.onload = function() {
        const content = fileReader.result.split(",")[1];
        callback("b" + content);
    };
    return fileReader.readAsDataURL(data);
};
exports.default = encodePacket;

},{"./commons.js":"bXajh","@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"bXajh":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "PACKET_TYPES", ()=>PACKET_TYPES
);
parcelHelpers.export(exports, "PACKET_TYPES_REVERSE", ()=>PACKET_TYPES_REVERSE
);
parcelHelpers.export(exports, "ERROR_PACKET", ()=>ERROR_PACKET
);
const PACKET_TYPES = Object.create(null); // no Map = no polyfill
PACKET_TYPES["open"] = "0";
PACKET_TYPES["close"] = "1";
PACKET_TYPES["ping"] = "2";
PACKET_TYPES["pong"] = "3";
PACKET_TYPES["message"] = "4";
PACKET_TYPES["upgrade"] = "5";
PACKET_TYPES["noop"] = "6";
const PACKET_TYPES_REVERSE = Object.create(null);
Object.keys(PACKET_TYPES).forEach((key)=>{
    PACKET_TYPES_REVERSE[PACKET_TYPES[key]] = key;
});
const ERROR_PACKET = {
    type: "error",
    data: "parser error"
};

},{"@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"gFioO":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
var _commonsJs = require("./commons.js");
var _base64Arraybuffer = require("base64-arraybuffer");
const withNativeArrayBuffer = typeof ArrayBuffer === "function";
const decodePacket = (encodedPacket, binaryType)=>{
    if (typeof encodedPacket !== "string") return {
        type: "message",
        data: mapBinary(encodedPacket, binaryType)
    };
    const type = encodedPacket.charAt(0);
    if (type === "b") return {
        type: "message",
        data: decodeBase64Packet(encodedPacket.substring(1), binaryType)
    };
    const packetType = _commonsJs.PACKET_TYPES_REVERSE[type];
    if (!packetType) return _commonsJs.ERROR_PACKET;
    return encodedPacket.length > 1 ? {
        type: _commonsJs.PACKET_TYPES_REVERSE[type],
        data: encodedPacket.substring(1)
    } : {
        type: _commonsJs.PACKET_TYPES_REVERSE[type]
    };
};
const decodeBase64Packet = (data, binaryType)=>{
    if (withNativeArrayBuffer) {
        const decoded = _base64Arraybuffer.decode(data);
        return mapBinary(decoded, binaryType);
    } else return {
        base64: true,
        data
    }; // fallback for old browsers
};
const mapBinary = (data, binaryType)=>{
    switch(binaryType){
        case "blob":
            return data instanceof ArrayBuffer ? new Blob([
                data
            ]) : data;
        case "arraybuffer":
        default:
            return data; // assuming the data is already an ArrayBuffer
    }
};
exports.default = decodePacket;

},{"./commons.js":"bXajh","base64-arraybuffer":"jdSE9","@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"jdSE9":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "decode", ()=>decode
);
parcelHelpers.export(exports, "encode", ()=>encode
);
/*
 * base64-arraybuffer 1.0.1 <https://github.com/niklasvh/base64-arraybuffer>
 * Copyright (c) 2021 Niklas von Hertzen <https://hertzen.com>
 * Released under MIT License
 */ var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
// Use a lookup table to find the index.
var lookup = typeof Uint8Array === 'undefined' ? [] : new Uint8Array(256);
for(var i1 = 0; i1 < chars.length; i1++)lookup[chars.charCodeAt(i1)] = i1;
var encode = function(arraybuffer) {
    var bytes = new Uint8Array(arraybuffer), i, len = bytes.length, base64 = '';
    for(i = 0; i < len; i += 3){
        base64 += chars[bytes[i] >> 2];
        base64 += chars[(bytes[i] & 3) << 4 | bytes[i + 1] >> 4];
        base64 += chars[(bytes[i + 1] & 15) << 2 | bytes[i + 2] >> 6];
        base64 += chars[bytes[i + 2] & 63];
    }
    if (len % 3 === 2) base64 = base64.substring(0, base64.length - 1) + '=';
    else if (len % 3 === 1) base64 = base64.substring(0, base64.length - 2) + '==';
    return base64;
};
var decode = function(base64) {
    var bufferLength = base64.length * 0.75, len = base64.length, i, p = 0, encoded1, encoded2, encoded3, encoded4;
    if (base64[base64.length - 1] === '=') {
        bufferLength--;
        if (base64[base64.length - 2] === '=') bufferLength--;
    }
    var arraybuffer = new ArrayBuffer(bufferLength), bytes = new Uint8Array(arraybuffer);
    for(i = 0; i < len; i += 4){
        encoded1 = lookup[base64.charCodeAt(i)];
        encoded2 = lookup[base64.charCodeAt(i + 1)];
        encoded3 = lookup[base64.charCodeAt(i + 2)];
        encoded4 = lookup[base64.charCodeAt(i + 3)];
        bytes[p++] = encoded1 << 2 | encoded2 >> 4;
        bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2;
        bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63;
    }
    return arraybuffer;
};

},{"@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"f8fLx":[function(require,module,exports) {
'use strict';
var alphabet = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_'.split(''), length = 64, map = {
}, seed = 0, i = 0, prev;
/**
 * Return a string representing the specified number.
 *
 * @param {Number} num The number to convert.
 * @returns {String} The string representation of the number.
 * @api public
 */ function encode(num) {
    var encoded = '';
    do {
        encoded = alphabet[num % length] + encoded;
        num = Math.floor(num / length);
    }while (num > 0)
    return encoded;
}
/**
 * Return the integer value specified by the given string.
 *
 * @param {String} str The string to convert.
 * @returns {Number} The integer value represented by the string.
 * @api public
 */ function decode(str) {
    var decoded = 0;
    for(i = 0; i < str.length; i++)decoded = decoded * length + map[str.charAt(i)];
    return decoded;
}
/**
 * Yeast: A tiny growing id generator.
 *
 * @returns {String} A unique id.
 * @api public
 */ function yeast() {
    var now = encode(+new Date());
    if (now !== prev) return seed = 0, prev = now;
    return now + '.' + encode(seed++);
}
//
// Map each character to its index.
//
for(; i < length; i++)map[alphabet[i]] = i;
//
// Expose the `yeast`, `encode` and `decode` functions.
//
yeast.encode = encode;
yeast.decode = decode;
module.exports = yeast;

},{}],"9ozfP":[function(require,module,exports) {
/**
 * Compiles a querystring
 * Returns string representation of the object
 *
 * @param {Object}
 * @api private
 */ exports.encode = function(obj) {
    var str = '';
    for(var i in obj)if (obj.hasOwnProperty(i)) {
        if (str.length) str += '&';
        str += encodeURIComponent(i) + '=' + encodeURIComponent(obj[i]);
    }
    return str;
};
/**
 * Parses a simple querystring into an object
 *
 * @param {String} qs
 * @api private
 */ exports.decode = function(qs) {
    var qry = {
    };
    var pairs = qs.split('&');
    for(var i = 0, l = pairs.length; i < l; i++){
        var pair = pairs[i].split('=');
        qry[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
    }
    return qry;
};

},{}],"2R4hk":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "WS", ()=>WS
);
var _transportJs = require("../transport.js");
var _parseqs = require("parseqs");
var _parseqsDefault = parcelHelpers.interopDefault(_parseqs);
var _yeast = require("yeast");
var _yeastDefault = parcelHelpers.interopDefault(_yeast);
var _utilJs = require("../util.js");
var _websocketConstructorJs = require("./websocket-constructor.js");
var _engineIoParser = require("engine.io-parser");
var Buffer = require("buffer").Buffer;
// detect ReactNative environment
const isReactNative = typeof navigator !== "undefined" && typeof navigator.product === "string" && navigator.product.toLowerCase() === "reactnative";
class WS extends _transportJs.Transport {
    /**
     * WebSocket transport constructor.
     *
     * @api {Object} connection options
     * @api public
     */ constructor(opts1){
        super(opts1);
        this.supportsBinary = !opts1.forceBase64;
    }
    /**
     * Transport name.
     *
     * @api public
     */ get name() {
        return "websocket";
    }
    /**
     * Opens socket.
     *
     * @api private
     */ doOpen() {
        if (!this.check()) // let probe timeout
        return;
        const uri = this.uri();
        const protocols = this.opts.protocols;
        // React Native only supports the 'headers' option, and will print a warning if anything else is passed
        const opts = isReactNative ? {
        } : _utilJs.pick(this.opts, "agent", "perMessageDeflate", "pfx", "key", "passphrase", "cert", "ca", "ciphers", "rejectUnauthorized", "localAddress", "protocolVersion", "origin", "maxPayload", "family", "checkServerIdentity");
        if (this.opts.extraHeaders) opts.headers = this.opts.extraHeaders;
        try {
            this.ws = _websocketConstructorJs.usingBrowserWebSocket && !isReactNative ? protocols ? new _websocketConstructorJs.WebSocket(uri, protocols) : new _websocketConstructorJs.WebSocket(uri) : new _websocketConstructorJs.WebSocket(uri, protocols, opts);
        } catch (err) {
            return this.emit("error", err);
        }
        this.ws.binaryType = this.socket.binaryType || _websocketConstructorJs.defaultBinaryType;
        this.addEventListeners();
    }
    /**
     * Adds event listeners to the socket
     *
     * @api private
     */ addEventListeners() {
        this.ws.onopen = ()=>{
            if (this.opts.autoUnref) this.ws._socket.unref();
            this.onOpen();
        };
        this.ws.onclose = this.onClose.bind(this);
        this.ws.onmessage = (ev)=>this.onData(ev.data)
        ;
        this.ws.onerror = (e)=>this.onError("websocket error", e)
        ;
    }
    /**
     * Writes data to socket.
     *
     * @param {Array} array of packets.
     * @api private
     */ write(packets) {
        this.writable = false;
        // encodePacket efficient as it uses WS framing
        // no need for encodePayload
        for(let i = 0; i < packets.length; i++){
            const packet = packets[i];
            const lastPacket = i === packets.length - 1;
            _engineIoParser.encodePacket(packet, this.supportsBinary, (data)=>{
                // always create a new object (GH-437)
                const opts = {
                };
                if (!_websocketConstructorJs.usingBrowserWebSocket) {
                    if (packet.options) opts.compress = packet.options.compress;
                    if (this.opts.perMessageDeflate) {
                        const len = "string" === typeof data ? Buffer.byteLength(data) : data.length;
                        if (len < this.opts.perMessageDeflate.threshold) opts.compress = false;
                    }
                }
                // Sometimes the websocket has already been closed but the browser didn't
                // have a chance of informing us about it yet, in that case send will
                // throw an error
                try {
                    if (_websocketConstructorJs.usingBrowserWebSocket) // TypeError is thrown when passing the second argument on Safari
                    this.ws.send(data);
                    else this.ws.send(data, opts);
                } catch (e) {
                }
                if (lastPacket) // fake drain
                // defer to next tick to allow Socket to clear writeBuffer
                _websocketConstructorJs.nextTick(()=>{
                    this.writable = true;
                    this.emit("drain");
                }, this.setTimeoutFn);
            });
        }
    }
    /**
     * Closes socket.
     *
     * @api private
     */ doClose() {
        if (typeof this.ws !== "undefined") {
            this.ws.close();
            this.ws = null;
        }
    }
    /**
     * Generates uri for connection.
     *
     * @api private
     */ uri() {
        let query = this.query || {
        };
        const schema = this.opts.secure ? "wss" : "ws";
        let port = "";
        // avoid port if default for schema
        if (this.opts.port && ("wss" === schema && Number(this.opts.port) !== 443 || "ws" === schema && Number(this.opts.port) !== 80)) port = ":" + this.opts.port;
        // append timestamp to URI
        if (this.opts.timestampRequests) query[this.opts.timestampParam] = _yeastDefault.default();
        // communicate binary support capabilities
        if (!this.supportsBinary) query.b64 = 1;
        const encodedQuery = _parseqsDefault.default.encode(query);
        const ipv6 = this.opts.hostname.indexOf(":") !== -1;
        return schema + "://" + (ipv6 ? "[" + this.opts.hostname + "]" : this.opts.hostname) + port + this.opts.path + (encodedQuery.length ? "?" + encodedQuery : "");
    }
    /**
     * Feature detection for WebSocket.
     *
     * @return {Boolean} whether this transport is available.
     * @api public
     */ check() {
        return !!_websocketConstructorJs.WebSocket && !("__initialize" in _websocketConstructorJs.WebSocket && this.name === WS.prototype.name);
    }
}

},{"buffer":"eKea5","../transport.js":"heRxf","parseqs":"9ozfP","yeast":"f8fLx","../util.js":"d3Esz","./websocket-constructor.js":"9jCat","engine.io-parser":"1k1e7","@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"9jCat":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "nextTick", ()=>nextTick
);
parcelHelpers.export(exports, "WebSocket", ()=>WebSocket
);
parcelHelpers.export(exports, "usingBrowserWebSocket", ()=>usingBrowserWebSocket
);
parcelHelpers.export(exports, "defaultBinaryType", ()=>defaultBinaryType
);
var _globalThisJs = require("../globalThis.js");
var _globalThisJsDefault = parcelHelpers.interopDefault(_globalThisJs);
const nextTick = (()=>{
    const isPromiseAvailable = typeof Promise === "function" && typeof Promise.resolve === "function";
    if (isPromiseAvailable) return (cb)=>Promise.resolve().then(cb)
    ;
    else return (cb, setTimeoutFn)=>setTimeoutFn(cb, 0)
    ;
})();
const WebSocket = _globalThisJsDefault.default.WebSocket || _globalThisJsDefault.default.MozWebSocket;
const usingBrowserWebSocket = true;
const defaultBinaryType = "arraybuffer";

},{"../globalThis.js":"gdRVd","@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"31FZk":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "Socket", ()=>Socket
);
var _socketIoParser = require("socket.io-parser");
var _onJs = require("./on.js");
var _componentEmitter = require("@socket.io/component-emitter");
/**
 * Internal events.
 * These events can't be emitted by the user.
 */ const RESERVED_EVENTS = Object.freeze({
    connect: 1,
    connect_error: 1,
    disconnect: 1,
    disconnecting: 1,
    // EventEmitter reserved events: https://nodejs.org/api/events.html#events_event_newlistener
    newListener: 1,
    removeListener: 1
});
class Socket extends _componentEmitter.Emitter {
    /**
     * `Socket` constructor.
     *
     * @public
     */ constructor(io, nsp, opts){
        super();
        this.connected = false;
        this.disconnected = true;
        this.receiveBuffer = [];
        this.sendBuffer = [];
        this.ids = 0;
        this.acks = {
        };
        this.flags = {
        };
        this.io = io;
        this.nsp = nsp;
        if (opts && opts.auth) this.auth = opts.auth;
        if (this.io._autoConnect) this.open();
    }
    /**
     * Subscribe to open, close and packet events
     *
     * @private
     */ subEvents() {
        if (this.subs) return;
        const io = this.io;
        this.subs = [
            _onJs.on(io, "open", this.onopen.bind(this)),
            _onJs.on(io, "packet", this.onpacket.bind(this)),
            _onJs.on(io, "error", this.onerror.bind(this)),
            _onJs.on(io, "close", this.onclose.bind(this)), 
        ];
    }
    /**
     * Whether the Socket will try to reconnect when its Manager connects or reconnects
     */ get active() {
        return !!this.subs;
    }
    /**
     * "Opens" the socket.
     *
     * @public
     */ connect() {
        if (this.connected) return this;
        this.subEvents();
        if (!this.io["_reconnecting"]) this.io.open(); // ensure open
        if ("open" === this.io._readyState) this.onopen();
        return this;
    }
    /**
     * Alias for connect()
     */ open() {
        return this.connect();
    }
    /**
     * Sends a `message` event.
     *
     * @return self
     * @public
     */ send(...args2) {
        args2.unshift("message");
        this.emit.apply(this, args2);
        return this;
    }
    /**
     * Override `emit`.
     * If the event is in `events`, it's emitted normally.
     *
     * @return self
     * @public
     */ emit(ev, ...args1) {
        if (RESERVED_EVENTS.hasOwnProperty(ev)) throw new Error('"' + ev + '" is a reserved event name');
        args1.unshift(ev);
        const packet = {
            type: _socketIoParser.PacketType.EVENT,
            data: args1
        };
        packet.options = {
        };
        packet.options.compress = this.flags.compress !== false;
        // event ack callback
        if ("function" === typeof args1[args1.length - 1]) {
            const id = this.ids++;
            const ack = args1.pop();
            this._registerAckCallback(id, ack);
            packet.id = id;
        }
        const isTransportWritable = this.io.engine && this.io.engine.transport && this.io.engine.transport.writable;
        const discardPacket = this.flags.volatile && (!isTransportWritable || !this.connected);
        if (discardPacket) ;
        else if (this.connected) this.packet(packet);
        else this.sendBuffer.push(packet);
        this.flags = {
        };
        return this;
    }
    /**
     * @private
     */ _registerAckCallback(id, ack) {
        const timeout = this.flags.timeout;
        if (timeout === undefined) {
            this.acks[id] = ack;
            return;
        }
        // @ts-ignore
        const timer = this.io.setTimeoutFn(()=>{
            delete this.acks[id];
            for(let i = 0; i < this.sendBuffer.length; i++)if (this.sendBuffer[i].id === id) this.sendBuffer.splice(i, 1);
            ack.call(this, new Error("operation has timed out"));
        }, timeout);
        this.acks[id] = (...args)=>{
            // @ts-ignore
            this.io.clearTimeoutFn(timer);
            ack.apply(this, [
                null,
                ...args
            ]);
        };
    }
    /**
     * Sends a packet.
     *
     * @param packet
     * @private
     */ packet(packet4) {
        packet4.nsp = this.nsp;
        this.io._packet(packet4);
    }
    /**
     * Called upon engine `open`.
     *
     * @private
     */ onopen() {
        if (typeof this.auth == "function") this.auth((data)=>{
            this.packet({
                type: _socketIoParser.PacketType.CONNECT,
                data
            });
        });
        else this.packet({
            type: _socketIoParser.PacketType.CONNECT,
            data: this.auth
        });
    }
    /**
     * Called upon engine or manager `error`.
     *
     * @param err
     * @private
     */ onerror(err) {
        if (!this.connected) this.emitReserved("connect_error", err);
    }
    /**
     * Called upon engine `close`.
     *
     * @param reason
     * @private
     */ onclose(reason) {
        this.connected = false;
        this.disconnected = true;
        delete this.id;
        this.emitReserved("disconnect", reason);
    }
    /**
     * Called with socket packet.
     *
     * @param packet
     * @private
     */ onpacket(packet1) {
        const sameNamespace = packet1.nsp === this.nsp;
        if (!sameNamespace) return;
        switch(packet1.type){
            case _socketIoParser.PacketType.CONNECT:
                if (packet1.data && packet1.data.sid) {
                    const id = packet1.data.sid;
                    this.onconnect(id);
                } else this.emitReserved("connect_error", new Error("It seems you are trying to reach a Socket.IO server in v2.x with a v3.x client, but they are not compatible (more information here: https://socket.io/docs/v3/migrating-from-2-x-to-3-0/)"));
                break;
            case _socketIoParser.PacketType.EVENT:
                this.onevent(packet1);
                break;
            case _socketIoParser.PacketType.BINARY_EVENT:
                this.onevent(packet1);
                break;
            case _socketIoParser.PacketType.ACK:
                this.onack(packet1);
                break;
            case _socketIoParser.PacketType.BINARY_ACK:
                this.onack(packet1);
                break;
            case _socketIoParser.PacketType.DISCONNECT:
                this.ondisconnect();
                break;
            case _socketIoParser.PacketType.CONNECT_ERROR:
                this.destroy();
                const err = new Error(packet1.data.message);
                // @ts-ignore
                err.data = packet1.data.data;
                this.emitReserved("connect_error", err);
                break;
        }
    }
    /**
     * Called upon a server event.
     *
     * @param packet
     * @private
     */ onevent(packet2) {
        const args = packet2.data || [];
        if (null != packet2.id) args.push(this.ack(packet2.id));
        if (this.connected) this.emitEvent(args);
        else this.receiveBuffer.push(Object.freeze(args));
    }
    emitEvent(args3) {
        if (this._anyListeners && this._anyListeners.length) {
            const listeners = this._anyListeners.slice();
            for (const listener of listeners)listener.apply(this, args3);
        }
        super.emit.apply(this, args3);
    }
    /**
     * Produces an ack callback to emit with an event.
     *
     * @private
     */ ack(id1) {
        const self = this;
        let sent = false;
        return function(...args) {
            // prevent double callbacks
            if (sent) return;
            sent = true;
            self.packet({
                type: _socketIoParser.PacketType.ACK,
                id: id1,
                data: args
            });
        };
    }
    /**
     * Called upon a server acknowlegement.
     *
     * @param packet
     * @private
     */ onack(packet3) {
        const ack = this.acks[packet3.id];
        if ("function" === typeof ack) {
            ack.apply(this, packet3.data);
            delete this.acks[packet3.id];
        }
    }
    /**
     * Called upon server connect.
     *
     * @private
     */ onconnect(id2) {
        this.id = id2;
        this.connected = true;
        this.disconnected = false;
        this.emitBuffered();
        this.emitReserved("connect");
    }
    /**
     * Emit buffered events (received and emitted).
     *
     * @private
     */ emitBuffered() {
        this.receiveBuffer.forEach((args)=>this.emitEvent(args)
        );
        this.receiveBuffer = [];
        this.sendBuffer.forEach((packet)=>this.packet(packet)
        );
        this.sendBuffer = [];
    }
    /**
     * Called upon server disconnect.
     *
     * @private
     */ ondisconnect() {
        this.destroy();
        this.onclose("io server disconnect");
    }
    /**
     * Called upon forced client/server side disconnections,
     * this method ensures the manager stops tracking us and
     * that reconnections don't get triggered for this.
     *
     * @private
     */ destroy() {
        if (this.subs) {
            // clean subscriptions to avoid reconnections
            this.subs.forEach((subDestroy)=>subDestroy()
            );
            this.subs = undefined;
        }
        this.io["_destroy"](this);
    }
    /**
     * Disconnects the socket manually.
     *
     * @return self
     * @public
     */ disconnect() {
        if (this.connected) this.packet({
            type: _socketIoParser.PacketType.DISCONNECT
        });
        // remove socket from pool
        this.destroy();
        if (this.connected) // fire events
        this.onclose("io client disconnect");
        return this;
    }
    /**
     * Alias for disconnect()
     *
     * @return self
     * @public
     */ close() {
        return this.disconnect();
    }
    /**
     * Sets the compress flag.
     *
     * @param compress - if `true`, compresses the sending data
     * @return self
     * @public
     */ compress(compress) {
        this.flags.compress = compress;
        return this;
    }
    /**
     * Sets a modifier for a subsequent event emission that the event message will be dropped when this socket is not
     * ready to send messages.
     *
     * @returns self
     * @public
     */ get volatile() {
        this.flags.volatile = true;
        return this;
    }
    /**
     * Sets a modifier for a subsequent event emission that the callback will be called with an error when the
     * given number of milliseconds have elapsed without an acknowledgement from the server:
     *
     * ```
     * socket.timeout(5000).emit("my-event", (err) => {
     *   if (err) {
     *     // the server did not acknowledge the event in the given delay
     *   }
     * });
     * ```
     *
     * @returns self
     * @public
     */ timeout(timeout) {
        this.flags.timeout = timeout;
        return this;
    }
    /**
     * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the
     * callback.
     *
     * @param listener
     * @public
     */ onAny(listener) {
        this._anyListeners = this._anyListeners || [];
        this._anyListeners.push(listener);
        return this;
    }
    /**
     * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the
     * callback. The listener is added to the beginning of the listeners array.
     *
     * @param listener
     * @public
     */ prependAny(listener1) {
        this._anyListeners = this._anyListeners || [];
        this._anyListeners.unshift(listener1);
        return this;
    }
    /**
     * Removes the listener that will be fired when any event is emitted.
     *
     * @param listener
     * @public
     */ offAny(listener2) {
        if (!this._anyListeners) return this;
        if (listener2) {
            const listeners = this._anyListeners;
            for(let i = 0; i < listeners.length; i++)if (listener2 === listeners[i]) {
                listeners.splice(i, 1);
                return this;
            }
        } else this._anyListeners = [];
        return this;
    }
    /**
     * Returns an array of listeners that are listening for any event that is specified. This array can be manipulated,
     * e.g. to remove listeners.
     *
     * @public
     */ listenersAny() {
        return this._anyListeners || [];
    }
}

},{"socket.io-parser":"37ak3","./on.js":"foI8Q","@socket.io/component-emitter":"kgnXr","@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"37ak3":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "protocol", ()=>protocol
);
parcelHelpers.export(exports, "PacketType", ()=>PacketType1
);
/**
 * A socket.io Encoder instance
 */ parcelHelpers.export(exports, "Encoder", ()=>Encoder
);
/**
 * A socket.io Decoder instance
 *
 * @return {Object} decoder
 */ parcelHelpers.export(exports, "Decoder", ()=>Decoder
);
var _componentEmitter = require("@socket.io/component-emitter");
var _binaryJs = require("./binary.js");
var _isBinaryJs = require("./is-binary.js");
const protocol = 5;
var PacketType1;
(function(PacketType) {
    PacketType[PacketType["CONNECT"] = 0] = "CONNECT";
    PacketType[PacketType["DISCONNECT"] = 1] = "DISCONNECT";
    PacketType[PacketType["EVENT"] = 2] = "EVENT";
    PacketType[PacketType["ACK"] = 3] = "ACK";
    PacketType[PacketType["CONNECT_ERROR"] = 4] = "CONNECT_ERROR";
    PacketType[PacketType["BINARY_EVENT"] = 5] = "BINARY_EVENT";
    PacketType[PacketType["BINARY_ACK"] = 6] = "BINARY_ACK";
})(PacketType1 || (PacketType1 = {
}));
class Encoder {
    /**
     * Encode a packet as a single string if non-binary, or as a
     * buffer sequence, depending on packet type.
     *
     * @param {Object} obj - packet object
     */ encode(obj) {
        if (obj.type === PacketType1.EVENT || obj.type === PacketType1.ACK) {
            if (_isBinaryJs.hasBinary(obj)) {
                obj.type = obj.type === PacketType1.EVENT ? PacketType1.BINARY_EVENT : PacketType1.BINARY_ACK;
                return this.encodeAsBinary(obj);
            }
        }
        return [
            this.encodeAsString(obj)
        ];
    }
    /**
     * Encode packet as string.
     */ encodeAsString(obj1) {
        // first is type
        let str = "" + obj1.type;
        // attachments if we have them
        if (obj1.type === PacketType1.BINARY_EVENT || obj1.type === PacketType1.BINARY_ACK) str += obj1.attachments + "-";
        // if we have a namespace other than `/`
        // we append it followed by a comma `,`
        if (obj1.nsp && "/" !== obj1.nsp) str += obj1.nsp + ",";
        // immediately followed by the id
        if (null != obj1.id) str += obj1.id;
        // json data
        if (null != obj1.data) str += JSON.stringify(obj1.data);
        return str;
    }
    /**
     * Encode packet as 'buffer sequence' by removing blobs, and
     * deconstructing packet into object with placeholders and
     * a list of buffers.
     */ encodeAsBinary(obj2) {
        const deconstruction = _binaryJs.deconstructPacket(obj2);
        const pack = this.encodeAsString(deconstruction.packet);
        const buffers = deconstruction.buffers;
        buffers.unshift(pack); // add packet info to beginning of data list
        return buffers; // write all the buffers
    }
}
class Decoder extends _componentEmitter.Emitter {
    constructor(){
        super();
    }
    /**
     * Decodes an encoded packet string into packet JSON.
     *
     * @param {String} obj - encoded packet
     */ add(obj3) {
        let packet;
        if (typeof obj3 === "string") {
            packet = this.decodeString(obj3);
            if (packet.type === PacketType1.BINARY_EVENT || packet.type === PacketType1.BINARY_ACK) {
                // binary packet's json
                this.reconstructor = new BinaryReconstructor(packet);
                // no attachments, labeled binary but no binary data to follow
                if (packet.attachments === 0) super.emitReserved("decoded", packet);
            } else // non-binary full packet
            super.emitReserved("decoded", packet);
        } else if (_isBinaryJs.isBinary(obj3) || obj3.base64) {
            // raw binary data
            if (!this.reconstructor) throw new Error("got binary data when not reconstructing a packet");
            else {
                packet = this.reconstructor.takeBinaryData(obj3);
                if (packet) {
                    // received final buffer
                    this.reconstructor = null;
                    super.emitReserved("decoded", packet);
                }
            }
        } else throw new Error("Unknown type: " + obj3);
    }
    /**
     * Decode a packet String (JSON data)
     *
     * @param {String} str
     * @return {Object} packet
     */ decodeString(str1) {
        let i = 0;
        // look up type
        const p = {
            type: Number(str1.charAt(0))
        };
        if (PacketType1[p.type] === undefined) throw new Error("unknown packet type " + p.type);
        // look up attachments if type binary
        if (p.type === PacketType1.BINARY_EVENT || p.type === PacketType1.BINARY_ACK) {
            const start = i + 1;
            while(str1.charAt(++i) !== "-" && i != str1.length);
            const buf = str1.substring(start, i);
            if (buf != Number(buf) || str1.charAt(i) !== "-") throw new Error("Illegal attachments");
            p.attachments = Number(buf);
        }
        // look up namespace (if any)
        if ("/" === str1.charAt(i + 1)) {
            const start = i + 1;
            while(++i){
                const c = str1.charAt(i);
                if ("," === c) break;
                if (i === str1.length) break;
            }
            p.nsp = str1.substring(start, i);
        } else p.nsp = "/";
        // look up id
        const next = str1.charAt(i + 1);
        if ("" !== next && Number(next) == next) {
            const start = i + 1;
            while(++i){
                const c = str1.charAt(i);
                if (null == c || Number(c) != c) {
                    --i;
                    break;
                }
                if (i === str1.length) break;
            }
            p.id = Number(str1.substring(start, i + 1));
        }
        // look up json data
        if (str1.charAt(++i)) {
            const payload = tryParse(str1.substr(i));
            if (Decoder.isPayloadValid(p.type, payload)) p.data = payload;
            else throw new Error("invalid payload");
        }
        return p;
    }
    static isPayloadValid(type, payload) {
        switch(type){
            case PacketType1.CONNECT:
                return typeof payload === "object";
            case PacketType1.DISCONNECT:
                return payload === undefined;
            case PacketType1.CONNECT_ERROR:
                return typeof payload === "string" || typeof payload === "object";
            case PacketType1.EVENT:
            case PacketType1.BINARY_EVENT:
                return Array.isArray(payload) && payload.length > 0;
            case PacketType1.ACK:
            case PacketType1.BINARY_ACK:
                return Array.isArray(payload);
        }
    }
    /**
     * Deallocates a parser's resources
     */ destroy() {
        if (this.reconstructor) this.reconstructor.finishedReconstruction();
    }
}
function tryParse(str) {
    try {
        return JSON.parse(str);
    } catch (e) {
        return false;
    }
}
/**
 * A manager of a binary event's 'buffer sequence'. Should
 * be constructed whenever a packet of type BINARY_EVENT is
 * decoded.
 *
 * @param {Object} packet
 * @return {BinaryReconstructor} initialized reconstructor
 */ class BinaryReconstructor {
    constructor(packet){
        this.packet = packet;
        this.buffers = [];
        this.reconPack = packet;
    }
    /**
     * Method to be called when binary data received from connection
     * after a BINARY_EVENT packet.
     *
     * @param {Buffer | ArrayBuffer} binData - the raw binary data received
     * @return {null | Object} returns null if more binary data is expected or
     *   a reconstructed packet object if all buffers have been received.
     */ takeBinaryData(binData) {
        this.buffers.push(binData);
        if (this.buffers.length === this.reconPack.attachments) {
            // done with buffer list
            const packet = _binaryJs.reconstructPacket(this.reconPack, this.buffers);
            this.finishedReconstruction();
            return packet;
        }
        return null;
    }
    /**
     * Cleans up binary packet reconstruction variables.
     */ finishedReconstruction() {
        this.reconPack = null;
        this.buffers = [];
    }
}

},{"@socket.io/component-emitter":"kgnXr","./binary.js":"cUXVr","./is-binary.js":"dZPgJ","@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"cUXVr":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
/**
 * Replaces every Buffer | ArrayBuffer | Blob | File in packet with a numbered placeholder.
 *
 * @param {Object} packet - socket.io event packet
 * @return {Object} with deconstructed packet and list of buffers
 * @public
 */ parcelHelpers.export(exports, "deconstructPacket", ()=>deconstructPacket
);
/**
 * Reconstructs a binary packet from its placeholder packet and buffers
 *
 * @param {Object} packet - event packet with placeholders
 * @param {Array} buffers - binary buffers to put in placeholder positions
 * @return {Object} reconstructed packet
 * @public
 */ parcelHelpers.export(exports, "reconstructPacket", ()=>reconstructPacket
);
var _isBinaryJs = require("./is-binary.js");
function deconstructPacket(packet) {
    const buffers = [];
    const packetData = packet.data;
    const pack = packet;
    pack.data = _deconstructPacket(packetData, buffers);
    pack.attachments = buffers.length; // number of binary 'attachments'
    return {
        packet: pack,
        buffers: buffers
    };
}
function _deconstructPacket(data, buffers) {
    if (!data) return data;
    if (_isBinaryJs.isBinary(data)) {
        const placeholder = {
            _placeholder: true,
            num: buffers.length
        };
        buffers.push(data);
        return placeholder;
    } else if (Array.isArray(data)) {
        const newData = new Array(data.length);
        for(let i = 0; i < data.length; i++)newData[i] = _deconstructPacket(data[i], buffers);
        return newData;
    } else if (typeof data === "object" && !(data instanceof Date)) {
        const newData = {
        };
        for(const key in data)if (data.hasOwnProperty(key)) newData[key] = _deconstructPacket(data[key], buffers);
        return newData;
    }
    return data;
}
function reconstructPacket(packet, buffers) {
    packet.data = _reconstructPacket(packet.data, buffers);
    packet.attachments = undefined; // no longer useful
    return packet;
}
function _reconstructPacket(data, buffers) {
    if (!data) return data;
    if (data && data._placeholder) return buffers[data.num]; // appropriate buffer (should be natural order anyway)
    else if (Array.isArray(data)) for(let i = 0; i < data.length; i++)data[i] = _reconstructPacket(data[i], buffers);
    else if (typeof data === "object") {
        for(const key in data)if (data.hasOwnProperty(key)) data[key] = _reconstructPacket(data[key], buffers);
    }
    return data;
}

},{"./is-binary.js":"dZPgJ","@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"dZPgJ":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
/**
 * Returns true if obj is a Buffer, an ArrayBuffer, a Blob or a File.
 *
 * @private
 */ parcelHelpers.export(exports, "isBinary", ()=>isBinary
);
parcelHelpers.export(exports, "hasBinary", ()=>hasBinary
);
const withNativeArrayBuffer = typeof ArrayBuffer === "function";
const isView = (obj)=>{
    return typeof ArrayBuffer.isView === "function" ? ArrayBuffer.isView(obj) : obj.buffer instanceof ArrayBuffer;
};
const toString = Object.prototype.toString;
const withNativeBlob = typeof Blob === "function" || typeof Blob !== "undefined" && toString.call(Blob) === "[object BlobConstructor]";
const withNativeFile = typeof File === "function" || typeof File !== "undefined" && toString.call(File) === "[object FileConstructor]";
function isBinary(obj) {
    return withNativeArrayBuffer && (obj instanceof ArrayBuffer || isView(obj)) || withNativeBlob && obj instanceof Blob || withNativeFile && obj instanceof File;
}
function hasBinary(obj, toJSON) {
    if (!obj || typeof obj !== "object") return false;
    if (Array.isArray(obj)) {
        for(let i = 0, l = obj.length; i < l; i++){
            if (hasBinary(obj[i])) return true;
        }
        return false;
    }
    if (isBinary(obj)) return true;
    if (obj.toJSON && typeof obj.toJSON === "function" && arguments.length === 1) return hasBinary(obj.toJSON(), true);
    for(const key in obj){
        if (Object.prototype.hasOwnProperty.call(obj, key) && hasBinary(obj[key])) return true;
    }
    return false;
}

},{"@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"foI8Q":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "on", ()=>on
);
function on(obj, ev, fn) {
    obj.on(ev, fn);
    return function subDestroy() {
        obj.off(ev, fn);
    };
}

},{"@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"antcs":[function(require,module,exports) {
/**
 * Expose `Backoff`.
 */ module.exports = Backoff;
/**
 * Initialize backoff timer with `opts`.
 *
 * - `min` initial timeout in milliseconds [100]
 * - `max` max timeout [10000]
 * - `jitter` [0]
 * - `factor` [2]
 *
 * @param {Object} opts
 * @api public
 */ function Backoff(opts) {
    opts = opts || {
    };
    this.ms = opts.min || 100;
    this.max = opts.max || 10000;
    this.factor = opts.factor || 2;
    this.jitter = opts.jitter > 0 && opts.jitter <= 1 ? opts.jitter : 0;
    this.attempts = 0;
}
/**
 * Return the backoff duration.
 *
 * @return {Number}
 * @api public
 */ Backoff.prototype.duration = function() {
    var ms = this.ms * Math.pow(this.factor, this.attempts++);
    if (this.jitter) {
        var rand = Math.random();
        var deviation = Math.floor(rand * this.jitter * ms);
        ms = (Math.floor(rand * 10) & 1) == 0 ? ms - deviation : ms + deviation;
    }
    return Math.min(ms, this.max) | 0;
};
/**
 * Reset the number of attempts.
 *
 * @api public
 */ Backoff.prototype.reset = function() {
    this.attempts = 0;
};
/**
 * Set the minimum duration
 *
 * @api public
 */ Backoff.prototype.setMin = function(min) {
    this.ms = min;
};
/**
 * Set the maximum duration
 *
 * @api public
 */ Backoff.prototype.setMax = function(max) {
    this.max = max;
};
/**
 * Set the jitter
 *
 * @api public
 */ Backoff.prototype.setJitter = function(jitter) {
    this.jitter = jitter;
};

},{}],"9tZ4u":[function(require,module,exports) {
'use strict';
const abortable = require('abortable-iterator');
const toIterable = require('stream-to-it');
const { CLOSE_TIMEOUT  } = require('./constants');
const toMultiaddr = require('libp2p-utils/src/ip-port-to-multiaddr');
const debug = require('debug');
const log = debug('libp2p:webrtc-star:socket');
log.error = debug('libp2p:webrtc-star:socket:error');
const toWebrtcMultiaddr = (address, port)=>{
    if (!address || !port) return undefined;
    try {
        return toMultiaddr(address, port);
    } catch (err) {
        log.error(err);
        // Account for mdns hostnames, just make it a local ip for now
        return toMultiaddr('0.0.0.0', port);
    }
};
// Convert a socket into a MultiaddrConnection
// https://github.com/libp2p/js-libp2p-interfaces/tree/master/src/transport#multiaddrconnection
module.exports = (socket, options = {
})=>{
    const { sink , source: source1  } = toIterable.duplex(socket);
    // If the remote address was passed, use it - it may have the peer ID encapsulated
    const remoteAddr = options.remoteAddr || toWebrtcMultiaddr(socket.remoteAddress, socket.remotePort);
    const localAddr = toWebrtcMultiaddr(socket.localAddress, socket.localPort);
    const maConn = {
        async sink (source) {
            if (options.signal) source = abortable(source, options.signal);
            try {
                await sink(async function*() {
                    for await (const chunk of source)// Convert BufferList to Buffer
                    yield chunk instanceof Uint8Array ? chunk : chunk.slice();
                }());
            } catch (err) {
                // If aborted we can safely ignore
                if (err.type !== 'aborted') // If the source errored the socket will already have been destroyed by
                // toIterable.duplex(). If the socket errored it will already be
                // destroyed. There's nothing to do here except log the error & return.
                log.error(err);
            }
        },
        source: options.signal ? abortable(source1, options.signal) : source1,
        conn: socket,
        localAddr,
        remoteAddr,
        timeline: {
            open: Date.now()
        },
        close () {
            if (socket.destroyed) return;
            return new Promise((resolve, reject)=>{
                const start = Date.now();
                // Attempt to end the socket. If it takes longer to close than the
                // timeout, destroy it manually.
                const timeout = setTimeout(()=>{
                    if (maConn.remoteAddr) {
                        const { host , port  } = maConn.remoteAddr.toOptions();
                        log('timeout closing socket to %s:%s after %dms, destroying it manually', host, port, Date.now() - start);
                    }
                    if (!socket.destroyed) socket.destroy();
                }, CLOSE_TIMEOUT);
                socket.once('close', ()=>{
                    resolve();
                });
                socket.end((err)=>{
                    clearTimeout(timeout);
                    maConn.timeline.close = Date.now();
                    if (err) return reject(err);
                });
            });
        }
    };
    socket.once('close', ()=>{
        // In instances where `close` was not explicitly called,
        // such as an iterable stream ending, ensure we have set the close
        // timeline
        if (!maConn.timeline.close) maConn.timeline.close = Date.now();
    });
    return maConn;
};

},{"abortable-iterator":"3n79Y","stream-to-it":"7P6rU","./constants":"avCUo","libp2p-utils/src/ip-port-to-multiaddr":"bkzJE","debug":"lWlU4"}],"7P6rU":[function(require,module,exports) {
module.exports = require('./source');
module.exports.source = require('./source');
module.exports.sink = require('./sink');
module.exports.transform = require('./transform');
module.exports.duplex = require('./duplex');

},{"./source":"aJitJ","./sink":"otzV1","./transform":"bCZHf","./duplex":"1iphj"}],"otzV1":[function(require,module,exports) {
const getIterator = require('get-iterator');
module.exports = (writable)=>async (source1)=>{
        source1 = getIterator(source1);
        const maybeEndSource = (source)=>{
            if (typeof source.return === 'function') source.return();
        };
        let error = null;
        let errCb = null;
        const errorHandler = (err)=>{
            error = err;
            if (errCb) errCb(err);
            // When the writable errors, try to end the source to exit iteration early
            maybeEndSource(source1);
        };
        let closeCb = null;
        let closed = false;
        const closeHandler = ()=>{
            closed = true;
            if (closeCb) closeCb();
        };
        let finishCb = null;
        let finished = false;
        const finishHandler = ()=>{
            finished = true;
            if (finishCb) finishCb();
        };
        let drainCb = null;
        const drainHandler = ()=>{
            if (drainCb) drainCb();
        };
        const waitForDrainOrClose = ()=>{
            return new Promise((resolve, reject)=>{
                closeCb = drainCb = resolve;
                errCb = reject;
                writable.once('drain', drainHandler);
            });
        };
        const waitForDone = ()=>{
            // Immediately try to end the source
            maybeEndSource(source1);
            return new Promise((resolve, reject)=>{
                if (closed || finished || error) return resolve();
                finishCb = closeCb = resolve;
                errCb = reject;
            });
        };
        const cleanup = ()=>{
            writable.removeListener('error', errorHandler);
            writable.removeListener('close', closeHandler);
            writable.removeListener('finish', finishHandler);
            writable.removeListener('drain', drainHandler);
        };
        writable.once('error', errorHandler);
        writable.once('close', closeHandler);
        writable.once('finish', finishHandler);
        try {
            for await (const value of source1){
                if (!writable.writable || writable.destroyed || error) break;
                if (writable.write(value) === false) await waitForDrainOrClose();
            }
        } catch (err) {
            // error is set by stream error handler so only destroy stream if source threw
            if (!error) writable.destroy();
            // could we be obscuring an error here?
            error = err;
        }
        try {
            // We're done writing, end everything (n.b. stream may be destroyed at this point but then this is a no-op)
            if (writable.writable) writable.end();
            // Wait until we close or finish. This supports halfClosed streams
            await waitForDone();
            // Notify the user an error occurred
            if (error) throw error;
        } finally{
            // Clean up listeners
            cleanup();
        }
    }
;

},{"get-iterator":"lJJ8v"}],"bCZHf":[function(require,module,exports) {
const toDuplex = require('./duplex');
module.exports = (transform)=>async function*(source) {
        const duplex = toDuplex(transform);
        // In a transform the sink and source are connected, an error in the sink
        // will be thrown in the source also. Catch the sink error to avoid unhandled
        // rejections and yield from the source.
        let sinkError;
        duplex.sink(source).catch((err)=>{
            sinkError = err;
        });
        yield* duplex.source;
        if (sinkError) throw sinkError;
    }
;

},{"./duplex":"1iphj"}],"1iphj":[function(require,module,exports) {
const toSink = require('./sink');
const toSource = require('./source');
module.exports = (duplex)=>({
        sink: toSink(duplex),
        source: toSource(duplex)
    })
;

},{"./sink":"otzV1","./source":"aJitJ"}],"cPlDM":[function(require,module,exports) {
'use strict';
const { Multiaddr  } = require('multiaddr');
function cleanUrlSIO(ma) {
    const maStrSplit = ma.toString().split('/');
    const tcpProto = ma.protos()[1].name;
    const wsProto = ma.protos()[2].name;
    const tcpPort = ma.stringTuples()[1][1];
    if (tcpProto !== 'tcp' || wsProto !== 'ws' && wsProto !== 'wss') throw new Error('invalid multiaddr: ' + ma.toString());
    if (!Multiaddr.isName(ma)) return 'http://' + maStrSplit[2] + ':' + maStrSplit[4];
    if (wsProto === 'ws') return 'http://' + maStrSplit[2] + (tcpPort === '80' ? '' : ':' + tcpPort);
    if (wsProto === 'wss') return 'https://' + maStrSplit[2] + (tcpPort === '443' ? '' : ':' + tcpPort);
}
function cleanMultiaddr(maStr) {
    const legacy = '/libp2p-webrtc-star';
    if (maStr.indexOf(legacy) !== -1) {
        maStr = maStr.substring(legacy.length, maStr.length);
        let ma = new Multiaddr(maStr);
        const tuppleIPFS = ma.stringTuples().filter((tupple)=>{
            return tupple[0] === 421 // ipfs code
            ;
        })[0];
        ma = ma.decapsulate('p2p');
        ma = ma.encapsulate('/p2p-webrtc-star');
        ma = ma.encapsulate(`/p2p/${tuppleIPFS[1]}`);
        maStr = ma.toString();
    }
    return maStr;
}
module.exports = {
    cleanUrlSIO,
    cleanMultiaddr
};

},{"multiaddr":"kOPrF"}],"lXsA5":[function(require,module,exports) {
'use strict';
module.exports = require('./mplex');

},{"./mplex":"liXT7"}],"liXT7":[function(require,module,exports) {
'use strict';
const pipe = require('it-pipe');
const pushable = require('it-pushable');
const log = require('debug')('libp2p:mplex');
const abortable = require('abortable-iterator');
const Coder = require('./coder');
const restrictSize = require('./restrict-size');
const { MessageTypes , MessageTypeNames  } = require('./message-types');
const createStream = require('./stream');
class Mplex {
    /**
   * @class
   * @param {object} options
   * @param {function(*)} options.onStream - Called whenever an inbound stream is created
   * @param {function(*)} options.onStreamEnd - Called whenever a stream ends
   * @param {AbortSignal} options.signal - An AbortController signal
   */ constructor(options){
        options = options || {
        };
        options = typeof options === 'function' ? {
            onStream: options
        } : options;
        this._streamId = 0;
        this._streams = {
            /**
       * @type {Map<number, *>} Stream to ids map
       */ initiators: new Map(),
            /**
       * @type {Map<number, *>} Stream to ids map
       */ receivers: new Map()
        };
        this._options = options;
        /**
     * An iterable sink
     */ this.sink = this._createSink();
        /**
     * An iterable source
     */ this.source = this._createSource();
        /**
     * @property {Function} onStream
     */ this.onStream = options.onStream;
        /**
     * @property {Function} onStreamEnd
     */ this.onStreamEnd = options.onStreamEnd;
    }
    /**
   * Returns a Map of streams and their ids
   *
   * @returns {Map<number,*>}
   */ get streams() {
        // Inbound and Outbound streams may have the same ids, so we need to make those unique
        const streams = [];
        this._streams.initiators.forEach((stream)=>{
            streams.push(stream);
        });
        this._streams.receivers.forEach((stream)=>{
            streams.push(stream);
        });
        return streams;
    }
    /**
   * Initiate a new stream with the given name. If no name is
   * provided, the id of th stream will be used.
   *
   * @param {string} [name] - If name is not a string it will be cast to one
   * @returns {Stream}
   */ newStream(name) {
        const id = this._streamId++;
        name = name == null ? id.toString() : String(name);
        const registry = this._streams.initiators;
        return this._newStream({
            id,
            name,
            type: 'initiator',
            registry
        });
    }
    /**
   * Called whenever an inbound stream is created
   *
   * @private
   * @param {*} options
   * @param {number} options.id
   * @param {string} options.name
   * @returns {*} A muxed stream
   */ _newReceiverStream({ id , name: name1  }) {
        const registry = this._streams.receivers;
        return this._newStream({
            id,
            name: name1,
            type: 'receiver',
            registry
        });
    }
    /**
   * Creates a new stream
   *
   * @private
   * @param {object} options
   * @param {number} options.id
   * @param {string} options.name
   * @param {string} options.type
   * @param {Map<number, *>} options.registry - A map of streams to their ids
   * @returns {*} A muxed stream
   */ _newStream({ id: id1 , name: name2 , type , registry  }) {
        if (registry.has(id1)) throw new Error(`${type} stream ${id1} already exists!`);
        log('new %s stream %s %s', type, id1, name2);
        const send = (msg)=>{
            if (log.enabled) log('%s stream %s %s send', type, id1, name2, {
                ...msg,
                type: MessageTypeNames[msg.type],
                data: msg.data && msg.data.slice()
            });
            return this.source.push(msg);
        };
        const onEnd = ()=>{
            log('%s stream %s %s ended', type, id1, name2);
            registry.delete(id1);
            this.onStreamEnd && this.onStreamEnd(stream);
        };
        const stream = createStream({
            id: id1,
            name: name2,
            send,
            type,
            onEnd,
            maxMsgSize: this._options.maxMsgSize
        });
        registry.set(id1, stream);
        return stream;
    }
    /**
   * Creates a sink with an abortable source. Incoming messages will
   * also have their size restricted. All messages will be varint decoded.
   *
   * @private
   * @returns {*} Returns an iterable sink
   */ _createSink() {
        return async (source1)=>{
            if (this._options.signal) source1 = abortable(source1, this._options.signal);
            try {
                await pipe(source1, Coder.decode, restrictSize(this._options.maxMsgSize), async (source)=>{
                    for await (const msgs of source)for (const msg of msgs)this._handleIncoming(msg);
                });
            } catch (err) {
                log('error in sink', err);
                return this.source.end(err) // End the source with an error
                ;
            }
            this.source.end();
        };
    }
    /**
   * Creates a source that restricts outgoing message sizes
   * and varint encodes them.
   *
   * @private
   * @returns {*} An iterable source
   */ _createSource() {
        const onEnd = (err)=>{
            const { initiators , receivers  } = this._streams;
            // Abort all the things!
            for (const s of initiators.values())s.abort(err);
            for (const s1 of receivers.values())s1.abort(err);
        };
        const source = pushable({
            onEnd,
            writev: true
        });
        return Object.assign(Coder.encode(source), {
            push: source.push,
            end: source.end,
            return: source.return
        });
    }
    /**
   * @private
   * @param {object} options
   * @param {number} options.id
   * @param {string} options.type
   * @param {Uint8Array|BufferList} options.data
   * @returns {void}
   */ _handleIncoming({ id: id2 , type: type1 , data  }) {
        if (log.enabled) log('incoming message', {
            id: id2,
            type: MessageTypeNames[type1],
            data: data.slice()
        });
        // Create a new stream?
        if (type1 === MessageTypes.NEW_STREAM && this.onStream) {
            const stream = this._newReceiverStream({
                id: id2,
                name: data.toString()
            });
            return this.onStream(stream);
        }
        const list = type1 & 1 ? this._streams.initiators : this._streams.receivers;
        const stream = list.get(id2);
        if (!stream) return log('missing stream %s', id2);
        switch(type1){
            case MessageTypes.MESSAGE_INITIATOR:
            case MessageTypes.MESSAGE_RECEIVER:
                stream.source.push(data);
                break;
            case MessageTypes.CLOSE_INITIATOR:
            case MessageTypes.CLOSE_RECEIVER:
                stream.close();
                break;
            case MessageTypes.RESET_INITIATOR:
            case MessageTypes.RESET_RECEIVER:
                stream.reset();
                break;
            default:
                log('unknown message type %s', type1);
        }
    }
}
Mplex.multicodec = '/mplex/6.7.0';
module.exports = Mplex;

},{"it-pipe":"4jukm","it-pushable":"hRi4l","debug":"lWlU4","abortable-iterator":"3n79Y","./coder":"lNBSA","./restrict-size":"8MhdM","./message-types":"bYeD2","./stream":"K86us"}],"lNBSA":[function(require,module,exports) {
'use strict';
exports.encode = require('./encode');
exports.decode = require('./decode');

},{"./encode":"g0bXk","./decode":"j5Ytn"}],"g0bXk":[function(require,module,exports) {
'use strict';
const varint = require('varint');
const BufferList = require('bl/BufferList');
const POOL_SIZE = 10240;
class Encoder {
    constructor(){
        this._pool = new Uint8Array(POOL_SIZE);
        this._poolOffset = 0;
    }
    /**
   * Encodes the given message and returns it and its header
   *
   * @param {*} msg - The message object to encode
   * @returns {Uint8Array|Uint8Array[]}
   */ write(msg1) {
        const pool = this._pool;
        let offset = this._poolOffset;
        varint.encode(msg1.id << 3 | msg1.type, pool, offset);
        offset += varint.encode.bytes;
        varint.encode(msg1.data ? msg1.data.length : 0, pool, offset);
        offset += varint.encode.bytes;
        const header = pool.subarray(this._poolOffset, offset);
        if (POOL_SIZE - offset < 100) {
            this._pool = new Uint8Array(POOL_SIZE);
            this._poolOffset = 0;
        } else this._poolOffset = offset;
        if (!msg1.data) return header;
        return [
            header,
            msg1.data
        ];
    }
}
const encoder = new Encoder();
// Encode one or more messages and yield a BufferList of encoded messages
module.exports = (source)=>(async function* encode() {
        for await (const msg of source)if (Array.isArray(msg)) yield new BufferList(msg.map((m)=>encoder.write(m)
        ));
        else yield new BufferList(encoder.write(msg));
    })()
;

},{"varint":"l84uL","bl/BufferList":"cK5XN"}],"j5Ytn":[function(require,module,exports) {
'use strict';
const varint = require('varint');
const BufferList = require('bl/BufferList');
// Decode a chunk and yield an _array_ of decoded messages
module.exports = (source)=>(async function* decode() {
        const decoder = new Decoder();
        for await (const chunk of source){
            const msgs = decoder.write(chunk);
            if (msgs.length) yield msgs;
        }
    })()
;
class Decoder {
    constructor(){
        this._buffer = new BufferList();
        // optimization to allow varint to take a BufferList (well a proxy to)
        this._bufferProxy = new Proxy({
        }, {
            get: (_, prop)=>prop[0] === 'l' ? this._buffer[prop] : this._buffer.get(parseInt(prop))
        });
        this._headerInfo = null;
    }
    /**
   * @param {Uint8Array|BufferList} chunk
   * @returns {object[]} An array of message objects
   */ write(chunk) {
        if (!chunk || !chunk.length) return [];
        this._buffer.append(chunk);
        const msgs = [];
        while(true){
            if (!this._headerInfo) try {
                this._headerInfo = this._decodeHeader(this._bufferProxy);
            } catch (_) {
                break; // We haven't received enough data yet
            }
            const { id , type , length , offset  } = this._headerInfo;
            const bufferedDataLength = this._buffer.length - offset;
            if (bufferedDataLength < length) break; // not enough data yet
            msgs.push({
                id,
                type,
                data: this._buffer.shallowSlice(offset, offset + length)
            });
            this._buffer.consume(offset + length);
            this._headerInfo = null;
        }
        return msgs;
    }
    /**
   * Attempts to decode the message header from the buffer
   *
   * @private
   * @param {Uint8Array} data
   * @returns {*} message header (id, type, offset, length)
   */ _decodeHeader(data) {
        const h = varint.decode(data);
        let offset = varint.decode.bytes;
        const length = varint.decode(data, offset);
        offset += varint.decode.bytes;
        return {
            id: h >> 3,
            type: h & 7,
            offset,
            length
        };
    }
}

},{"varint":"l84uL","bl/BufferList":"cK5XN"}],"8MhdM":[function(require,module,exports) {
'use strict';
const MAX_MSG_SIZE = 1048576 // 1MB
;
/**
 * Creates an iterable transform that restricts message sizes to
 * the given maximum size.
 *
 * @param {number} [max] - The maximum message size. Defaults to 1MB
 * @returns {*} An iterable transform.
 */ module.exports = (max)=>{
    max = max || MAX_MSG_SIZE;
    const checkSize = (msg)=>{
        if (msg.data && msg.data.length > max) throw Object.assign(new Error('message size too large!'), {
            code: 'ERR_MSG_TOO_BIG'
        });
    };
    return (source)=>{
        return (async function* restrictSize() {
            for await (const msg of source){
                if (Array.isArray(msg)) msg.forEach(checkSize);
                else checkSize(msg);
                yield msg;
            }
        })();
    };
};
module.exports.MAX_MSG_SIZE = MAX_MSG_SIZE;

},{}],"bYeD2":[function(require,module,exports) {
'use strict';
const MessageTypes = Object.freeze({
    NEW_STREAM: 0,
    MESSAGE_RECEIVER: 1,
    MESSAGE_INITIATOR: 2,
    CLOSE_RECEIVER: 3,
    CLOSE_INITIATOR: 4,
    RESET_RECEIVER: 5,
    RESET_INITIATOR: 6
});
exports.MessageTypes = MessageTypes;
exports.InitiatorMessageTypes = Object.freeze({
    NEW_STREAM: MessageTypes.NEW_STREAM,
    MESSAGE: MessageTypes.MESSAGE_INITIATOR,
    CLOSE: MessageTypes.CLOSE_INITIATOR,
    RESET: MessageTypes.RESET_INITIATOR
});
exports.ReceiverMessageTypes = Object.freeze({
    MESSAGE: MessageTypes.MESSAGE_RECEIVER,
    CLOSE: MessageTypes.CLOSE_RECEIVER,
    RESET: MessageTypes.RESET_RECEIVER
});
exports.MessageTypeNames = Object.freeze(Object.entries(MessageTypes).reduce((obj, e)=>{
    obj[e[1]] = e[0];
    return obj;
}, {
}));

},{}],"K86us":[function(require,module,exports) {
'use strict';
const abortable = require('abortable-iterator');
const AbortController = require('abort-controller');
const log = require('debug')('libp2p:mplex:stream');
const pushable = require('it-pushable');
const BufferList = require('bl/BufferList');
const errCode = require('err-code');
const { MAX_MSG_SIZE  } = require('./restrict-size');
const { InitiatorMessageTypes , ReceiverMessageTypes  } = require('./message-types');
const ERR_MPLEX_STREAM_RESET = 'ERR_MPLEX_STREAM_RESET';
const ERR_MPLEX_STREAM_ABORT = 'ERR_MPLEX_STREAM_ABORT';
/**
 * @param {object} options
 * @param {number} options.id
 * @param {string} options.name
 * @param {function(*)} options.send - Called to send data through the stream
 * @param {function(Error)} [options.onEnd] - Called whenever the stream ends
 * @param {string} [options.type] - One of ['initiator','receiver']. Defaults to 'initiator'
 * @param {number} [options.maxMsgSize] - Max size of an mplex message in bytes. Writes > size are automatically split. Defaults to 1MB
 * @returns {*} A muxed stream
 */ module.exports = ({ id , name , send , onEnd =()=>{
} , type ='initiator' , maxMsgSize =MAX_MSG_SIZE  })=>{
    const abortController = new AbortController();
    const resetController = new AbortController();
    const Types = type === 'initiator' ? InitiatorMessageTypes : ReceiverMessageTypes;
    const externalId = type === 'initiator' ? `i${id}` : `r${id}`;
    name = String(name == null ? id : name);
    let sourceEnded = false;
    let sinkEnded = false;
    let endErr;
    const onSourceEnd = (err)=>{
        if (sourceEnded) return;
        sourceEnded = true;
        log('%s stream %s source end', type, name, err);
        if (err && !endErr) endErr = err;
        if (sinkEnded) {
            stream.timeline.close = Date.now();
            onEnd(endErr);
        }
    };
    const onSinkEnd = (err)=>{
        if (sinkEnded) return;
        sinkEnded = true;
        log('%s stream %s sink end', type, name, err);
        if (err && !endErr) endErr = err;
        if (sourceEnded) {
            stream.timeline.close = Date.now();
            onEnd(endErr);
        }
    };
    const stream = {
        // Close for reading
        close: ()=>stream.source.end()
        ,
        // Close for reading and writing (local error)
        abort: (err)=>{
            log('%s stream %s abort', type, name, err);
            // End the source with the passed error
            stream.source.end(err);
            abortController.abort();
            onSinkEnd(err);
        },
        // Close immediately for reading and writing (remote error)
        reset: ()=>{
            const err = errCode(new Error('stream reset'), ERR_MPLEX_STREAM_RESET);
            resetController.abort();
            stream.source.end(err);
            onSinkEnd(err);
        },
        sink: async (source)=>{
            source = abortable(source, [
                {
                    signal: abortController.signal,
                    options: {
                        abortMessage: 'stream aborted',
                        abortCode: ERR_MPLEX_STREAM_ABORT
                    }
                },
                {
                    signal: resetController.signal,
                    options: {
                        abortMessage: 'stream reset',
                        abortCode: ERR_MPLEX_STREAM_RESET
                    }
                }
            ]);
            if (type === 'initiator') send({
                id,
                type: Types.NEW_STREAM,
                data: name
            });
            try {
                for await (let data of source)while(data.length){
                    if (data.length <= maxMsgSize) {
                        send({
                            id,
                            type: Types.MESSAGE,
                            data
                        });
                        break;
                    }
                    data = BufferList.isBufferList(data) ? data : new BufferList(data);
                    send({
                        id,
                        type: Types.MESSAGE,
                        data: data.shallowSlice(0, maxMsgSize)
                    });
                    data.consume(maxMsgSize);
                }
            } catch (err) {
                // Send no more data if this stream was remotely reset
                if (err.code === ERR_MPLEX_STREAM_RESET) log('%s stream %s reset', type, name);
                else {
                    log('%s stream %s error', type, name, err);
                    send({
                        id,
                        type: Types.RESET
                    });
                }
                stream.source.end(err);
                return onSinkEnd(err);
            }
            send({
                id,
                type: Types.CLOSE
            });
            onSinkEnd();
        },
        source: pushable(onSourceEnd),
        timeline: {
            open: Date.now(),
            close: null
        },
        id: externalId
    };
    return stream;
};

},{"abortable-iterator":"3n79Y","abort-controller":"hVuZx","debug":"lWlU4","it-pushable":"hRi4l","bl/BufferList":"cK5XN","err-code":"eQvyh","./restrict-size":"8MhdM","./message-types":"bYeD2"}],"1tH8u":[function(require,module,exports) {
"use strict";
var __createBinding = this && this.__createBinding || (Object.create ? function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    Object.defineProperty(o, k2, {
        enumerable: true,
        get: function() {
            return m[k];
        }
    });
} : function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
});
var __exportStar = this && this.__exportStar || function(m, exports) {
    for(var p in m)if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.NOISE = void 0;
const noise_1 = require("./noise");
__exportStar(require("./noise"), exports);
/**
 * Default configuration, it will generate new noise static key and enable noise pipes (IK handshake).
 */ exports.NOISE = new noise_1.Noise();

},{"./noise":"3o4Gv"}],"3o4Gv":[function(require,module,exports) {
"use strict";
var __createBinding = this && this.__createBinding || (Object.create ? function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    Object.defineProperty(o, k2, {
        enumerable: true,
        get: function() {
            return m[k];
        }
    });
} : function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
});
var __setModuleDefault = this && this.__setModuleDefault || (Object.create ? function(o, v) {
    Object.defineProperty(o, "default", {
        enumerable: true,
        value: v
    });
} : function(o, v) {
    o["default"] = v;
});
var __importStar = this && this.__importStar || function(mod) {
    if (mod && mod.__esModule) return mod;
    var result = {
    };
    if (mod != null) {
        for(var k in mod)if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    }
    __setModuleDefault(result, mod);
    return result;
};
var __importDefault = this && this.__importDefault || function(mod) {
    return mod && mod.__esModule ? mod : {
        "default": mod
    };
};
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.Noise = void 0;
const x25519 = __importStar(require("@stablelib/x25519"));
const buffer_1 = require("buffer");
const it_pb_rpc_1 = __importDefault(require("it-pb-rpc"));
const duplex_1 = __importDefault(require("it-pair/duplex"));
const it_buffer_1 = __importDefault(require("it-buffer"));
const it_pipe_1 = __importDefault(require("it-pipe"));
const it_length_prefixed_1 = require("it-length-prefixed");
const handshake_xx_1 = require("./handshake-xx");
const handshake_ik_1 = require("./handshake-ik");
const handshake_xx_fallback_1 = require("./handshake-xx-fallback");
const utils_1 = require("./utils");
const encoder_1 = require("./encoder");
const crypto_1 = require("./crypto");
const keycache_1 = require("./keycache");
const logger_1 = require("./logger");
const constants_1 = require("./constants");
class Noise {
    /**
     *
     * @param {bytes} staticNoiseKey - x25519 private key, reuse for faster handshakes
     * @param {bytes} earlyData
     */ constructor(staticNoiseKey, earlyData){
        this.protocol = '/noise';
        this.prologue = buffer_1.Buffer.alloc(0);
        this.earlyData = earlyData !== null && earlyData !== void 0 ? earlyData : buffer_1.Buffer.alloc(0);
        // disabled until properly specked
        this.useNoisePipes = false;
        if (staticNoiseKey) {
            // accepts x25519 private key of length 32
            const keyPair = x25519.generateKeyPairFromSeed(staticNoiseKey);
            this.staticKeys = {
                privateKey: buffer_1.Buffer.from(keyPair.secretKey.buffer, keyPair.secretKey.byteOffset, keyPair.secretKey.length),
                publicKey: buffer_1.Buffer.from(keyPair.publicKey.buffer, keyPair.publicKey.byteOffset, keyPair.publicKey.length)
            };
        } else this.staticKeys = utils_1.generateKeypair();
    }
    /**
     * Encrypt outgoing data to the remote party (handshake as initiator)
     *
     * @param {PeerId} localPeer - PeerId of the receiving peer
     * @param {any} connection - streaming iterable duplex that will be encrypted
     * @param {PeerId} remotePeer - PeerId of the remote peer. Used to validate the integrity of the remote peer.
     * @returns {Promise<SecureOutbound>}
     */ async secureOutbound(localPeer, connection, remotePeer) {
        const wrappedConnection = it_pb_rpc_1.default(connection, {
            lengthEncoder: encoder_1.uint16BEEncode,
            lengthDecoder: encoder_1.uint16BEDecode,
            maxDataLength: constants_1.NOISE_MSG_MAX_LENGTH_BYTES
        });
        const handshake = await this.performHandshake({
            connection: wrappedConnection,
            isInitiator: true,
            localPeer,
            remotePeer
        });
        const conn = await this.createSecureConnection(wrappedConnection, handshake);
        return {
            conn,
            remoteEarlyData: handshake.remoteEarlyData,
            remotePeer: handshake.remotePeer
        };
    }
    /**
     * Decrypt incoming data (handshake as responder).
     *
     * @param {PeerId} localPeer - PeerId of the receiving peer.
     * @param {any} connection - streaming iterable duplex that will be encryption.
     * @param {PeerId} remotePeer - optional PeerId of the initiating peer, if known. This may only exist during transport upgrades.
     * @returns {Promise<SecureOutbound>}
     */ async secureInbound(localPeer1, connection1, remotePeer1) {
        const wrappedConnection = it_pb_rpc_1.default(connection1, {
            lengthEncoder: encoder_1.uint16BEEncode,
            lengthDecoder: encoder_1.uint16BEDecode,
            maxDataLength: constants_1.NOISE_MSG_MAX_LENGTH_BYTES
        });
        const handshake = await this.performHandshake({
            connection: wrappedConnection,
            isInitiator: false,
            localPeer: localPeer1,
            remotePeer: remotePeer1
        });
        const conn = await this.createSecureConnection(wrappedConnection, handshake);
        return {
            conn,
            remoteEarlyData: handshake.remoteEarlyData,
            remotePeer: handshake.remotePeer
        };
    }
    /**
     * If Noise pipes supported, tries IK handshake first with XX as fallback if it fails.
     * If noise pipes disabled or remote peer static key is unknown, use XX.
     *
     * @param {HandshakeParams} params
     */ async performHandshake(params) {
        var _a;
        const payload = await utils_1.getPayload(params.localPeer, this.staticKeys.publicKey, this.earlyData);
        let tryIK = this.useNoisePipes;
        if (params.isInitiator && keycache_1.KeyCache.load(params.remotePeer) === null) // if we are initiator and remote static key is unknown, don't try IK
        tryIK = false;
        // Try IK if acting as responder or initiator that has remote's static key.
        if (tryIK) {
            // Try IK first
            const { remotePeer , connection , isInitiator  } = params;
            const ikHandshake = new handshake_ik_1.IKHandshake(isInitiator, payload, this.prologue, this.staticKeys, connection, // safe to cast as we did checks
            (_a = keycache_1.KeyCache.load(params.remotePeer)) !== null && _a !== void 0 ? _a : buffer_1.Buffer.alloc(32), remotePeer);
            try {
                return await this.performIKHandshake(ikHandshake);
            } catch (e) {
                // IK failed, go to XX fallback
                let ephemeralKeys;
                if (params.isInitiator) ephemeralKeys = ikHandshake.getLocalEphemeralKeys();
                return await this.performXXFallbackHandshake(params, payload, e.initialMsg, ephemeralKeys);
            }
        } else // run XX handshake
        return await this.performXXHandshake(params, payload);
    }
    async performXXFallbackHandshake(params1, payload, initialMsg, ephemeralKeys) {
        const { isInitiator , remotePeer , connection  } = params1;
        const handshake = new handshake_xx_fallback_1.XXFallbackHandshake(isInitiator, payload, this.prologue, this.staticKeys, connection, initialMsg, remotePeer, ephemeralKeys);
        try {
            await handshake.propose();
            await handshake.exchange();
            await handshake.finish();
        } catch (e) {
            logger_1.logger(e);
            const err = e;
            throw new Error(`Error occurred during XX Fallback handshake: ${err.message}`);
        }
        return handshake;
    }
    async performXXHandshake(params2, payload1) {
        const { isInitiator , remotePeer , connection  } = params2;
        const handshake = new handshake_xx_1.XXHandshake(isInitiator, payload1, this.prologue, this.staticKeys, connection, remotePeer);
        try {
            await handshake.propose();
            await handshake.exchange();
            await handshake.finish();
            if (this.useNoisePipes && handshake.remotePeer) keycache_1.KeyCache.store(handshake.remotePeer, handshake.getRemoteStaticKey());
        } catch (e) {
            const err = e;
            throw new Error(`Error occurred during XX handshake: ${err.message}`);
        }
        return handshake;
    }
    async performIKHandshake(handshake) {
        await handshake.stage0();
        await handshake.stage1();
        return handshake;
    }
    async createSecureConnection(connection2, handshake1) {
        // Create encryption box/unbox wrapper
        const [secure, user] = duplex_1.default();
        const network = connection2.unwrap();
        await it_pipe_1.default(secure, it_buffer_1.default, crypto_1.encryptStream(handshake1), it_length_prefixed_1.encode({
            lengthEncoder: encoder_1.uint16BEEncode
        }), network, it_length_prefixed_1.decode({
            lengthDecoder: encoder_1.uint16BEDecode
        }), it_buffer_1.default, crypto_1.decryptStream(handshake1), secure // pipe to the wrapper
        );
        return user;
    }
}
exports.Noise = Noise;

},{"@stablelib/x25519":"f6HJy","buffer":"eKea5","it-pb-rpc":"64xeB","it-pair/duplex":"iMkvZ","it-buffer":"cfN57","it-pipe":"4jukm","it-length-prefixed":"2cvC1","./handshake-xx":"40XvU","./handshake-ik":"2Xb7e","./handshake-xx-fallback":"lKp03","./utils":"3C9kU","./encoder":"fw0Lz","./crypto":"7ejgP","./keycache":"6mUAQ","./logger":"hHMfO","./constants":"3FbHN"}],"f6HJy":[function(require,module,exports) {
"use strict";
// Copyright (C) 2016 Dmitry Chestnykh
// MIT License. See LICENSE file for details.
Object.defineProperty(exports, "__esModule", {
    value: true
});
/**
 * Package x25519 implements X25519 key agreement.
 */ var random_1 = require("@stablelib/random");
var wipe_1 = require("@stablelib/wipe");
exports.PUBLIC_KEY_LENGTH = 32;
exports.SECRET_KEY_LENGTH = 32;
exports.SHARED_KEY_LENGTH = 32;
// Returns new zero-filled 16-element GF (Float64Array).
// If passed an array of numbers, prefills the returned
// array with them.
//
// We use Float64Array, because we need 48-bit numbers
// for this implementation.
function gf(init) {
    var r = new Float64Array(16);
    if (init) for(var i = 0; i < init.length; i++)r[i] = init[i];
    return r;
}
// Base point.
var _9 = new Uint8Array(32);
_9[0] = 9;
var _121665 = gf([
    56129,
    1
]);
function car25519(o) {
    var c = 1;
    for(var i = 0; i < 16; i++){
        var v = o[i] + c + 65535;
        c = Math.floor(v / 65536);
        o[i] = v - c * 65536;
    }
    o[0] += c - 1 + 37 * (c - 1);
}
function sel25519(p, q, b) {
    var c = ~(b - 1);
    for(var i = 0; i < 16; i++){
        var t = c & (p[i] ^ q[i]);
        p[i] ^= t;
        q[i] ^= t;
    }
}
function pack25519(o, n) {
    var m = gf();
    var t = gf();
    for(var i = 0; i < 16; i++)t[i] = n[i];
    car25519(t);
    car25519(t);
    car25519(t);
    for(var j = 0; j < 2; j++){
        m[0] = t[0] - 65517;
        for(var i = 1; i < 15; i++){
            m[i] = t[i] - 65535 - (m[i - 1] >> 16 & 1);
            m[i - 1] &= 65535;
        }
        m[15] = t[15] - 32767 - (m[14] >> 16 & 1);
        var b = m[15] >> 16 & 1;
        m[14] &= 65535;
        sel25519(t, m, 1 - b);
    }
    for(var i = 0; i < 16; i++){
        o[2 * i] = t[i] & 255;
        o[2 * i + 1] = t[i] >> 8;
    }
}
function unpack25519(o, n) {
    for(var i = 0; i < 16; i++)o[i] = n[2 * i] + (n[2 * i + 1] << 8);
    o[15] &= 32767;
}
function add(o, a, b) {
    for(var i = 0; i < 16; i++)o[i] = a[i] + b[i];
}
function sub(o, a, b) {
    for(var i = 0; i < 16; i++)o[i] = a[i] - b[i];
}
function mul(o, a, b) {
    var v, c, t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0, t8 = 0, t9 = 0, t10 = 0, t11 = 0, t12 = 0, t13 = 0, t14 = 0, t15 = 0, t16 = 0, t17 = 0, t18 = 0, t19 = 0, t20 = 0, t21 = 0, t22 = 0, t23 = 0, t24 = 0, t25 = 0, t26 = 0, t27 = 0, t28 = 0, t29 = 0, t30 = 0, b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3], b4 = b[4], b5 = b[5], b6 = b[6], b7 = b[7], b8 = b[8], b9 = b[9], b10 = b[10], b11 = b[11], b12 = b[12], b13 = b[13], b14 = b[14], b15 = b[15];
    v = a[0];
    t0 += v * b0;
    t1 += v * b1;
    t2 += v * b2;
    t3 += v * b3;
    t4 += v * b4;
    t5 += v * b5;
    t6 += v * b6;
    t7 += v * b7;
    t8 += v * b8;
    t9 += v * b9;
    t10 += v * b10;
    t11 += v * b11;
    t12 += v * b12;
    t13 += v * b13;
    t14 += v * b14;
    t15 += v * b15;
    v = a[1];
    t1 += v * b0;
    t2 += v * b1;
    t3 += v * b2;
    t4 += v * b3;
    t5 += v * b4;
    t6 += v * b5;
    t7 += v * b6;
    t8 += v * b7;
    t9 += v * b8;
    t10 += v * b9;
    t11 += v * b10;
    t12 += v * b11;
    t13 += v * b12;
    t14 += v * b13;
    t15 += v * b14;
    t16 += v * b15;
    v = a[2];
    t2 += v * b0;
    t3 += v * b1;
    t4 += v * b2;
    t5 += v * b3;
    t6 += v * b4;
    t7 += v * b5;
    t8 += v * b6;
    t9 += v * b7;
    t10 += v * b8;
    t11 += v * b9;
    t12 += v * b10;
    t13 += v * b11;
    t14 += v * b12;
    t15 += v * b13;
    t16 += v * b14;
    t17 += v * b15;
    v = a[3];
    t3 += v * b0;
    t4 += v * b1;
    t5 += v * b2;
    t6 += v * b3;
    t7 += v * b4;
    t8 += v * b5;
    t9 += v * b6;
    t10 += v * b7;
    t11 += v * b8;
    t12 += v * b9;
    t13 += v * b10;
    t14 += v * b11;
    t15 += v * b12;
    t16 += v * b13;
    t17 += v * b14;
    t18 += v * b15;
    v = a[4];
    t4 += v * b0;
    t5 += v * b1;
    t6 += v * b2;
    t7 += v * b3;
    t8 += v * b4;
    t9 += v * b5;
    t10 += v * b6;
    t11 += v * b7;
    t12 += v * b8;
    t13 += v * b9;
    t14 += v * b10;
    t15 += v * b11;
    t16 += v * b12;
    t17 += v * b13;
    t18 += v * b14;
    t19 += v * b15;
    v = a[5];
    t5 += v * b0;
    t6 += v * b1;
    t7 += v * b2;
    t8 += v * b3;
    t9 += v * b4;
    t10 += v * b5;
    t11 += v * b6;
    t12 += v * b7;
    t13 += v * b8;
    t14 += v * b9;
    t15 += v * b10;
    t16 += v * b11;
    t17 += v * b12;
    t18 += v * b13;
    t19 += v * b14;
    t20 += v * b15;
    v = a[6];
    t6 += v * b0;
    t7 += v * b1;
    t8 += v * b2;
    t9 += v * b3;
    t10 += v * b4;
    t11 += v * b5;
    t12 += v * b6;
    t13 += v * b7;
    t14 += v * b8;
    t15 += v * b9;
    t16 += v * b10;
    t17 += v * b11;
    t18 += v * b12;
    t19 += v * b13;
    t20 += v * b14;
    t21 += v * b15;
    v = a[7];
    t7 += v * b0;
    t8 += v * b1;
    t9 += v * b2;
    t10 += v * b3;
    t11 += v * b4;
    t12 += v * b5;
    t13 += v * b6;
    t14 += v * b7;
    t15 += v * b8;
    t16 += v * b9;
    t17 += v * b10;
    t18 += v * b11;
    t19 += v * b12;
    t20 += v * b13;
    t21 += v * b14;
    t22 += v * b15;
    v = a[8];
    t8 += v * b0;
    t9 += v * b1;
    t10 += v * b2;
    t11 += v * b3;
    t12 += v * b4;
    t13 += v * b5;
    t14 += v * b6;
    t15 += v * b7;
    t16 += v * b8;
    t17 += v * b9;
    t18 += v * b10;
    t19 += v * b11;
    t20 += v * b12;
    t21 += v * b13;
    t22 += v * b14;
    t23 += v * b15;
    v = a[9];
    t9 += v * b0;
    t10 += v * b1;
    t11 += v * b2;
    t12 += v * b3;
    t13 += v * b4;
    t14 += v * b5;
    t15 += v * b6;
    t16 += v * b7;
    t17 += v * b8;
    t18 += v * b9;
    t19 += v * b10;
    t20 += v * b11;
    t21 += v * b12;
    t22 += v * b13;
    t23 += v * b14;
    t24 += v * b15;
    v = a[10];
    t10 += v * b0;
    t11 += v * b1;
    t12 += v * b2;
    t13 += v * b3;
    t14 += v * b4;
    t15 += v * b5;
    t16 += v * b6;
    t17 += v * b7;
    t18 += v * b8;
    t19 += v * b9;
    t20 += v * b10;
    t21 += v * b11;
    t22 += v * b12;
    t23 += v * b13;
    t24 += v * b14;
    t25 += v * b15;
    v = a[11];
    t11 += v * b0;
    t12 += v * b1;
    t13 += v * b2;
    t14 += v * b3;
    t15 += v * b4;
    t16 += v * b5;
    t17 += v * b6;
    t18 += v * b7;
    t19 += v * b8;
    t20 += v * b9;
    t21 += v * b10;
    t22 += v * b11;
    t23 += v * b12;
    t24 += v * b13;
    t25 += v * b14;
    t26 += v * b15;
    v = a[12];
    t12 += v * b0;
    t13 += v * b1;
    t14 += v * b2;
    t15 += v * b3;
    t16 += v * b4;
    t17 += v * b5;
    t18 += v * b6;
    t19 += v * b7;
    t20 += v * b8;
    t21 += v * b9;
    t22 += v * b10;
    t23 += v * b11;
    t24 += v * b12;
    t25 += v * b13;
    t26 += v * b14;
    t27 += v * b15;
    v = a[13];
    t13 += v * b0;
    t14 += v * b1;
    t15 += v * b2;
    t16 += v * b3;
    t17 += v * b4;
    t18 += v * b5;
    t19 += v * b6;
    t20 += v * b7;
    t21 += v * b8;
    t22 += v * b9;
    t23 += v * b10;
    t24 += v * b11;
    t25 += v * b12;
    t26 += v * b13;
    t27 += v * b14;
    t28 += v * b15;
    v = a[14];
    t14 += v * b0;
    t15 += v * b1;
    t16 += v * b2;
    t17 += v * b3;
    t18 += v * b4;
    t19 += v * b5;
    t20 += v * b6;
    t21 += v * b7;
    t22 += v * b8;
    t23 += v * b9;
    t24 += v * b10;
    t25 += v * b11;
    t26 += v * b12;
    t27 += v * b13;
    t28 += v * b14;
    t29 += v * b15;
    v = a[15];
    t15 += v * b0;
    t16 += v * b1;
    t17 += v * b2;
    t18 += v * b3;
    t19 += v * b4;
    t20 += v * b5;
    t21 += v * b6;
    t22 += v * b7;
    t23 += v * b8;
    t24 += v * b9;
    t25 += v * b10;
    t26 += v * b11;
    t27 += v * b12;
    t28 += v * b13;
    t29 += v * b14;
    t30 += v * b15;
    t0 += 38 * t16;
    t1 += 38 * t17;
    t2 += 38 * t18;
    t3 += 38 * t19;
    t4 += 38 * t20;
    t5 += 38 * t21;
    t6 += 38 * t22;
    t7 += 38 * t23;
    t8 += 38 * t24;
    t9 += 38 * t25;
    t10 += 38 * t26;
    t11 += 38 * t27;
    t12 += 38 * t28;
    t13 += 38 * t29;
    t14 += 38 * t30;
    // t15 left as is
    // first car
    c = 1;
    v = t0 + c + 65535;
    c = Math.floor(v / 65536);
    t0 = v - c * 65536;
    v = t1 + c + 65535;
    c = Math.floor(v / 65536);
    t1 = v - c * 65536;
    v = t2 + c + 65535;
    c = Math.floor(v / 65536);
    t2 = v - c * 65536;
    v = t3 + c + 65535;
    c = Math.floor(v / 65536);
    t3 = v - c * 65536;
    v = t4 + c + 65535;
    c = Math.floor(v / 65536);
    t4 = v - c * 65536;
    v = t5 + c + 65535;
    c = Math.floor(v / 65536);
    t5 = v - c * 65536;
    v = t6 + c + 65535;
    c = Math.floor(v / 65536);
    t6 = v - c * 65536;
    v = t7 + c + 65535;
    c = Math.floor(v / 65536);
    t7 = v - c * 65536;
    v = t8 + c + 65535;
    c = Math.floor(v / 65536);
    t8 = v - c * 65536;
    v = t9 + c + 65535;
    c = Math.floor(v / 65536);
    t9 = v - c * 65536;
    v = t10 + c + 65535;
    c = Math.floor(v / 65536);
    t10 = v - c * 65536;
    v = t11 + c + 65535;
    c = Math.floor(v / 65536);
    t11 = v - c * 65536;
    v = t12 + c + 65535;
    c = Math.floor(v / 65536);
    t12 = v - c * 65536;
    v = t13 + c + 65535;
    c = Math.floor(v / 65536);
    t13 = v - c * 65536;
    v = t14 + c + 65535;
    c = Math.floor(v / 65536);
    t14 = v - c * 65536;
    v = t15 + c + 65535;
    c = Math.floor(v / 65536);
    t15 = v - c * 65536;
    t0 += c - 1 + 37 * (c - 1);
    // second car
    c = 1;
    v = t0 + c + 65535;
    c = Math.floor(v / 65536);
    t0 = v - c * 65536;
    v = t1 + c + 65535;
    c = Math.floor(v / 65536);
    t1 = v - c * 65536;
    v = t2 + c + 65535;
    c = Math.floor(v / 65536);
    t2 = v - c * 65536;
    v = t3 + c + 65535;
    c = Math.floor(v / 65536);
    t3 = v - c * 65536;
    v = t4 + c + 65535;
    c = Math.floor(v / 65536);
    t4 = v - c * 65536;
    v = t5 + c + 65535;
    c = Math.floor(v / 65536);
    t5 = v - c * 65536;
    v = t6 + c + 65535;
    c = Math.floor(v / 65536);
    t6 = v - c * 65536;
    v = t7 + c + 65535;
    c = Math.floor(v / 65536);
    t7 = v - c * 65536;
    v = t8 + c + 65535;
    c = Math.floor(v / 65536);
    t8 = v - c * 65536;
    v = t9 + c + 65535;
    c = Math.floor(v / 65536);
    t9 = v - c * 65536;
    v = t10 + c + 65535;
    c = Math.floor(v / 65536);
    t10 = v - c * 65536;
    v = t11 + c + 65535;
    c = Math.floor(v / 65536);
    t11 = v - c * 65536;
    v = t12 + c + 65535;
    c = Math.floor(v / 65536);
    t12 = v - c * 65536;
    v = t13 + c + 65535;
    c = Math.floor(v / 65536);
    t13 = v - c * 65536;
    v = t14 + c + 65535;
    c = Math.floor(v / 65536);
    t14 = v - c * 65536;
    v = t15 + c + 65535;
    c = Math.floor(v / 65536);
    t15 = v - c * 65536;
    t0 += c - 1 + 37 * (c - 1);
    o[0] = t0;
    o[1] = t1;
    o[2] = t2;
    o[3] = t3;
    o[4] = t4;
    o[5] = t5;
    o[6] = t6;
    o[7] = t7;
    o[8] = t8;
    o[9] = t9;
    o[10] = t10;
    o[11] = t11;
    o[12] = t12;
    o[13] = t13;
    o[14] = t14;
    o[15] = t15;
}
function square(o, a) {
    mul(o, a, a);
}
function inv25519(o, inp) {
    var c = gf();
    for(var i = 0; i < 16; i++)c[i] = inp[i];
    for(var i = 253; i >= 0; i--){
        square(c, c);
        if (i !== 2 && i !== 4) mul(c, c, inp);
    }
    for(var i = 0; i < 16; i++)o[i] = c[i];
}
function scalarMult(n, p) {
    var z = new Uint8Array(32);
    var x = new Float64Array(80);
    var a = gf(), b = gf(), c = gf(), d = gf(), e = gf(), f = gf();
    for(var i = 0; i < 31; i++)z[i] = n[i];
    z[31] = n[31] & 127 | 64;
    z[0] &= 248;
    unpack25519(x, p);
    for(var i = 0; i < 16; i++)b[i] = x[i];
    a[0] = d[0] = 1;
    for(var i = 254; i >= 0; --i){
        var r = z[i >>> 3] >>> (i & 7) & 1;
        sel25519(a, b, r);
        sel25519(c, d, r);
        add(e, a, c);
        sub(a, a, c);
        add(c, b, d);
        sub(b, b, d);
        square(d, e);
        square(f, a);
        mul(a, c, a);
        mul(c, b, e);
        add(e, a, c);
        sub(a, a, c);
        square(b, a);
        sub(c, d, f);
        mul(a, c, _121665);
        add(a, a, d);
        mul(c, c, a);
        mul(a, d, f);
        mul(d, b, x);
        square(b, e);
        sel25519(a, b, r);
        sel25519(c, d, r);
    }
    for(var i = 0; i < 16; i++){
        x[i + 16] = a[i];
        x[i + 32] = c[i];
        x[i + 48] = b[i];
        x[i + 64] = d[i];
    }
    var x32 = x.subarray(32);
    var x16 = x.subarray(16);
    inv25519(x32, x32);
    mul(x16, x16, x32);
    var q = new Uint8Array(32);
    pack25519(q, x16);
    return q;
}
exports.scalarMult = scalarMult;
function scalarMultBase(n) {
    return scalarMult(n, _9);
}
exports.scalarMultBase = scalarMultBase;
function generateKeyPairFromSeed(seed) {
    if (seed.length !== exports.SECRET_KEY_LENGTH) throw new Error("x25519: seed must be " + exports.SECRET_KEY_LENGTH + " bytes");
    var secretKey = new Uint8Array(seed);
    var publicKey = scalarMultBase(secretKey);
    return {
        publicKey: publicKey,
        secretKey: secretKey
    };
}
exports.generateKeyPairFromSeed = generateKeyPairFromSeed;
function generateKeyPair(prng) {
    var seed = random_1.randomBytes(32, prng);
    var result = generateKeyPairFromSeed(seed);
    wipe_1.wipe(seed);
    return result;
}
exports.generateKeyPair = generateKeyPair;
/**
 * Returns a shared key between our secret key and a peer's public key.
 *
 * Throws an error if the given keys are of wrong length.
 *
 * If rejectZero is true throws if the calculated shared key is all-zero.
 * From RFC 7748:
 *
 * > Protocol designers using Diffie-Hellman over the curves defined in
 * > this document must not assume "contributory behavior".  Specially,
 * > contributory behavior means that both parties' private keys
 * > contribute to the resulting shared key.  Since curve25519 and
 * > curve448 have cofactors of 8 and 4 (respectively), an input point of
 * > small order will eliminate any contribution from the other party's
 * > private key.  This situation can be detected by checking for the all-
 * > zero output, which implementations MAY do, as specified in Section 6.
 * > However, a large number of existing implementations do not do this.
 *
 * IMPORTANT: the returned key is a raw result of scalar multiplication.
 * To use it as a key material, hash it with a cryptographic hash function.
 */ function sharedKey(mySecretKey, theirPublicKey, rejectZero) {
    if (rejectZero === void 0) rejectZero = false;
    if (mySecretKey.length !== exports.PUBLIC_KEY_LENGTH) throw new Error("X25519: incorrect secret key length");
    if (theirPublicKey.length !== exports.PUBLIC_KEY_LENGTH) throw new Error("X25519: incorrect public key length");
    var result = scalarMult(mySecretKey, theirPublicKey);
    if (rejectZero) {
        var zeros = 0;
        for(var i = 0; i < result.length; i++)zeros |= result[i];
        if (zeros === 0) throw new Error("X25519: invalid shared key");
    }
    return result;
}
exports.sharedKey = sharedKey;

},{"@stablelib/random":"93tiL","@stablelib/wipe":"eWLFw"}],"93tiL":[function(require,module,exports) {
"use strict";
// Copyright (C) 2016 Dmitry Chestnykh
// MIT License. See LICENSE file for details.
Object.defineProperty(exports, "__esModule", {
    value: true
});
var system_1 = require("./source/system");
var binary_1 = require("@stablelib/binary");
var wipe_1 = require("@stablelib/wipe");
exports.defaultRandomSource = new system_1.SystemRandomSource();
function randomBytes(length, prng) {
    if (prng === void 0) prng = exports.defaultRandomSource;
    return prng.randomBytes(length);
}
exports.randomBytes = randomBytes;
/**
 * Returns a uniformly random unsigned 32-bit integer.
 */ function randomUint32(prng) {
    if (prng === void 0) prng = exports.defaultRandomSource;
    // Generate 4-byte random buffer.
    var buf = randomBytes(4, prng);
    // Convert bytes from buffer into a 32-bit integer.
    // It's not important which byte order to use, since
    // the result is random.
    var result = binary_1.readUint32LE(buf);
    // Clean the buffer.
    wipe_1.wipe(buf);
    return result;
}
exports.randomUint32 = randomUint32;
/** 62 alphanumeric characters for default charset of randomString() */ var ALPHANUMERIC = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
/**
 * Returns a uniform random string of the given length
 * with characters from the given charset.
 *
 * Charset must not have more than 256 characters.
 *
 * Default charset generates case-sensitive alphanumeric
 * strings (0-9, A-Z, a-z).
 */ function randomString(length, charset, prng) {
    if (charset === void 0) charset = ALPHANUMERIC;
    if (prng === void 0) prng = exports.defaultRandomSource;
    if (charset.length < 2) throw new Error("randomString charset is too short");
    if (charset.length > 256) throw new Error("randomString charset is too long");
    var out = '';
    var charsLen = charset.length;
    var maxByte = 256 - 256 % charsLen;
    while(length > 0){
        var buf = randomBytes(Math.ceil(length * 256 / maxByte), prng);
        for(var i = 0; i < buf.length && length > 0; i++){
            var randomByte = buf[i];
            if (randomByte < maxByte) {
                out += charset.charAt(randomByte % charsLen);
                length--;
            }
        }
        wipe_1.wipe(buf);
    }
    return out;
}
exports.randomString = randomString;
/**
 * Returns uniform random string containing at least the given
 * number of bits of entropy.
 *
 * For example, randomStringForEntropy(128) will return a 22-character
 * alphanumeric string, while randomStringForEntropy(128, "0123456789")
 * will return a 39-character numeric string, both will contain at
 * least 128 bits of entropy.
 *
 * Default charset generates case-sensitive alphanumeric
 * strings (0-9, A-Z, a-z).
 */ function randomStringForEntropy(bits, charset, prng) {
    if (charset === void 0) charset = ALPHANUMERIC;
    if (prng === void 0) prng = exports.defaultRandomSource;
    var length = Math.ceil(bits / (Math.log(charset.length) / Math.LN2));
    return randomString(length, charset, prng);
}
exports.randomStringForEntropy = randomStringForEntropy;

},{"./source/system":"g1XSC","@stablelib/binary":"jpDs0","@stablelib/wipe":"eWLFw"}],"g1XSC":[function(require,module,exports) {
"use strict";
// Copyright (C) 2016 Dmitry Chestnykh
// MIT License. See LICENSE file for details.
Object.defineProperty(exports, "__esModule", {
    value: true
});
var browser_1 = require("./browser");
var node_1 = require("./node");
var SystemRandomSource1 = function() {
    function SystemRandomSource() {
        this.isAvailable = false;
        this.name = "";
        // Try browser.
        this._source = new browser_1.BrowserRandomSource();
        if (this._source.isAvailable) {
            this.isAvailable = true;
            this.name = "Browser";
            return;
        }
        // If no browser source, try Node.
        this._source = new node_1.NodeRandomSource();
        if (this._source.isAvailable) {
            this.isAvailable = true;
            this.name = "Node";
            return;
        }
    // No sources, we're out of options.
    }
    SystemRandomSource.prototype.randomBytes = function(length) {
        if (!this.isAvailable) throw new Error("System random byte generator is not available.");
        return this._source.randomBytes(length);
    };
    return SystemRandomSource;
}();
exports.SystemRandomSource = SystemRandomSource1;

},{"./browser":"gMyk3","./node":"kuQdQ"}],"gMyk3":[function(require,module,exports) {
"use strict";
// Copyright (C) 2016 Dmitry Chestnykh
// MIT License. See LICENSE file for details.
Object.defineProperty(exports, "__esModule", {
    value: true
});
var QUOTA = 65536;
var BrowserRandomSource1 = function() {
    function BrowserRandomSource() {
        this.isAvailable = false;
        this.isInstantiated = false;
        var browserCrypto = typeof self !== 'undefined' ? self.crypto || self.msCrypto : null;
        if (browserCrypto && browserCrypto.getRandomValues) {
            this._crypto = browserCrypto;
            this.isAvailable = true;
            this.isInstantiated = true;
        }
    }
    BrowserRandomSource.prototype.randomBytes = function(length) {
        if (!this.isAvailable || !this._crypto) throw new Error("Browser random byte generator is not available.");
        var out = new Uint8Array(length);
        for(var i = 0; i < out.length; i += QUOTA)this._crypto.getRandomValues(out.subarray(i, i + Math.min(out.length - i, QUOTA)));
        return out;
    };
    return BrowserRandomSource;
}();
exports.BrowserRandomSource = BrowserRandomSource1;

},{}],"kuQdQ":[function(require,module,exports) {
"use strict";
// Copyright (C) 2016 Dmitry Chestnykh
// MIT License. See LICENSE file for details.
Object.defineProperty(exports, "__esModule", {
    value: true
});
var wipe_1 = require("@stablelib/wipe");
var NodeRandomSource1 = function() {
    function NodeRandomSource() {
        this.isAvailable = false;
        this.isInstantiated = false;
        if (typeof require !== "undefined") {
            var nodeCrypto = require("crypto");
            if (nodeCrypto && nodeCrypto.randomBytes) {
                this._crypto = nodeCrypto;
                this.isAvailable = true;
                this.isInstantiated = true;
            }
        }
    }
    NodeRandomSource.prototype.randomBytes = function(length) {
        if (!this.isAvailable || !this._crypto) throw new Error("Node.js random byte generator is not available.");
        // Get random bytes (result is Buffer).
        var buffer = this._crypto.randomBytes(length);
        // Make sure we got the length that we requested.
        if (buffer.length !== length) throw new Error("NodeRandomSource: got fewer bytes than requested");
        // Allocate output array.
        var out = new Uint8Array(length);
        // Copy bytes from buffer to output.
        for(var i = 0; i < out.length; i++)out[i] = buffer[i];
        // Cleanup.
        wipe_1.wipe(buffer);
        return out;
    };
    return NodeRandomSource;
}();
exports.NodeRandomSource = NodeRandomSource1;

},{"@stablelib/wipe":"eWLFw","crypto":"joWnX"}],"eWLFw":[function(require,module,exports) {
"use strict";
// Copyright (C) 2016 Dmitry Chestnykh
// MIT License. See LICENSE file for details.
Object.defineProperty(exports, "__esModule", {
    value: true
});
/**
 * Sets all values in the given array to zero and returns it.
 *
 * The fact that it sets bytes to zero can be relied on.
 *
 * There is no guarantee that this function makes data disappear from memory,
 * as runtime implementation can, for example, have copying garbage collector
 * that will make copies of sensitive data before we wipe it. Or that an
 * operating system will write our data to swap or sleep image. Another thing
 * is that an optimizing compiler can remove calls to this function or make it
 * no-op. There's nothing we can do with it, so we just do our best and hope
 * that everything will be okay and good will triumph over evil.
 */ function wipe(array) {
    // Right now it's similar to array.fill(0). If it turns
    // out that runtimes optimize this call away, maybe
    // we can try something else.
    for(var i = 0; i < array.length; i++)array[i] = 0;
    return array;
}
exports.wipe = wipe;

},{}],"jpDs0":[function(require,module,exports) {
"use strict";
// Copyright (C) 2016 Dmitry Chestnykh
// MIT License. See LICENSE file for details.
Object.defineProperty(exports, "__esModule", {
    value: true
});
/**
 * Package binary provides functions for encoding and decoding numbers in byte arrays.
 */ var int_1 = require("@stablelib/int");
// TODO(dchest): add asserts for correct value ranges and array offsets.
/**
 * Reads 2 bytes from array starting at offset as big-endian
 * signed 16-bit integer and returns it.
 */ function readInt16BE(array, offset) {
    if (offset === void 0) offset = 0;
    return (array[offset + 0] << 8 | array[offset + 1]) << 16 >> 16;
}
exports.readInt16BE = readInt16BE;
/**
 * Reads 2 bytes from array starting at offset as big-endian
 * unsigned 16-bit integer and returns it.
 */ function readUint16BE(array, offset) {
    if (offset === void 0) offset = 0;
    return (array[offset + 0] << 8 | array[offset + 1]) >>> 0;
}
exports.readUint16BE = readUint16BE;
/**
 * Reads 2 bytes from array starting at offset as little-endian
 * signed 16-bit integer and returns it.
 */ function readInt16LE(array, offset) {
    if (offset === void 0) offset = 0;
    return (array[offset + 1] << 8 | array[offset]) << 16 >> 16;
}
exports.readInt16LE = readInt16LE;
/**
 * Reads 2 bytes from array starting at offset as little-endian
 * unsigned 16-bit integer and returns it.
 */ function readUint16LE(array, offset) {
    if (offset === void 0) offset = 0;
    return (array[offset + 1] << 8 | array[offset]) >>> 0;
}
exports.readUint16LE = readUint16LE;
/**
 * Writes 2-byte big-endian representation of 16-bit unsigned
 * value to byte array starting at offset.
 *
 * If byte array is not given, creates a new 2-byte one.
 *
 * Returns the output byte array.
 */ function writeUint16BE(value, out, offset) {
    if (out === void 0) out = new Uint8Array(2);
    if (offset === void 0) offset = 0;
    out[offset + 0] = value >>> 8;
    out[offset + 1] = value >>> 0;
    return out;
}
exports.writeUint16BE = writeUint16BE;
exports.writeInt16BE = writeUint16BE;
/**
 * Writes 2-byte little-endian representation of 16-bit unsigned
 * value to array starting at offset.
 *
 * If byte array is not given, creates a new 2-byte one.
 *
 * Returns the output byte array.
 */ function writeUint16LE(value, out, offset) {
    if (out === void 0) out = new Uint8Array(2);
    if (offset === void 0) offset = 0;
    out[offset + 0] = value >>> 0;
    out[offset + 1] = value >>> 8;
    return out;
}
exports.writeUint16LE = writeUint16LE;
exports.writeInt16LE = writeUint16LE;
/**
 * Reads 4 bytes from array starting at offset as big-endian
 * signed 32-bit integer and returns it.
 */ function readInt32BE(array, offset) {
    if (offset === void 0) offset = 0;
    return array[offset] << 24 | array[offset + 1] << 16 | array[offset + 2] << 8 | array[offset + 3];
}
exports.readInt32BE = readInt32BE;
/**
 * Reads 4 bytes from array starting at offset as big-endian
 * unsigned 32-bit integer and returns it.
 */ function readUint32BE(array, offset) {
    if (offset === void 0) offset = 0;
    return (array[offset] << 24 | array[offset + 1] << 16 | array[offset + 2] << 8 | array[offset + 3]) >>> 0;
}
exports.readUint32BE = readUint32BE;
/**
 * Reads 4 bytes from array starting at offset as little-endian
 * signed 32-bit integer and returns it.
 */ function readInt32LE(array, offset) {
    if (offset === void 0) offset = 0;
    return array[offset + 3] << 24 | array[offset + 2] << 16 | array[offset + 1] << 8 | array[offset];
}
exports.readInt32LE = readInt32LE;
/**
 * Reads 4 bytes from array starting at offset as little-endian
 * unsigned 32-bit integer and returns it.
 */ function readUint32LE(array, offset) {
    if (offset === void 0) offset = 0;
    return (array[offset + 3] << 24 | array[offset + 2] << 16 | array[offset + 1] << 8 | array[offset]) >>> 0;
}
exports.readUint32LE = readUint32LE;
/**
 * Writes 4-byte big-endian representation of 32-bit unsigned
 * value to byte array starting at offset.
 *
 * If byte array is not given, creates a new 4-byte one.
 *
 * Returns the output byte array.
 */ function writeUint32BE(value, out, offset) {
    if (out === void 0) out = new Uint8Array(4);
    if (offset === void 0) offset = 0;
    out[offset + 0] = value >>> 24;
    out[offset + 1] = value >>> 16;
    out[offset + 2] = value >>> 8;
    out[offset + 3] = value >>> 0;
    return out;
}
exports.writeUint32BE = writeUint32BE;
exports.writeInt32BE = writeUint32BE;
/**
 * Writes 4-byte little-endian representation of 32-bit unsigned
 * value to array starting at offset.
 *
 * If byte array is not given, creates a new 4-byte one.
 *
 * Returns the output byte array.
 */ function writeUint32LE(value, out, offset) {
    if (out === void 0) out = new Uint8Array(4);
    if (offset === void 0) offset = 0;
    out[offset + 0] = value >>> 0;
    out[offset + 1] = value >>> 8;
    out[offset + 2] = value >>> 16;
    out[offset + 3] = value >>> 24;
    return out;
}
exports.writeUint32LE = writeUint32LE;
exports.writeInt32LE = writeUint32LE;
/**
 * Reads 8 bytes from array starting at offset as big-endian
 * signed 64-bit integer and returns it.
 *
 * IMPORTANT: due to JavaScript limitation, supports exact
 * numbers in range -9007199254740991 to 9007199254740991.
 * If the number stored in the byte array is outside this range,
 * the result is not exact.
 */ function readInt64BE(array, offset) {
    if (offset === void 0) offset = 0;
    var hi = readInt32BE(array, offset);
    var lo = readInt32BE(array, offset + 4);
    return hi * 4294967296 + lo - (lo >> 31) * 4294967296;
}
exports.readInt64BE = readInt64BE;
/**
 * Reads 8 bytes from array starting at offset as big-endian
 * unsigned 64-bit integer and returns it.
 *
 * IMPORTANT: due to JavaScript limitation, supports values up to 2^53-1.
 */ function readUint64BE(array, offset) {
    if (offset === void 0) offset = 0;
    var hi = readUint32BE(array, offset);
    var lo = readUint32BE(array, offset + 4);
    return hi * 4294967296 + lo;
}
exports.readUint64BE = readUint64BE;
/**
 * Reads 8 bytes from array starting at offset as little-endian
 * signed 64-bit integer and returns it.
 *
 * IMPORTANT: due to JavaScript limitation, supports exact
 * numbers in range -9007199254740991 to 9007199254740991.
 * If the number stored in the byte array is outside this range,
 * the result is not exact.
 */ function readInt64LE(array, offset) {
    if (offset === void 0) offset = 0;
    var lo = readInt32LE(array, offset);
    var hi = readInt32LE(array, offset + 4);
    return hi * 4294967296 + lo - (lo >> 31) * 4294967296;
}
exports.readInt64LE = readInt64LE;
/**
 * Reads 8 bytes from array starting at offset as little-endian
 * unsigned 64-bit integer and returns it.
 *
 * IMPORTANT: due to JavaScript limitation, supports values up to 2^53-1.
 */ function readUint64LE(array, offset) {
    if (offset === void 0) offset = 0;
    var lo = readUint32LE(array, offset);
    var hi = readUint32LE(array, offset + 4);
    return hi * 4294967296 + lo;
}
exports.readUint64LE = readUint64LE;
/**
 * Writes 8-byte big-endian representation of 64-bit unsigned
 * value to byte array starting at offset.
 *
 * Due to JavaScript limitation, supports values up to 2^53-1.
 *
 * If byte array is not given, creates a new 8-byte one.
 *
 * Returns the output byte array.
 */ function writeUint64BE(value, out, offset) {
    if (out === void 0) out = new Uint8Array(8);
    if (offset === void 0) offset = 0;
    writeUint32BE(value / 4294967296 >>> 0, out, offset);
    writeUint32BE(value >>> 0, out, offset + 4);
    return out;
}
exports.writeUint64BE = writeUint64BE;
exports.writeInt64BE = writeUint64BE;
/**
 * Writes 8-byte little-endian representation of 64-bit unsigned
 * value to byte array starting at offset.
 *
 * Due to JavaScript limitation, supports values up to 2^53-1.
 *
 * If byte array is not given, creates a new 8-byte one.
 *
 * Returns the output byte array.
 */ function writeUint64LE(value, out, offset) {
    if (out === void 0) out = new Uint8Array(8);
    if (offset === void 0) offset = 0;
    writeUint32LE(value >>> 0, out, offset);
    writeUint32LE(value / 4294967296 >>> 0, out, offset + 4);
    return out;
}
exports.writeUint64LE = writeUint64LE;
exports.writeInt64LE = writeUint64LE;
/**
 * Reads bytes from array starting at offset as big-endian
 * unsigned bitLen-bit integer and returns it.
 *
 * Supports bit lengths divisible by 8, up to 48.
 */ function readUintBE(bitLength, array, offset) {
    if (offset === void 0) offset = 0;
    // TODO(dchest): implement support for bitLengths non-divisible by 8
    if (bitLength % 8 !== 0) throw new Error("readUintBE supports only bitLengths divisible by 8");
    if (bitLength / 8 > array.length - offset) throw new Error("readUintBE: array is too short for the given bitLength");
    var result = 0;
    var mul = 1;
    for(var i = bitLength / 8 + offset - 1; i >= offset; i--){
        result += array[i] * mul;
        mul *= 256;
    }
    return result;
}
exports.readUintBE = readUintBE;
/**
 * Reads bytes from array starting at offset as little-endian
 * unsigned bitLen-bit integer and returns it.
 *
 * Supports bit lengths divisible by 8, up to 48.
 */ function readUintLE(bitLength, array, offset) {
    if (offset === void 0) offset = 0;
    // TODO(dchest): implement support for bitLengths non-divisible by 8
    if (bitLength % 8 !== 0) throw new Error("readUintLE supports only bitLengths divisible by 8");
    if (bitLength / 8 > array.length - offset) throw new Error("readUintLE: array is too short for the given bitLength");
    var result = 0;
    var mul = 1;
    for(var i = offset; i < offset + bitLength / 8; i++){
        result += array[i] * mul;
        mul *= 256;
    }
    return result;
}
exports.readUintLE = readUintLE;
/**
 * Writes a big-endian representation of bitLen-bit unsigned
 * value to array starting at offset.
 *
 * Supports bit lengths divisible by 8, up to 48.
 *
 * If byte array is not given, creates a new one.
 *
 * Returns the output byte array.
 */ function writeUintBE(bitLength, value, out, offset) {
    if (out === void 0) out = new Uint8Array(bitLength / 8);
    if (offset === void 0) offset = 0;
    // TODO(dchest): implement support for bitLengths non-divisible by 8
    if (bitLength % 8 !== 0) throw new Error("writeUintBE supports only bitLengths divisible by 8");
    if (!int_1.isSafeInteger(value)) throw new Error("writeUintBE value must be an integer");
    var div = 1;
    for(var i = bitLength / 8 + offset - 1; i >= offset; i--){
        out[i] = value / div & 255;
        div *= 256;
    }
    return out;
}
exports.writeUintBE = writeUintBE;
/**
 * Writes a little-endian representation of bitLen-bit unsigned
 * value to array starting at offset.
 *
 * Supports bit lengths divisible by 8, up to 48.
 *
 * If byte array is not given, creates a new one.
 *
 * Returns the output byte array.
 */ function writeUintLE(bitLength, value, out, offset) {
    if (out === void 0) out = new Uint8Array(bitLength / 8);
    if (offset === void 0) offset = 0;
    // TODO(dchest): implement support for bitLengths non-divisible by 8
    if (bitLength % 8 !== 0) throw new Error("writeUintLE supports only bitLengths divisible by 8");
    if (!int_1.isSafeInteger(value)) throw new Error("writeUintLE value must be an integer");
    var div = 1;
    for(var i = offset; i < offset + bitLength / 8; i++){
        out[i] = value / div & 255;
        div *= 256;
    }
    return out;
}
exports.writeUintLE = writeUintLE;
/**
 * Reads 4 bytes from array starting at offset as big-endian
 * 32-bit floating-point number and returns it.
 */ function readFloat32BE(array, offset) {
    if (offset === void 0) offset = 0;
    var view = new DataView(array.buffer, array.byteOffset, array.byteLength);
    return view.getFloat32(offset);
}
exports.readFloat32BE = readFloat32BE;
/**
 * Reads 4 bytes from array starting at offset as little-endian
 * 32-bit floating-point number and returns it.
 */ function readFloat32LE(array, offset) {
    if (offset === void 0) offset = 0;
    var view = new DataView(array.buffer, array.byteOffset, array.byteLength);
    return view.getFloat32(offset, true);
}
exports.readFloat32LE = readFloat32LE;
/**
 * Reads 8 bytes from array starting at offset as big-endian
 * 64-bit floating-point number ("double") and returns it.
 */ function readFloat64BE(array, offset) {
    if (offset === void 0) offset = 0;
    var view = new DataView(array.buffer, array.byteOffset, array.byteLength);
    return view.getFloat64(offset);
}
exports.readFloat64BE = readFloat64BE;
/**
 * Reads 8 bytes from array starting at offset as little-endian
 * 64-bit floating-point number ("double") and returns it.
 */ function readFloat64LE(array, offset) {
    if (offset === void 0) offset = 0;
    var view = new DataView(array.buffer, array.byteOffset, array.byteLength);
    return view.getFloat64(offset, true);
}
exports.readFloat64LE = readFloat64LE;
/**
 * Writes 4-byte big-endian floating-point representation of value
 * to byte array starting at offset.
 *
 * If byte array is not given, creates a new 4-byte one.
 *
 * Returns the output byte array.
 */ function writeFloat32BE(value, out, offset) {
    if (out === void 0) out = new Uint8Array(4);
    if (offset === void 0) offset = 0;
    var view = new DataView(out.buffer, out.byteOffset, out.byteLength);
    view.setFloat32(offset, value);
    return out;
}
exports.writeFloat32BE = writeFloat32BE;
/**
 * Writes 4-byte little-endian floating-point representation of value
 * to byte array starting at offset.
 *
 * If byte array is not given, creates a new 4-byte one.
 *
 * Returns the output byte array.
 */ function writeFloat32LE(value, out, offset) {
    if (out === void 0) out = new Uint8Array(4);
    if (offset === void 0) offset = 0;
    var view = new DataView(out.buffer, out.byteOffset, out.byteLength);
    view.setFloat32(offset, value, true);
    return out;
}
exports.writeFloat32LE = writeFloat32LE;
/**
 * Writes 8-byte big-endian floating-point representation of value
 * to byte array starting at offset.
 *
 * If byte array is not given, creates a new 8-byte one.
 *
 * Returns the output byte array.
 */ function writeFloat64BE(value, out, offset) {
    if (out === void 0) out = new Uint8Array(8);
    if (offset === void 0) offset = 0;
    var view = new DataView(out.buffer, out.byteOffset, out.byteLength);
    view.setFloat64(offset, value);
    return out;
}
exports.writeFloat64BE = writeFloat64BE;
/**
 * Writes 8-byte little-endian floating-point representation of value
 * to byte array starting at offset.
 *
 * If byte array is not given, creates a new 8-byte one.
 *
 * Returns the output byte array.
 */ function writeFloat64LE(value, out, offset) {
    if (out === void 0) out = new Uint8Array(8);
    if (offset === void 0) offset = 0;
    var view = new DataView(out.buffer, out.byteOffset, out.byteLength);
    view.setFloat64(offset, value, true);
    return out;
}
exports.writeFloat64LE = writeFloat64LE;

},{"@stablelib/int":"hoCdR"}],"hoCdR":[function(require,module,exports) {
"use strict";
// Copyright (C) 2016 Dmitry Chestnykh
// MIT License. See LICENSE file for details.
Object.defineProperty(exports, "__esModule", {
    value: true
});
/**
 * Package int provides helper functions for integerss.
 */ // Shim using 16-bit pieces.
function imulShim(a, b) {
    var ah = a >>> 16 & 65535, al = a & 65535;
    var bh = b >>> 16 & 65535, bl = b & 65535;
    return al * bl + (ah * bl + al * bh << 16 >>> 0) | 0;
}
/** 32-bit integer multiplication.  */ // Use system Math.imul if available, otherwise use our shim.
exports.mul = Math.imul || imulShim;
/** 32-bit integer addition.  */ function add(a, b) {
    return a + b | 0;
}
exports.add = add;
/**  32-bit integer subtraction.  */ function sub(a, b) {
    return a - b | 0;
}
exports.sub = sub;
/** 32-bit integer left rotation */ function rotl(x, n) {
    return x << n | x >>> 32 - n;
}
exports.rotl = rotl;
/** 32-bit integer left rotation */ function rotr(x, n) {
    return x << 32 - n | x >>> n;
}
exports.rotr = rotr;
function isIntegerShim(n) {
    return typeof n === "number" && isFinite(n) && Math.floor(n) === n;
}
/**
 * Returns true if the argument is an integer number.
 *
 * In ES2015, Number.isInteger.
 */ exports.isInteger = Number.isInteger || isIntegerShim;
/**
 *  Math.pow(2, 53) - 1
 *
 *  In ES2015 Number.MAX_SAFE_INTEGER.
 */ exports.MAX_SAFE_INTEGER = 9007199254740991;
/**
 * Returns true if the argument is a safe integer number
 * (-MIN_SAFE_INTEGER < number <= MAX_SAFE_INTEGER)
 *
 * In ES2015, Number.isSafeInteger.
 */ exports.isSafeInteger = function(n) {
    return exports.isInteger(n) && n >= -exports.MAX_SAFE_INTEGER && n <= exports.MAX_SAFE_INTEGER;
};

},{}],"64xeB":[function(require,module,exports) {
'use strict';
const isBuffer = require('is-buffer');
const Shake = require('it-handshake');
const lp = require('it-length-prefixed');
module.exports = (duplex, opts = {
})=>{
    const shake = Shake(duplex);
    const lpReader = lp.decode.fromReader(shake.reader, opts);
    let isDone = false;
    const W = {
        read: async (bytes)=>{
            // just read
            const { value , done  } = await shake.reader.next(bytes);
            if (done && value.length < bytes) throw new Error('Couldn\'t read enough bytes');
            isDone = done;
            if (!value) throw new Error('Value is null');
            return value;
        },
        readLP: async ()=>{
            // read, decode
            const { value , done  } = await lpReader.next();
            isDone = done;
            if (!value) throw new Error('Value is null');
            return value;
        },
        readPB: async (proto)=>{
            // readLP, decode
            const value = await W.readLP();
            if (!value) throw new Error('Value is null');
            // Is this a buffer?
            const buf = isBuffer(value) ? value : value.slice();
            return proto.decode(buf);
        },
        write: (data)=>{
            // just write
            shake.writer.push(data);
        },
        writeLP: (data)=>{
            // encode, write
            W.write(lp.encode.single(data, opts));
        },
        writePB: (data, proto)=>{
            // encode, writeLP
            W.writeLP(proto.encode(data));
        },
        pb: (proto)=>{
            return {
                read: ()=>W.readPB(proto)
                ,
                write: (d)=>W.writePB(d, proto)
            };
        },
        unwrap: ()=>{
            // returns vanilla duplex again, terminates all reads/writes from this object
            shake.rest();
            return shake.stream;
        }
    };
    return W;
};

},{"is-buffer":"1UQTn","it-handshake":"gkdlr","it-length-prefixed":"2cvC1"}],"gkdlr":[function(require,module,exports) {
'use strict';
const Reader = require('it-reader');
const Writer = require('it-pushable');
const defer = require('p-defer');
// Convert a duplex stream into a reader and writer and rest stream
module.exports = (stream)=>{
    const writer = Writer() // Write bytes on demand to the sink
    ;
    const reader = Reader(stream.source) // Read bytes on demand from the source
    ;
    // Waits for a source to be passed to the rest stream's sink
    const sourcePromise = defer();
    let sinkErr;
    const sinkPromise = stream.sink(async function*() {
        yield* writer;
        const source = await sourcePromise.promise;
        yield* source;
    }());
    sinkPromise.catch((err)=>{
        sinkErr = err;
    });
    const rest = {
        sink: (source)=>{
            if (sinkErr) return Promise.reject(sinkErr);
            sourcePromise.resolve(source);
            return sinkPromise;
        },
        source: reader
    };
    return {
        reader,
        writer,
        stream: rest,
        rest: ()=>writer.end()
        ,
        write: writer.push,
        read: async ()=>{
            return (await reader.next()).value;
        }
    };
};

},{"it-reader":"8Ef74","it-pushable":"hRi4l","p-defer":"gZqcC"}],"iMkvZ":[function(require,module,exports) {
var Pair = require('./');
module.exports = function() {
    var a = Pair();
    var b = Pair();
    return [
        {
            source: a.source,
            sink: b.sink
        },
        {
            source: b.source,
            sink: a.sink
        }
    ];
};

},{"./":"5FAie"}],"5FAie":[function(require,module,exports) {
'use strict';
const getIterator = require('get-iterator');
// a pair of streams where one drains from the other
module.exports = function pair() {
    let _source, onSource;
    const sink = async (source)=>{
        if (_source) throw new Error('already piped');
        _source = getIterator(source);
        if (onSource) onSource(_source);
    };
    const source1 = {
        [Symbol.asyncIterator] () {
            return this;
        },
        next () {
            if (_source) return _source.next();
            return new Promise((resolve)=>{
                onSource = (source)=>{
                    onSource = null;
                    resolve(source.next());
                };
            });
        }
    };
    return {
        sink,
        source: source1
    };
};

},{"get-iterator":"lJJ8v"}],"cfN57":[function(require,module,exports) {
'use strict';
const { Buffer  } = require('buffer');
const BufferList = require('bl/BufferList');
module.exports = async function*(source) {
    for await (const b of source){
        if (Buffer.isBuffer(b)) yield b;
        else if (BufferList.isBufferList(b)) yield b.slice();
        else yield Buffer.from(b);
    }
};
module.exports.toBuffer = module.exports;
module.exports.toList = async function*(source) {
    for await (const b of source){
        if (Buffer.isBuffer(b)) yield new BufferList().append(b);
        else if (BufferList.isBufferList(b)) yield b;
        else yield new BufferList().append(Buffer.from(b));
    }
};

},{"buffer":"eKea5","bl/BufferList":"cK5XN"}],"40XvU":[function(require,module,exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.XXHandshake = void 0;
const buffer_1 = require("buffer");
const xx_1 = require("./handshakes/xx");
const utils_1 = require("./utils");
const logger_1 = require("./logger");
const encoder_1 = require("./encoder");
class XXHandshake {
    constructor(isInitiator, payload, prologue, staticKeypair, connection, remotePeer, handshake){
        this.isInitiator = isInitiator;
        this.payload = payload;
        this.prologue = prologue;
        this.staticKeypair = staticKeypair;
        this.connection = connection;
        if (remotePeer) this.remotePeer = remotePeer;
        this.xx = handshake !== null && handshake !== void 0 ? handshake : new xx_1.XX();
        this.session = this.xx.initSession(this.isInitiator, this.prologue, this.staticKeypair);
        this.remoteEarlyData = buffer_1.Buffer.alloc(0);
    }
    // stage 0
    async propose() {
        logger_1.logLocalStaticKeys(this.session.hs.s);
        if (this.isInitiator) {
            logger_1.logger('Stage 0 - Initiator starting to send first message.');
            const messageBuffer = this.xx.sendMessage(this.session, buffer_1.Buffer.alloc(0));
            this.connection.writeLP(encoder_1.encode0(messageBuffer));
            logger_1.logger('Stage 0 - Initiator finished sending first message.');
            logger_1.logLocalEphemeralKeys(this.session.hs.e);
        } else {
            logger_1.logger('Stage 0 - Responder waiting to receive first message...');
            const receivedMessageBuffer = encoder_1.decode0((await this.connection.readLP()).slice());
            const { valid  } = this.xx.recvMessage(this.session, receivedMessageBuffer);
            if (!valid) throw new Error('xx handshake stage 0 validation fail');
            logger_1.logger('Stage 0 - Responder received first message.');
            logger_1.logRemoteEphemeralKey(this.session.hs.re);
        }
    }
    // stage 1
    async exchange() {
        if (this.isInitiator) {
            logger_1.logger('Stage 1 - Initiator waiting to receive first message from responder...');
            const receivedMessageBuffer = encoder_1.decode1((await this.connection.readLP()).slice());
            const { plaintext , valid  } = this.xx.recvMessage(this.session, receivedMessageBuffer);
            if (!valid) throw new Error('xx handshake stage 1 validation fail');
            logger_1.logger('Stage 1 - Initiator received the message.');
            logger_1.logRemoteEphemeralKey(this.session.hs.re);
            logger_1.logRemoteStaticKey(this.session.hs.rs);
            logger_1.logger("Initiator going to check remote's signature...");
            try {
                const decodedPayload = await utils_1.decodePayload(plaintext);
                this.remotePeer = this.remotePeer || await utils_1.getPeerIdFromPayload(decodedPayload);
                this.remotePeer = await utils_1.verifySignedPayload(receivedMessageBuffer.ns, decodedPayload, this.remotePeer);
                this.setRemoteEarlyData(decodedPayload.data);
            } catch (e) {
                const err = e;
                throw new Error(`Error occurred while verifying signed payload: ${err.message}`);
            }
            logger_1.logger('All good with the signature!');
        } else {
            logger_1.logger('Stage 1 - Responder sending out first message with signed payload and static key.');
            const messageBuffer = this.xx.sendMessage(this.session, this.payload);
            this.connection.writeLP(encoder_1.encode1(messageBuffer));
            logger_1.logger('Stage 1 - Responder sent the second handshake message with signed payload.');
            logger_1.logLocalEphemeralKeys(this.session.hs.e);
        }
    }
    // stage 2
    async finish() {
        if (this.isInitiator) {
            logger_1.logger('Stage 2 - Initiator sending third handshake message.');
            const messageBuffer = this.xx.sendMessage(this.session, this.payload);
            this.connection.writeLP(encoder_1.encode2(messageBuffer));
            logger_1.logger('Stage 2 - Initiator sent message with signed payload.');
        } else {
            logger_1.logger('Stage 2 - Responder waiting for third handshake message...');
            const receivedMessageBuffer = encoder_1.decode2((await this.connection.readLP()).slice());
            const { plaintext , valid  } = this.xx.recvMessage(this.session, receivedMessageBuffer);
            if (!valid) throw new Error('xx handshake stage 2 validation fail');
            logger_1.logger('Stage 2 - Responder received the message, finished handshake.');
            try {
                const decodedPayload = await utils_1.decodePayload(plaintext);
                this.remotePeer = this.remotePeer || await utils_1.getPeerIdFromPayload(decodedPayload);
                await utils_1.verifySignedPayload(this.session.hs.rs, decodedPayload, this.remotePeer);
                this.setRemoteEarlyData(decodedPayload.data);
            } catch (e) {
                const err = e;
                throw new Error(`Error occurred while verifying signed payload: ${err.message}`);
            }
        }
        logger_1.logCipherState(this.session);
    }
    encrypt(plaintext, session) {
        const cs = this.getCS(session);
        return this.xx.encryptWithAd(cs, buffer_1.Buffer.alloc(0), plaintext);
    }
    decrypt(ciphertext, session1) {
        const cs = this.getCS(session1, false);
        return this.xx.decryptWithAd(cs, buffer_1.Buffer.alloc(0), ciphertext);
    }
    getRemoteStaticKey() {
        return this.session.hs.rs;
    }
    getCS(session2, encryption = true) {
        if (!session2.cs1 || !session2.cs2) throw new Error('Handshake not completed properly, cipher state does not exist.');
        if (this.isInitiator) return encryption ? session2.cs1 : session2.cs2;
        else return encryption ? session2.cs2 : session2.cs1;
    }
    setRemoteEarlyData(data) {
        if (data) this.remoteEarlyData = buffer_1.Buffer.from(data.buffer, data.byteOffset, data.length);
    }
}
exports.XXHandshake = XXHandshake;

},{"buffer":"eKea5","./handshakes/xx":"kLnzd","./utils":"3C9kU","./logger":"hHMfO","./encoder":"fw0Lz"}],"kLnzd":[function(require,module,exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.XX = void 0;
const buffer_1 = require("buffer");
const utils_1 = require("../utils");
const abstract_handshake_1 = require("./abstract-handshake");
class XX extends abstract_handshake_1.AbstractHandshake {
    initializeInitiator(prologue, s, rs, psk) {
        const name = 'Noise_XX_25519_ChaChaPoly_SHA256';
        const ss = this.initializeSymmetric(name);
        this.mixHash(ss, prologue);
        const re = buffer_1.Buffer.alloc(32);
        return {
            ss,
            s,
            rs,
            psk,
            re
        };
    }
    initializeResponder(prologue1, s1, rs1, psk1) {
        const name = 'Noise_XX_25519_ChaChaPoly_SHA256';
        const ss = this.initializeSymmetric(name);
        this.mixHash(ss, prologue1);
        const re = buffer_1.Buffer.alloc(32);
        return {
            ss,
            s: s1,
            rs: rs1,
            psk: psk1,
            re
        };
    }
    writeMessageA(hs, payload, e) {
        const ns = buffer_1.Buffer.alloc(0);
        if (e !== undefined) hs.e = e;
        else hs.e = utils_1.generateKeypair();
        const ne = hs.e.publicKey;
        this.mixHash(hs.ss, ne);
        const ciphertext = this.encryptAndHash(hs.ss, payload);
        return {
            ne,
            ns,
            ciphertext
        };
    }
    writeMessageB(hs1, payload1) {
        hs1.e = utils_1.generateKeypair();
        const ne = hs1.e.publicKey;
        this.mixHash(hs1.ss, ne);
        this.mixKey(hs1.ss, this.dh(hs1.e.privateKey, hs1.re));
        const spk = buffer_1.Buffer.from(hs1.s.publicKey);
        const ns = this.encryptAndHash(hs1.ss, spk);
        this.mixKey(hs1.ss, this.dh(hs1.s.privateKey, hs1.re));
        const ciphertext = this.encryptAndHash(hs1.ss, payload1);
        return {
            ne,
            ns,
            ciphertext
        };
    }
    writeMessageC(hs2, payload2) {
        const spk = buffer_1.Buffer.from(hs2.s.publicKey);
        const ns = this.encryptAndHash(hs2.ss, spk);
        this.mixKey(hs2.ss, this.dh(hs2.s.privateKey, hs2.re));
        const ciphertext = this.encryptAndHash(hs2.ss, payload2);
        const ne = this.createEmptyKey();
        const messageBuffer = {
            ne,
            ns,
            ciphertext
        };
        const { cs1 , cs2  } = this.split(hs2.ss);
        return {
            h: hs2.ss.h,
            messageBuffer,
            cs1,
            cs2
        };
    }
    readMessageA(hs3, message) {
        if (utils_1.isValidPublicKey(message.ne)) hs3.re = message.ne;
        this.mixHash(hs3.ss, hs3.re);
        return this.decryptAndHash(hs3.ss, message.ciphertext);
    }
    readMessageB(hs4, message1) {
        if (utils_1.isValidPublicKey(message1.ne)) hs4.re = message1.ne;
        this.mixHash(hs4.ss, hs4.re);
        if (!hs4.e) throw new Error('Handshake state `e` param is missing.');
        this.mixKey(hs4.ss, this.dh(hs4.e.privateKey, hs4.re));
        const { plaintext: ns , valid: valid1  } = this.decryptAndHash(hs4.ss, message1.ns);
        if (valid1 && ns.length === 32 && utils_1.isValidPublicKey(ns)) hs4.rs = ns;
        this.mixKey(hs4.ss, this.dh(hs4.e.privateKey, hs4.rs));
        const { plaintext , valid: valid2  } = this.decryptAndHash(hs4.ss, message1.ciphertext);
        return {
            plaintext,
            valid: valid1 && valid2
        };
    }
    readMessageC(hs5, message2) {
        const { plaintext: ns , valid: valid1  } = this.decryptAndHash(hs5.ss, message2.ns);
        if (valid1 && ns.length === 32 && utils_1.isValidPublicKey(ns)) hs5.rs = ns;
        if (!hs5.e) throw new Error('Handshake state `e` param is missing.');
        this.mixKey(hs5.ss, this.dh(hs5.e.privateKey, hs5.rs));
        const { plaintext , valid: valid2  } = this.decryptAndHash(hs5.ss, message2.ciphertext);
        const { cs1 , cs2  } = this.split(hs5.ss);
        return {
            h: hs5.ss.h,
            plaintext,
            valid: valid1 && valid2,
            cs1,
            cs2
        };
    }
    initSession(initiator, prologue2, s2) {
        const psk = this.createEmptyKey();
        const rs = buffer_1.Buffer.alloc(32); // no static key yet
        let hs;
        if (initiator) hs = this.initializeInitiator(prologue2, s2, rs, psk);
        else hs = this.initializeResponder(prologue2, s2, rs, psk);
        return {
            hs,
            i: initiator,
            mc: 0
        };
    }
    sendMessage(session, message3, ephemeral) {
        let messageBuffer;
        if (session.mc === 0) messageBuffer = this.writeMessageA(session.hs, message3, ephemeral);
        else if (session.mc === 1) messageBuffer = this.writeMessageB(session.hs, message3);
        else if (session.mc === 2) {
            const { h , messageBuffer: resultingBuffer , cs1 , cs2  } = this.writeMessageC(session.hs, message3);
            messageBuffer = resultingBuffer;
            session.h = h;
            session.cs1 = cs1;
            session.cs2 = cs2;
        } else if (session.mc > 2) {
            if (session.i) {
                if (!session.cs1) throw new Error('CS1 (cipher state) is not defined');
                messageBuffer = this.writeMessageRegular(session.cs1, message3);
            } else {
                if (!session.cs2) throw new Error('CS2 (cipher state) is not defined');
                messageBuffer = this.writeMessageRegular(session.cs2, message3);
            }
        } else throw new Error('Session invalid.');
        session.mc++;
        return messageBuffer;
    }
    recvMessage(session1, message4) {
        let plaintext = buffer_1.Buffer.alloc(0);
        let valid = false;
        if (session1.mc === 0) ({ plaintext , valid  } = this.readMessageA(session1.hs, message4));
        else if (session1.mc === 1) ({ plaintext , valid  } = this.readMessageB(session1.hs, message4));
        else if (session1.mc === 2) {
            const { h , plaintext: resultingPlaintext , valid: resultingValid , cs1 , cs2  } = this.readMessageC(session1.hs, message4);
            plaintext = resultingPlaintext;
            valid = resultingValid;
            session1.h = h;
            session1.cs1 = cs1;
            session1.cs2 = cs2;
        }
        session1.mc++;
        return {
            plaintext,
            valid
        };
    }
}
exports.XX = XX;

},{"buffer":"eKea5","../utils":"3C9kU","./abstract-handshake":"5ysQS"}],"3C9kU":[function(require,module,exports) {
"use strict";
var __createBinding = this && this.__createBinding || (Object.create ? function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    Object.defineProperty(o, k2, {
        enumerable: true,
        get: function() {
            return m[k];
        }
    });
} : function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
});
var __setModuleDefault = this && this.__setModuleDefault || (Object.create ? function(o, v) {
    Object.defineProperty(o, "default", {
        enumerable: true,
        value: v
    });
} : function(o, v) {
    o["default"] = v;
});
var __importStar = this && this.__importStar || function(mod) {
    if (mod && mod.__esModule) return mod;
    var result = {
    };
    if (mod != null) {
        for(var k in mod)if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    }
    __setModuleDefault(result, mod);
    return result;
};
var __importDefault = this && this.__importDefault || function(mod) {
    return mod && mod.__esModule ? mod : {
        "default": mod
    };
};
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.isValidPublicKey = exports.getHkdf = exports.verifySignedPayload = exports.getHandshakePayload = exports.decodePayload = exports.getPeerIdFromPayload = exports.signPayload = exports.createHandshakePayload = exports.getPayload = exports.generateKeypair = void 0;
const hkdf_1 = require("@stablelib/hkdf");
const sha256_1 = require("@stablelib/sha256");
const x25519 = __importStar(require("@stablelib/x25519"));
const buffer_1 = require("buffer");
const peer_id_1 = __importDefault(require("peer-id"));
const libp2p_crypto_1 = require("libp2p-crypto");
const payload_1 = require("./proto/payload");
const equals_1 = require("uint8arrays/equals");
const NoiseHandshakePayloadProto = payload_1.pb.NoiseHandshakePayload;
function generateKeypair() {
    const keypair = x25519.generateKeyPair();
    return {
        publicKey: buffer_1.Buffer.from(keypair.publicKey.buffer, keypair.publicKey.byteOffset, keypair.publicKey.length),
        privateKey: buffer_1.Buffer.from(keypair.secretKey.buffer, keypair.secretKey.byteOffset, keypair.secretKey.length)
    };
}
exports.generateKeypair = generateKeypair;
async function getPayload(localPeer, staticPublicKey, earlyData) {
    const signedPayload = await signPayload(localPeer, getHandshakePayload(staticPublicKey));
    const earlyDataPayload = earlyData !== null && earlyData !== void 0 ? earlyData : buffer_1.Buffer.alloc(0);
    return createHandshakePayload(localPeer.marshalPubKey(), signedPayload, earlyDataPayload);
}
exports.getPayload = getPayload;
function createHandshakePayload(libp2pPublicKey, signedPayload, earlyData) {
    const payloadInit = NoiseHandshakePayloadProto.create({
        identityKey: buffer_1.Buffer.from(libp2pPublicKey),
        identitySig: signedPayload,
        data: earlyData !== null && earlyData !== void 0 ? earlyData : null
    });
    return buffer_1.Buffer.from(NoiseHandshakePayloadProto.encode(payloadInit).finish());
}
exports.createHandshakePayload = createHandshakePayload;
async function signPayload(peerId, payload) {
    return buffer_1.Buffer.from(await peerId.privKey.sign(payload));
}
exports.signPayload = signPayload;
async function getPeerIdFromPayload(payload) {
    return await peer_id_1.default.createFromPubKey(buffer_1.Buffer.from(payload.identityKey));
}
exports.getPeerIdFromPayload = getPeerIdFromPayload;
function decodePayload(payload) {
    return NoiseHandshakePayloadProto.toObject(NoiseHandshakePayloadProto.decode(buffer_1.Buffer.from(payload)));
}
exports.decodePayload = decodePayload;
function getHandshakePayload(publicKey) {
    return buffer_1.Buffer.concat([
        buffer_1.Buffer.from('noise-libp2p-static-key:'),
        publicKey
    ]);
}
exports.getHandshakePayload = getHandshakePayload;
async function isValidPeerId(peerId, publicKeyProtobuf) {
    const generatedPeerId = await peer_id_1.default.createFromPubKey(publicKeyProtobuf);
    return equals_1.equals(generatedPeerId.id, peerId);
}
/**
 * Verifies signed payload, throws on any irregularities.
 *
 * @param {bytes} noiseStaticKey - owner's noise static key
 * @param {bytes} payload - decoded payload
 * @param {PeerId} remotePeer - owner's libp2p peer ID
 * @returns {Promise<PeerId>} - peer ID of payload owner
 */ async function verifySignedPayload(noiseStaticKey, payload, remotePeer) {
    const identityKey = buffer_1.Buffer.from(payload.identityKey);
    if (!await isValidPeerId(remotePeer.id, identityKey)) throw new Error("Peer ID doesn't match libp2p public key.");
    const generatedPayload = getHandshakePayload(noiseStaticKey);
    // Unmarshaling from PublicKey protobuf
    const publicKey = libp2p_crypto_1.keys.unmarshalPublicKey(identityKey);
    // TODO remove this after libp2p-crypto ships proper types
    // eslint-disable-next-line @typescript-eslint/no-misused-promises
    if (!payload.identitySig || !publicKey.verify(generatedPayload, buffer_1.Buffer.from(payload.identitySig))) throw new Error("Static key doesn't match to peer that signed payload!");
    return await peer_id_1.default.createFromPubKey(identityKey);
}
exports.verifySignedPayload = verifySignedPayload;
function getHkdf(ck, ikm) {
    const hkdf = new hkdf_1.HKDF(sha256_1.SHA256, ikm, ck);
    const okmU8Array = hkdf.expand(96);
    const okm = buffer_1.Buffer.from(okmU8Array.buffer, okmU8Array.byteOffset, okmU8Array.length);
    const k1 = okm.slice(0, 32);
    const k2 = okm.slice(32, 64);
    const k3 = okm.slice(64, 96);
    return [
        k1,
        k2,
        k3
    ];
}
exports.getHkdf = getHkdf;
function isValidPublicKey(pk) {
    if (!buffer_1.Buffer.isBuffer(pk)) return false;
    if (pk.length !== 32) return false;
    return true;
}
exports.isValidPublicKey = isValidPublicKey;

},{"@stablelib/hkdf":"2kSJI","@stablelib/sha256":"6Moum","@stablelib/x25519":"f6HJy","buffer":"eKea5","peer-id":"4VGWt","libp2p-crypto":"hsRcr","./proto/payload":"2BVF8","uint8arrays/equals":"fjLeN"}],"2kSJI":[function(require,module,exports) {
"use strict";
// Copyright (C) 2016 Dmitry Chestnykh
// MIT License. See LICENSE file for details.
Object.defineProperty(exports, "__esModule", {
    value: true
});
var hmac_1 = require("@stablelib/hmac");
var wipe_1 = require("@stablelib/wipe");
/**
 * HMAC-based Extract-and-Expand Key Derivation Function.
 *
 * Implements HKDF from RFC5869.
 *
 * Expands the given master key with salt and info into
 * a limited stream of key material.
 */ var HKDF1 = function() {
    /**
     * Create a new HKDF instance for the given hash function
     * with the master key, optional salt, and info.
     *
     * - Master key is a high-entropy secret key (not a password).
     * - Salt is a non-secret random value.
     * - Info is application- and/or context-specific information.
     */ function HKDF(hash, key, salt, info) {
        if (salt === void 0) salt = new Uint8Array(0);
        this._counter = new Uint8Array(1); // starts with zero
        this._hash = hash;
        this._info = info;
        // HKDF-Extract uses salt as HMAC key, and key as data.
        var okm = hmac_1.hmac(this._hash, salt, key);
        // Initialize HMAC for expanding with extracted key.
        this._hmac = new hmac_1.HMAC(hash, okm);
        // Allocate buffer.
        this._buffer = new Uint8Array(this._hmac.digestLength);
        this._bufpos = this._buffer.length;
    }
    // Fill buffer with new block of HKDF-Extract output.
    HKDF.prototype._fillBuffer = function() {
        // Increment counter.
        this._counter[0]++;
        var ctr = this._counter[0];
        // Check if counter overflowed.
        if (ctr === 0) throw new Error("hkdf: cannot expand more");
        // Prepare HMAC instance for new data with old key.
        this._hmac.reset();
        // Hash in previous output if it was generated
        // (i.e. counter is greater than 1).
        if (ctr > 1) this._hmac.update(this._buffer);
        // Hash in info if it exists.
        if (this._info) this._hmac.update(this._info);
        // Hash in the counter.
        this._hmac.update(this._counter);
        // Output result to buffer and clean HMAC instance.
        this._hmac.finish(this._buffer);
        // Reset buffer position.
        this._bufpos = 0;
    };
    /**
     * Expand returns next key material of the given length.
     *
     * It throws if expansion limit is reached (which is
     * 254 digests of the underlying HMAC function).
     */ HKDF.prototype.expand = function(length) {
        var out = new Uint8Array(length);
        for(var i = 0; i < out.length; i++){
            if (this._bufpos === this._buffer.length) this._fillBuffer();
            out[i] = this._buffer[this._bufpos++];
        }
        return out;
    };
    HKDF.prototype.clean = function() {
        this._hmac.clean();
        wipe_1.wipe(this._buffer);
        wipe_1.wipe(this._counter);
        this._bufpos = 0;
    };
    return HKDF;
}();
exports.HKDF = HKDF1; // TODO(dchest): maybe implement deriveKey?

},{"@stablelib/hmac":"biINZ","@stablelib/wipe":"eWLFw"}],"biINZ":[function(require,module,exports) {
"use strict";
// Copyright (C) 2016 Dmitry Chestnykh
// MIT License. See LICENSE file for details.
Object.defineProperty(exports, "__esModule", {
    value: true
});
/**
 * Package hmac implements HMAC algorithm.
 */ var hash_1 = require("@stablelib/hash");
var constant_time_1 = require("@stablelib/constant-time");
var wipe_1 = require("@stablelib/wipe");
/**
 *  HMAC implements hash-based message authentication algorithm.
 */ var HMAC1 = function() {
    /**
     * Constructs a new HMAC with the given Hash and secret key.
     */ function HMAC(hash, key) {
        this._finished = false; // true if HMAC was finalized
        // Initialize inner and outer hashes.
        this._inner = new hash();
        this._outer = new hash();
        // Set block and digest sizes for this HMAC
        // instance to values from the hash.
        this.blockSize = this._outer.blockSize;
        this.digestLength = this._outer.digestLength;
        // Pad temporary stores a key (or its hash) padded with zeroes.
        var pad = new Uint8Array(this.blockSize);
        if (key.length > this.blockSize) // If key is bigger than hash block size, it must be
        // hashed and this hash is used as a key instead.
        this._inner.update(key).finish(pad).clean();
        else // Otherwise, copy the key into pad.
        pad.set(key);
        // Now two different keys are derived from padded key
        // by xoring a different byte value to each.
        // To make inner hash key, xor byte 0x36 into pad.
        for(var i = 0; i < pad.length; i++)pad[i] ^= 54;
        // Update inner hash with the result.
        this._inner.update(pad);
        // To make outer hash key, xor byte 0x5c into pad.
        // But since we already xored 0x36 there, we must
        // first undo this by xoring it again.
        for(var i = 0; i < pad.length; i++)pad[i] ^= 106;
        // Update outer hash with the result.
        this._outer.update(pad);
        // Save states of both hashes, so that we can quickly restore
        // them later in reset() without the need to remember the actual
        // key and perform this initialization again.
        if (hash_1.isSerializableHash(this._inner) && hash_1.isSerializableHash(this._outer)) {
            this._innerKeyedState = this._inner.saveState();
            this._outerKeyedState = this._outer.saveState();
        }
        // Clean pad.
        wipe_1.wipe(pad);
    }
    /**
     * Returns HMAC state to the state initialized with key
     * to make it possible to run HMAC over the other data with the same
     * key without creating a new instance.
     */ HMAC.prototype.reset = function() {
        if (!hash_1.isSerializableHash(this._inner) || !hash_1.isSerializableHash(this._outer)) throw new Error("hmac: can't reset() because hash doesn't implement restoreState()");
        // Restore keyed states of inner and outer hashes.
        this._inner.restoreState(this._innerKeyedState);
        this._outer.restoreState(this._outerKeyedState);
        this._finished = false;
        return this;
    };
    /**
     * Cleans HMAC state.
     */ HMAC.prototype.clean = function() {
        if (hash_1.isSerializableHash(this._inner)) this._inner.cleanSavedState(this._innerKeyedState);
        if (hash_1.isSerializableHash(this._outer)) this._outer.cleanSavedState(this._outerKeyedState);
        this._inner.clean();
        this._outer.clean();
    };
    /**
     * Updates state with provided data.
     */ HMAC.prototype.update = function(data) {
        this._inner.update(data);
        return this;
    };
    /**
     * Finalizes HMAC and puts the result in out.
     */ HMAC.prototype.finish = function(out) {
        if (this._finished) {
            // If HMAC was finalized, outer hash is also finalized,
            // so it produces the same digest it produced when it
            // was finalized.
            this._outer.finish(out);
            return this;
        }
        // Finalize inner hash and store the result temporarily.
        this._inner.finish(out);
        // Update outer hash with digest of inner hash and and finalize it.
        this._outer.update(out.subarray(0, this.digestLength)).finish(out);
        this._finished = true;
        return this;
    };
    /**
     * Returns the computed message authentication code.
     */ HMAC.prototype.digest = function() {
        var out = new Uint8Array(this.digestLength);
        this.finish(out);
        return out;
    };
    /**
     * Saves HMAC state.
     * This function is needed for PBKDF2 optimization.
     */ HMAC.prototype.saveState = function() {
        if (!hash_1.isSerializableHash(this._inner)) throw new Error("hmac: can't saveState() because hash doesn't implement it");
        return this._inner.saveState();
    };
    HMAC.prototype.restoreState = function(savedState) {
        if (!hash_1.isSerializableHash(this._inner) || !hash_1.isSerializableHash(this._outer)) throw new Error("hmac: can't restoreState() because hash doesn't implement it");
        this._inner.restoreState(savedState);
        this._outer.restoreState(this._outerKeyedState);
        this._finished = false;
        return this;
    };
    HMAC.prototype.cleanSavedState = function(savedState) {
        if (!hash_1.isSerializableHash(this._inner)) throw new Error("hmac: can't cleanSavedState() because hash doesn't implement it");
        this._inner.cleanSavedState(savedState);
    };
    return HMAC;
}();
exports.HMAC = HMAC1;
/**
 * Returns HMAC using the given hash constructor for the key over data.
 */ function hmac(hash, key, data) {
    var h = new HMAC1(hash, key);
    h.update(data);
    var digest = h.digest();
    h.clean();
    return digest;
}
exports.hmac = hmac;
/**
 * Returns true if two HMAC digests are equal.
 * Uses constant-time comparison to avoid leaking timing information.
 *
 * Example:
 *
 *    const receivedDigest = ...
 *    const realDigest = hmac(SHA256, key, data);
 *    if (!equal(receivedDigest, realDigest)) {
 *        throw new Error("Authentication error");
 *    }
 */ exports.equal = constant_time_1.equal;

},{"@stablelib/hash":"49FYc","@stablelib/constant-time":"3JsQo","@stablelib/wipe":"eWLFw"}],"49FYc":[function(require,module,exports) {
"use strict";
// Copyright (C) 2016 Dmitry Chestnykh
// MIT License. See LICENSE file for details.
Object.defineProperty(exports, "__esModule", {
    value: true
});
function isSerializableHash(h) {
    return typeof h.saveState !== "undefined" && typeof h.restoreState !== "undefined" && typeof h.cleanSavedState !== "undefined";
}
exports.isSerializableHash = isSerializableHash; // TODO(dchest): figure out the standardized interface for XOF such as
 // SHAKE and BLAKE2X.

},{}],"3JsQo":[function(require,module,exports) {
"use strict";
// Copyright (C) 2016 Dmitry Chestnykh
// MIT License. See LICENSE file for details.
Object.defineProperty(exports, "__esModule", {
    value: true
});
/**
 * Package constant-time provides functions for performing algorithmically constant-time operations.
 */ /**
 * NOTE! Due to the inability to guarantee real constant time evaluation of
 * anything in JavaScript VM, this is module is the best effort.
 */ /**
 * Returns resultIfOne if subject is 1, or resultIfZero if subject is 0.
 *
 * Supports only 32-bit integers, so resultIfOne or resultIfZero are not
 * integers, they'll be converted to them with bitwise operations.
 */ function select(subject, resultIfOne, resultIfZero) {
    return ~(subject - 1) & resultIfOne | subject - 1 & resultIfZero;
}
exports.select = select;
/**
 * Returns 1 if a <= b, or 0 if not.
 * Arguments must be positive 32-bit integers less than or equal to 2^31 - 1.
 */ function lessOrEqual(a, b) {
    return (a | 0) - (b | 0) - 1 >>> 31 & 1;
}
exports.lessOrEqual = lessOrEqual;
/**
 * Returns 1 if a and b are of equal length and their contents
 * are equal, or 0 otherwise.
 *
 * Note that unlike in equal(), zero-length inputs are considered
 * the same, so this function will return 1.
 */ function compare(a, b) {
    if (a.length !== b.length) return 0;
    var result = 0;
    for(var i = 0; i < a.length; i++)result |= a[i] ^ b[i];
    return 1 & result - 1 >>> 8;
}
exports.compare = compare;
/**
 * Returns true if a and b are of equal non-zero length,
 * and their contents are equal, or false otherwise.
 *
 * Note that unlike in compare() zero-length inputs are considered
 * _not_ equal, so this function will return false.
 */ function equal(a, b) {
    if (a.length === 0 || b.length === 0) return false;
    return compare(a, b) !== 0;
}
exports.equal = equal;

},{}],"6Moum":[function(require,module,exports) {
"use strict";
// Copyright (C) 2016 Dmitry Chestnykh
// MIT License. See LICENSE file for details.
Object.defineProperty(exports, "__esModule", {
    value: true
});
var binary_1 = require("@stablelib/binary");
var wipe_1 = require("@stablelib/wipe");
exports.DIGEST_LENGTH = 32;
exports.BLOCK_SIZE = 64;
/**
 * SHA2-256 cryptographic hash algorithm.
 */ var SHA2561 = function() {
    function SHA256() {
        /** Length of hash output */ this.digestLength = exports.DIGEST_LENGTH;
        /** Block size */ this.blockSize = exports.BLOCK_SIZE;
        // Note: Int32Array is used instead of Uint32Array for performance reasons.
        this._state = new Int32Array(8); // hash state
        this._temp = new Int32Array(64); // temporary state
        this._buffer = new Uint8Array(128); // buffer for data to hash
        this._bufferLength = 0; // number of bytes in buffer
        this._bytesHashed = 0; // number of total bytes hashed
        this._finished = false; // indicates whether the hash was finalized
        this.reset();
    }
    SHA256.prototype._initState = function() {
        this._state[0] = 1779033703;
        this._state[1] = 3144134277;
        this._state[2] = 1013904242;
        this._state[3] = 2773480762;
        this._state[4] = 1359893119;
        this._state[5] = 2600822924;
        this._state[6] = 528734635;
        this._state[7] = 1541459225;
    };
    /**
     * Resets hash state making it possible
     * to re-use this instance to hash other data.
     */ SHA256.prototype.reset = function() {
        this._initState();
        this._bufferLength = 0;
        this._bytesHashed = 0;
        this._finished = false;
        return this;
    };
    /**
     * Cleans internal buffers and resets hash state.
     */ SHA256.prototype.clean = function() {
        wipe_1.wipe(this._buffer);
        wipe_1.wipe(this._temp);
        this.reset();
    };
    /**
     * Updates hash state with the given data.
     *
     * Throws error when trying to update already finalized hash:
     * instance must be reset to update it again.
     */ SHA256.prototype.update = function(data, dataLength) {
        if (dataLength === void 0) dataLength = data.length;
        if (this._finished) throw new Error("SHA256: can't update because hash was finished.");
        var dataPos = 0;
        this._bytesHashed += dataLength;
        if (this._bufferLength > 0) {
            while(this._bufferLength < this.blockSize && dataLength > 0){
                this._buffer[this._bufferLength++] = data[dataPos++];
                dataLength--;
            }
            if (this._bufferLength === this.blockSize) {
                hashBlocks(this._temp, this._state, this._buffer, 0, this.blockSize);
                this._bufferLength = 0;
            }
        }
        if (dataLength >= this.blockSize) {
            dataPos = hashBlocks(this._temp, this._state, data, dataPos, dataLength);
            dataLength %= this.blockSize;
        }
        while(dataLength > 0){
            this._buffer[this._bufferLength++] = data[dataPos++];
            dataLength--;
        }
        return this;
    };
    /**
     * Finalizes hash state and puts hash into out.
     * If hash was already finalized, puts the same value.
     */ SHA256.prototype.finish = function(out) {
        if (!this._finished) {
            var bytesHashed = this._bytesHashed;
            var left = this._bufferLength;
            var bitLenHi = bytesHashed / 536870912 | 0;
            var bitLenLo = bytesHashed << 3;
            var padLength = bytesHashed % 64 < 56 ? 64 : 128;
            this._buffer[left] = 128;
            for(var i = left + 1; i < padLength - 8; i++)this._buffer[i] = 0;
            binary_1.writeUint32BE(bitLenHi, this._buffer, padLength - 8);
            binary_1.writeUint32BE(bitLenLo, this._buffer, padLength - 4);
            hashBlocks(this._temp, this._state, this._buffer, 0, padLength);
            this._finished = true;
        }
        for(var i = 0; i < this.digestLength / 4; i++)binary_1.writeUint32BE(this._state[i], out, i * 4);
        return this;
    };
    /**
     * Returns the final hash digest.
     */ SHA256.prototype.digest = function() {
        var out = new Uint8Array(this.digestLength);
        this.finish(out);
        return out;
    };
    /**
     * Function useful for HMAC/PBKDF2 optimization.
     * Returns hash state to be used with restoreState().
     * Only chain value is saved, not buffers or other
     * state variables.
     */ SHA256.prototype.saveState = function() {
        if (this._finished) throw new Error("SHA256: cannot save finished state");
        return {
            state: new Int32Array(this._state),
            buffer: this._bufferLength > 0 ? new Uint8Array(this._buffer) : undefined,
            bufferLength: this._bufferLength,
            bytesHashed: this._bytesHashed
        };
    };
    /**
     * Function useful for HMAC/PBKDF2 optimization.
     * Restores state saved by saveState() and sets bytesHashed
     * to the given value.
     */ SHA256.prototype.restoreState = function(savedState) {
        this._state.set(savedState.state);
        this._bufferLength = savedState.bufferLength;
        if (savedState.buffer) this._buffer.set(savedState.buffer);
        this._bytesHashed = savedState.bytesHashed;
        this._finished = false;
        return this;
    };
    /**
     * Cleans state returned by saveState().
     */ SHA256.prototype.cleanSavedState = function(savedState) {
        wipe_1.wipe(savedState.state);
        if (savedState.buffer) wipe_1.wipe(savedState.buffer);
        savedState.bufferLength = 0;
        savedState.bytesHashed = 0;
    };
    return SHA256;
}();
exports.SHA256 = SHA2561;
// Constants
var K = new Int32Array([
    1116352408,
    1899447441,
    3049323471,
    3921009573,
    961987163,
    1508970993,
    2453635748,
    2870763221,
    3624381080,
    310598401,
    607225278,
    1426881987,
    1925078388,
    2162078206,
    2614888103,
    3248222580,
    3835390401,
    4022224774,
    264347078,
    604807628,
    770255983,
    1249150122,
    1555081692,
    1996064986,
    2554220882,
    2821834349,
    2952996808,
    3210313671,
    3336571891,
    3584528711,
    113926993,
    338241895,
    666307205,
    773529912,
    1294757372,
    1396182291,
    1695183700,
    1986661051,
    2177026350,
    2456956037,
    2730485921,
    2820302411,
    3259730800,
    3345764771,
    3516065817,
    3600352804,
    4094571909,
    275423344,
    430227734,
    506948616,
    659060556,
    883997877,
    958139571,
    1322822218,
    1537002063,
    1747873779,
    1955562222,
    2024104815,
    2227730452,
    2361852424,
    2428436474,
    2756734187,
    3204031479,
    3329325298
]);
function hashBlocks(w, v, p, pos, len) {
    while(len >= 64){
        var a = v[0];
        var b = v[1];
        var c = v[2];
        var d = v[3];
        var e = v[4];
        var f = v[5];
        var g = v[6];
        var h = v[7];
        for(var i = 0; i < 16; i++){
            var j = pos + i * 4;
            w[i] = binary_1.readUint32BE(p, j);
        }
        for(var i = 16; i < 64; i++){
            var u = w[i - 2];
            var t1 = (u >>> 17 | u << 15) ^ (u >>> 19 | u << 13) ^ u >>> 10;
            u = w[i - 15];
            var t2 = (u >>> 7 | u << 25) ^ (u >>> 18 | u << 14) ^ u >>> 3;
            w[i] = (t1 + w[i - 7] | 0) + (t2 + w[i - 16] | 0);
        }
        for(var i = 0; i < 64; i++){
            var t1 = (((e >>> 6 | e << 26) ^ (e >>> 11 | e << 21) ^ (e >>> 25 | e << 7)) + (e & f ^ ~e & g) | 0) + (h + (K[i] + w[i] | 0) | 0) | 0;
            var t2 = ((a >>> 2 | a << 30) ^ (a >>> 13 | a << 19) ^ (a >>> 22 | a << 10)) + (a & b ^ a & c ^ b & c) | 0;
            h = g;
            g = f;
            f = e;
            e = d + t1 | 0;
            d = c;
            c = b;
            b = a;
            a = t1 + t2 | 0;
        }
        v[0] += a;
        v[1] += b;
        v[2] += c;
        v[3] += d;
        v[4] += e;
        v[5] += f;
        v[6] += g;
        v[7] += h;
        pos += 64;
        len -= 64;
    }
    return pos;
}
function hash(data) {
    var h = new SHA2561();
    h.update(data);
    var digest = h.digest();
    h.clean();
    return digest;
}
exports.hash = hash;

},{"@stablelib/binary":"jpDs0","@stablelib/wipe":"eWLFw"}],"2BVF8":[function(require,module,exports) {
"use strict";
/*eslint-disable block-scoped-var, id-length, no-control-regex, no-magic-numbers, no-prototype-builtins, no-redeclare, no-shadow, no-var, sort-vars*/ (function(global, factory) {
    /* AMD */ if (typeof define === 'function' && define.amd) define([
        "protobufjs/minimal"
    ], factory);
    else if (typeof require === 'function' && typeof module === 'object' && module && module.exports) module.exports = factory(require("protobufjs/minimal"));
})(this, function($protobuf) {
    "use strict";
    // Common aliases
    var $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util;
    // Exported root namespace
    var $root = $protobuf.roots["libp2p-noise"] || ($protobuf.roots["libp2p-noise"] = {
    });
    $root.pb = (function() {
        /**
         * Namespace pb.
         * @exports pb
         * @namespace
         */ var pb = {
        };
        pb.NoiseHandshakePayload = (function() {
            /**
             * Properties of a NoiseHandshakePayload.
             * @memberof pb
             * @interface INoiseHandshakePayload
             * @property {Uint8Array|null} [identityKey] NoiseHandshakePayload identityKey
             * @property {Uint8Array|null} [identitySig] NoiseHandshakePayload identitySig
             * @property {Uint8Array|null} [data] NoiseHandshakePayload data
             */ /**
             * Constructs a new NoiseHandshakePayload.
             * @memberof pb
             * @classdesc Represents a NoiseHandshakePayload.
             * @implements INoiseHandshakePayload
             * @constructor
             * @param {pb.INoiseHandshakePayload=} [properties] Properties to set
             */ function NoiseHandshakePayload(properties) {
                if (properties) {
                    for(var keys = Object.keys(properties), i = 0; i < keys.length; ++i)if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]];
                }
            }
            /**
             * NoiseHandshakePayload identityKey.
             * @member {Uint8Array} identityKey
             * @memberof pb.NoiseHandshakePayload
             * @instance
             */ NoiseHandshakePayload.prototype.identityKey = $util.newBuffer([]);
            /**
             * NoiseHandshakePayload identitySig.
             * @member {Uint8Array} identitySig
             * @memberof pb.NoiseHandshakePayload
             * @instance
             */ NoiseHandshakePayload.prototype.identitySig = $util.newBuffer([]);
            /**
             * NoiseHandshakePayload data.
             * @member {Uint8Array} data
             * @memberof pb.NoiseHandshakePayload
             * @instance
             */ NoiseHandshakePayload.prototype.data = $util.newBuffer([]);
            /**
             * Creates a new NoiseHandshakePayload instance using the specified properties.
             * @function create
             * @memberof pb.NoiseHandshakePayload
             * @static
             * @param {pb.INoiseHandshakePayload=} [properties] Properties to set
             * @returns {pb.NoiseHandshakePayload} NoiseHandshakePayload instance
             */ NoiseHandshakePayload.create = function create(properties) {
                return new NoiseHandshakePayload(properties);
            };
            /**
             * Encodes the specified NoiseHandshakePayload message. Does not implicitly {@link pb.NoiseHandshakePayload.verify|verify} messages.
             * @function encode
             * @memberof pb.NoiseHandshakePayload
             * @static
             * @param {pb.INoiseHandshakePayload} message NoiseHandshakePayload message or plain object to encode
             * @param {$protobuf.Writer} [writer] Writer to encode to
             * @returns {$protobuf.Writer} Writer
             */ NoiseHandshakePayload.encode = function encode(message, writer) {
                if (!writer) writer = $Writer.create();
                if (message.identityKey != null && Object.hasOwnProperty.call(message, "identityKey")) writer.uint32(/* id 1, wireType 2 =*/ 10).bytes(message.identityKey);
                if (message.identitySig != null && Object.hasOwnProperty.call(message, "identitySig")) writer.uint32(/* id 2, wireType 2 =*/ 18).bytes(message.identitySig);
                if (message.data != null && Object.hasOwnProperty.call(message, "data")) writer.uint32(/* id 3, wireType 2 =*/ 26).bytes(message.data);
                return writer;
            };
            /**
             * Encodes the specified NoiseHandshakePayload message, length delimited. Does not implicitly {@link pb.NoiseHandshakePayload.verify|verify} messages.
             * @function encodeDelimited
             * @memberof pb.NoiseHandshakePayload
             * @static
             * @param {pb.INoiseHandshakePayload} message NoiseHandshakePayload message or plain object to encode
             * @param {$protobuf.Writer} [writer] Writer to encode to
             * @returns {$protobuf.Writer} Writer
             */ NoiseHandshakePayload.encodeDelimited = function encodeDelimited(message, writer) {
                return this.encode(message, writer).ldelim();
            };
            /**
             * Decodes a NoiseHandshakePayload message from the specified reader or buffer.
             * @function decode
             * @memberof pb.NoiseHandshakePayload
             * @static
             * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
             * @param {number} [length] Message length if known beforehand
             * @returns {pb.NoiseHandshakePayload} NoiseHandshakePayload
             * @throws {Error} If the payload is not a reader or valid buffer
             * @throws {$protobuf.util.ProtocolError} If required fields are missing
             */ NoiseHandshakePayload.decode = function decode(reader, length) {
                if (!(reader instanceof $Reader)) reader = $Reader.create(reader);
                var end = length === undefined ? reader.len : reader.pos + length, message = new $root.pb.NoiseHandshakePayload();
                while(reader.pos < end){
                    var tag = reader.uint32();
                    switch(tag >>> 3){
                        case 1:
                            message.identityKey = reader.bytes();
                            break;
                        case 2:
                            message.identitySig = reader.bytes();
                            break;
                        case 3:
                            message.data = reader.bytes();
                            break;
                        default:
                            reader.skipType(tag & 7);
                            break;
                    }
                }
                return message;
            };
            /**
             * Decodes a NoiseHandshakePayload message from the specified reader or buffer, length delimited.
             * @function decodeDelimited
             * @memberof pb.NoiseHandshakePayload
             * @static
             * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
             * @returns {pb.NoiseHandshakePayload} NoiseHandshakePayload
             * @throws {Error} If the payload is not a reader or valid buffer
             * @throws {$protobuf.util.ProtocolError} If required fields are missing
             */ NoiseHandshakePayload.decodeDelimited = function decodeDelimited(reader) {
                if (!(reader instanceof $Reader)) reader = new $Reader(reader);
                return this.decode(reader, reader.uint32());
            };
            /**
             * Verifies a NoiseHandshakePayload message.
             * @function verify
             * @memberof pb.NoiseHandshakePayload
             * @static
             * @param {Object.<string,*>} message Plain object to verify
             * @returns {string|null} `null` if valid, otherwise the reason why it is not
             */ NoiseHandshakePayload.verify = function verify(message) {
                if (typeof message !== "object" || message === null) return "object expected";
                if (message.identityKey != null && message.hasOwnProperty("identityKey")) {
                    if (!(message.identityKey && typeof message.identityKey.length === "number" || $util.isString(message.identityKey))) return "identityKey: buffer expected";
                }
                if (message.identitySig != null && message.hasOwnProperty("identitySig")) {
                    if (!(message.identitySig && typeof message.identitySig.length === "number" || $util.isString(message.identitySig))) return "identitySig: buffer expected";
                }
                if (message.data != null && message.hasOwnProperty("data")) {
                    if (!(message.data && typeof message.data.length === "number" || $util.isString(message.data))) return "data: buffer expected";
                }
                return null;
            };
            /**
             * Creates a NoiseHandshakePayload message from a plain object. Also converts values to their respective internal types.
             * @function fromObject
             * @memberof pb.NoiseHandshakePayload
             * @static
             * @param {Object.<string,*>} object Plain object
             * @returns {pb.NoiseHandshakePayload} NoiseHandshakePayload
             */ NoiseHandshakePayload.fromObject = function fromObject(object) {
                if (object instanceof $root.pb.NoiseHandshakePayload) return object;
                var message = new $root.pb.NoiseHandshakePayload();
                if (object.identityKey != null) {
                    if (typeof object.identityKey === "string") $util.base64.decode(object.identityKey, message.identityKey = $util.newBuffer($util.base64.length(object.identityKey)), 0);
                    else if (object.identityKey.length) message.identityKey = object.identityKey;
                }
                if (object.identitySig != null) {
                    if (typeof object.identitySig === "string") $util.base64.decode(object.identitySig, message.identitySig = $util.newBuffer($util.base64.length(object.identitySig)), 0);
                    else if (object.identitySig.length) message.identitySig = object.identitySig;
                }
                if (object.data != null) {
                    if (typeof object.data === "string") $util.base64.decode(object.data, message.data = $util.newBuffer($util.base64.length(object.data)), 0);
                    else if (object.data.length) message.data = object.data;
                }
                return message;
            };
            /**
             * Creates a plain object from a NoiseHandshakePayload message. Also converts values to other types if specified.
             * @function toObject
             * @memberof pb.NoiseHandshakePayload
             * @static
             * @param {pb.NoiseHandshakePayload} message NoiseHandshakePayload
             * @param {$protobuf.IConversionOptions} [options] Conversion options
             * @returns {Object.<string,*>} Plain object
             */ NoiseHandshakePayload.toObject = function toObject(message, options) {
                if (!options) options = {
                };
                var object = {
                };
                if (options.defaults) {
                    if (options.bytes === String) object.identityKey = "";
                    else {
                        object.identityKey = [];
                        if (options.bytes !== Array) object.identityKey = $util.newBuffer(object.identityKey);
                    }
                    if (options.bytes === String) object.identitySig = "";
                    else {
                        object.identitySig = [];
                        if (options.bytes !== Array) object.identitySig = $util.newBuffer(object.identitySig);
                    }
                    if (options.bytes === String) object.data = "";
                    else {
                        object.data = [];
                        if (options.bytes !== Array) object.data = $util.newBuffer(object.data);
                    }
                }
                if (message.identityKey != null && message.hasOwnProperty("identityKey")) object.identityKey = options.bytes === String ? $util.base64.encode(message.identityKey, 0, message.identityKey.length) : options.bytes === Array ? Array.prototype.slice.call(message.identityKey) : message.identityKey;
                if (message.identitySig != null && message.hasOwnProperty("identitySig")) object.identitySig = options.bytes === String ? $util.base64.encode(message.identitySig, 0, message.identitySig.length) : options.bytes === Array ? Array.prototype.slice.call(message.identitySig) : message.identitySig;
                if (message.data != null && message.hasOwnProperty("data")) object.data = options.bytes === String ? $util.base64.encode(message.data, 0, message.data.length) : options.bytes === Array ? Array.prototype.slice.call(message.data) : message.data;
                return object;
            };
            /**
             * Converts this NoiseHandshakePayload to JSON.
             * @function toJSON
             * @memberof pb.NoiseHandshakePayload
             * @instance
             * @returns {Object.<string,*>} JSON object
             */ NoiseHandshakePayload.prototype.toJSON = function toJSON() {
                return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
            };
            return NoiseHandshakePayload;
        })();
        return pb;
    })();
    return $root;
});

},{"protobufjs/minimal":"9Jmso"}],"5ysQS":[function(require,module,exports) {
"use strict";
var __createBinding = this && this.__createBinding || (Object.create ? function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    Object.defineProperty(o, k2, {
        enumerable: true,
        get: function() {
            return m[k];
        }
    });
} : function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
});
var __setModuleDefault = this && this.__setModuleDefault || (Object.create ? function(o, v) {
    Object.defineProperty(o, "default", {
        enumerable: true,
        value: v
    });
} : function(o, v) {
    o["default"] = v;
});
var __importStar = this && this.__importStar || function(mod) {
    if (mod && mod.__esModule) return mod;
    var result = {
    };
    if (mod != null) {
        for(var k in mod)if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    }
    __setModuleDefault(result, mod);
    return result;
};
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.AbstractHandshake = exports.MIN_NONCE = void 0;
const buffer_1 = require("buffer");
const x25519 = __importStar(require("@stablelib/x25519"));
const SHA256 = __importStar(require("@stablelib/sha256"));
const chacha20poly1305_1 = require("@stablelib/chacha20poly1305");
const utils_1 = require("../utils");
const logger_1 = require("../logger");
exports.MIN_NONCE = 0;
class AbstractHandshake {
    encryptWithAd(cs, ad, plaintext) {
        const e = this.encrypt(cs.k, cs.n, ad, plaintext);
        this.setNonce(cs, this.incrementNonce(cs.n));
        return e;
    }
    decryptWithAd(cs1, ad1, ciphertext) {
        const { plaintext , valid  } = this.decrypt(cs1.k, cs1.n, ad1, ciphertext);
        this.setNonce(cs1, this.incrementNonce(cs1.n));
        return {
            plaintext,
            valid
        };
    }
    // Cipher state related
    hasKey(cs2) {
        return !this.isEmptyKey(cs2.k);
    }
    setNonce(cs3, nonce) {
        cs3.n = nonce;
    }
    createEmptyKey() {
        return buffer_1.Buffer.alloc(32);
    }
    isEmptyKey(k) {
        const emptyKey = this.createEmptyKey();
        return emptyKey.equals(k);
    }
    incrementNonce(n) {
        return n + 1;
    }
    nonceToBytes(n1) {
        const nonce = buffer_1.Buffer.alloc(12);
        nonce.writeUInt32LE(n1, 4);
        return nonce;
    }
    encrypt(k1, n2, ad2, plaintext1) {
        const nonce = this.nonceToBytes(n2);
        const ctx = new chacha20poly1305_1.ChaCha20Poly1305(k1);
        const encryptedMessage = ctx.seal(nonce, plaintext1, ad2);
        return buffer_1.Buffer.from(encryptedMessage.buffer, encryptedMessage.byteOffset, encryptedMessage.length);
    }
    encryptAndHash(ss, plaintext2) {
        let ciphertext;
        if (this.hasKey(ss.cs)) ciphertext = this.encryptWithAd(ss.cs, ss.h, plaintext2);
        else ciphertext = plaintext2;
        this.mixHash(ss, ciphertext);
        return ciphertext;
    }
    decrypt(k2, n3, ad3, ciphertext1) {
        const nonce = this.nonceToBytes(n3);
        const ctx = new chacha20poly1305_1.ChaCha20Poly1305(k2);
        const encryptedMessage = ctx.open(nonce, ciphertext1, ad3);
        if (encryptedMessage) return {
            plaintext: buffer_1.Buffer.from(encryptedMessage.buffer, encryptedMessage.byteOffset, encryptedMessage.length),
            valid: true
        };
        else return {
            plaintext: buffer_1.Buffer.from(''),
            valid: false
        };
    }
    decryptAndHash(ss1, ciphertext2) {
        let plaintext;
        let valid = true;
        if (this.hasKey(ss1.cs)) ({ plaintext , valid  } = this.decryptWithAd(ss1.cs, ss1.h, ciphertext2));
        else plaintext = ciphertext2;
        this.mixHash(ss1, ciphertext2);
        return {
            plaintext,
            valid
        };
    }
    dh(privateKey, publicKey) {
        try {
            const derivedU8 = x25519.sharedKey(privateKey, publicKey);
            const derived = buffer_1.Buffer.from(derivedU8.buffer, derivedU8.byteOffset, derivedU8.length);
            const result = buffer_1.Buffer.alloc(32);
            derived.copy(result);
            return result;
        } catch (e) {
            logger_1.logger(e.message);
            return buffer_1.Buffer.alloc(32);
        }
    }
    mixHash(ss2, data) {
        ss2.h = this.getHash(ss2.h, data);
    }
    getHash(a, b) {
        const hash = SHA256.hash(buffer_1.Buffer.from([
            ...a,
            ...b
        ]));
        return buffer_1.Buffer.from(hash.buffer, hash.byteOffset, hash.length);
    }
    mixKey(ss3, ikm) {
        const [ck, tempK] = utils_1.getHkdf(ss3.ck, ikm);
        ss3.cs = this.initializeKey(tempK);
        ss3.ck = ck;
    }
    initializeKey(k3) {
        const n = exports.MIN_NONCE;
        return {
            k: k3,
            n
        };
    }
    // Symmetric state related
    initializeSymmetric(protocolName) {
        const protocolNameBytes = buffer_1.Buffer.from(protocolName, 'utf-8');
        const h = this.hashProtocolName(protocolNameBytes);
        const ck = h;
        const key = this.createEmptyKey();
        const cs = this.initializeKey(key);
        return {
            cs,
            ck,
            h
        };
    }
    hashProtocolName(protocolName1) {
        if (protocolName1.length <= 32) {
            const h = buffer_1.Buffer.alloc(32);
            protocolName1.copy(h);
            return h;
        } else return this.getHash(protocolName1, buffer_1.Buffer.alloc(0));
    }
    split(ss4) {
        const [tempk1, tempk2] = utils_1.getHkdf(ss4.ck, buffer_1.Buffer.alloc(0));
        const cs1 = this.initializeKey(tempk1);
        const cs2 = this.initializeKey(tempk2);
        return {
            cs1,
            cs2
        };
    }
    writeMessageRegular(cs4, payload) {
        const ciphertext = this.encryptWithAd(cs4, buffer_1.Buffer.alloc(0), payload);
        const ne = this.createEmptyKey();
        const ns = buffer_1.Buffer.alloc(0);
        return {
            ne,
            ns,
            ciphertext
        };
    }
    readMessageRegular(cs5, message) {
        return this.decryptWithAd(cs5, buffer_1.Buffer.alloc(0), message.ciphertext);
    }
}
exports.AbstractHandshake = AbstractHandshake;

},{"buffer":"eKea5","@stablelib/x25519":"f6HJy","@stablelib/sha256":"6Moum","@stablelib/chacha20poly1305":"hZW6W","../utils":"3C9kU","../logger":"hHMfO"}],"hZW6W":[function(require,module,exports) {
"use strict";
// Copyright (C) 2016 Dmitry Chestnykh
// MIT License. See LICENSE file for details.
Object.defineProperty(exports, "__esModule", {
    value: true
});
var chacha_1 = require("@stablelib/chacha");
var poly1305_1 = require("@stablelib/poly1305");
var wipe_1 = require("@stablelib/wipe");
var binary_1 = require("@stablelib/binary");
var constant_time_1 = require("@stablelib/constant-time");
exports.KEY_LENGTH = 32;
exports.NONCE_LENGTH = 12;
exports.TAG_LENGTH = 16;
var ZEROS = new Uint8Array(16);
/**
 * ChaCha20-Poly1305 Authenticated Encryption with Associated Data.
 *
 * Defined in RFC7539.
 */ var ChaCha20Poly13051 = function() {
    /**
     * Creates a new instance with the given 32-byte key.
     */ function ChaCha20Poly1305(key) {
        this.nonceLength = exports.NONCE_LENGTH;
        this.tagLength = exports.TAG_LENGTH;
        if (key.length !== exports.KEY_LENGTH) throw new Error("ChaCha20Poly1305 needs 32-byte key");
        // Copy key.
        this._key = new Uint8Array(key);
    }
    /**
     * Encrypts and authenticates plaintext, authenticates associated data,
     * and returns sealed ciphertext, which includes authentication tag.
     *
     * RFC7539 specifies 12 bytes for nonce. It may be this 12-byte nonce
     * ("IV"), or full 16-byte counter (called "32-bit fixed-common part")
     * and nonce.
     *
     * If dst is given (it must be the size of plaintext + the size of tag
     * length) the result will be put into it. Dst and plaintext must not
     * overlap.
     */ ChaCha20Poly1305.prototype.seal = function(nonce, plaintext, associatedData, dst) {
        if (nonce.length > 16) throw new Error("ChaCha20Poly1305: incorrect nonce length");
        // Allocate space for counter, and set nonce as last bytes of it.
        var counter = new Uint8Array(16);
        counter.set(nonce, counter.length - nonce.length);
        // Generate authentication key by taking first 32-bytes of stream.
        // We pass full counter, which has 12-byte nonce and 4-byte block counter,
        // and it will get incremented after generating the block, which is
        // exactly what we need: we only use the first 32 bytes of 64-byte
        // ChaCha block and discard the next 32 bytes.
        var authKey = new Uint8Array(32);
        chacha_1.stream(this._key, counter, authKey, 4);
        // Allocate space for sealed ciphertext.
        var resultLength = plaintext.length + this.tagLength;
        var result;
        if (dst) {
            if (dst.length !== resultLength) throw new Error("ChaCha20Poly1305: incorrect destination length");
            result = dst;
        } else result = new Uint8Array(resultLength);
        // Encrypt plaintext.
        chacha_1.streamXOR(this._key, counter, plaintext, result, 4);
        // Authenticate.
        // XXX: can "simplify" here: pass full result (which is already padded
        // due to zeroes prepared for tag), and ciphertext length instead of
        // subarray of result.
        this._authenticate(result.subarray(result.length - this.tagLength, result.length), authKey, result.subarray(0, result.length - this.tagLength), associatedData);
        // Cleanup.
        wipe_1.wipe(counter);
        return result;
    };
    /**
     * Authenticates sealed ciphertext (which includes authentication tag) and
     * associated data, decrypts ciphertext and returns decrypted plaintext.
     *
     * RFC7539 specifies 12 bytes for nonce. It may be this 12-byte nonce
     * ("IV"), or full 16-byte counter (called "32-bit fixed-common part")
     * and nonce.
     *
     * If authentication fails, it returns null.
     *
     * If dst is given (it must be of ciphertext length minus tag length),
     * the result will be put into it. Dst and plaintext must not overlap.
     */ ChaCha20Poly1305.prototype.open = function(nonce, sealed, associatedData, dst) {
        if (nonce.length > 16) throw new Error("ChaCha20Poly1305: incorrect nonce length");
        // Sealed ciphertext should at least contain tag.
        if (sealed.length < this.tagLength) // TODO(dchest): should we throw here instead?
        return null;
        // Allocate space for counter, and set nonce as last bytes of it.
        var counter = new Uint8Array(16);
        counter.set(nonce, counter.length - nonce.length);
        // Generate authentication key by taking first 32-bytes of stream.
        var authKey = new Uint8Array(32);
        chacha_1.stream(this._key, counter, authKey, 4);
        // Authenticate.
        // XXX: can simplify and avoid allocation: since authenticate()
        // already allocates tag (from Poly1305.digest(), it can return)
        // it instead of copying to calculatedTag. But then in seal()
        // we'll need to copy it.
        var calculatedTag = new Uint8Array(this.tagLength);
        this._authenticate(calculatedTag, authKey, sealed.subarray(0, sealed.length - this.tagLength), associatedData);
        // Constant-time compare tags and return null if they differ.
        if (!constant_time_1.equal(calculatedTag, sealed.subarray(sealed.length - this.tagLength, sealed.length))) return null;
        // Allocate space for decrypted plaintext.
        var resultLength = sealed.length - this.tagLength;
        var result;
        if (dst) {
            if (dst.length !== resultLength) throw new Error("ChaCha20Poly1305: incorrect destination length");
            result = dst;
        } else result = new Uint8Array(resultLength);
        // Decrypt.
        chacha_1.streamXOR(this._key, counter, sealed.subarray(0, sealed.length - this.tagLength), result, 4);
        // Cleanup.
        wipe_1.wipe(counter);
        return result;
    };
    ChaCha20Poly1305.prototype.clean = function() {
        wipe_1.wipe(this._key);
        return this;
    };
    ChaCha20Poly1305.prototype._authenticate = function(tagOut, authKey, ciphertext, associatedData) {
        // Initialize Poly1305 with authKey.
        var h = new poly1305_1.Poly1305(authKey);
        // Authenticate padded associated data.
        if (associatedData) {
            h.update(associatedData);
            if (associatedData.length % 16 > 0) h.update(ZEROS.subarray(associatedData.length % 16));
        }
        // Authenticate padded ciphertext.
        h.update(ciphertext);
        if (ciphertext.length % 16 > 0) h.update(ZEROS.subarray(ciphertext.length % 16));
        // Authenticate length of associated data.
        // XXX: can avoid allocation here?
        var length = new Uint8Array(8);
        if (associatedData) binary_1.writeUint64LE(associatedData.length, length);
        h.update(length);
        // Authenticate length of ciphertext.
        binary_1.writeUint64LE(ciphertext.length, length);
        h.update(length);
        // Get tag and copy it into tagOut.
        var tag = h.digest();
        for(var i = 0; i < tag.length; i++)tagOut[i] = tag[i];
        // Cleanup.
        h.clean();
        wipe_1.wipe(tag);
        wipe_1.wipe(length);
    };
    return ChaCha20Poly1305;
}();
exports.ChaCha20Poly1305 = ChaCha20Poly13051;

},{"@stablelib/chacha":"gmYtb","@stablelib/poly1305":"dOy7o","@stablelib/wipe":"eWLFw","@stablelib/binary":"jpDs0","@stablelib/constant-time":"3JsQo"}],"gmYtb":[function(require,module,exports) {
"use strict";
// Copyright (C) 2016 Dmitry Chestnykh
// MIT License. See LICENSE file for details.
Object.defineProperty(exports, "__esModule", {
    value: true
});
/**
 * Package chacha implements ChaCha stream cipher.
 */ var binary_1 = require("@stablelib/binary");
var wipe_1 = require("@stablelib/wipe");
// Number of ChaCha rounds (ChaCha20).
var ROUNDS = 20;
// Applies the ChaCha core function to 16-byte input,
// 32-byte key key, and puts the result into 64-byte array out.
function core(out, input, key) {
    var j0 = 1634760805; // "expa"  -- ChaCha's "sigma" constant
    var j1 = 857760878; // "nd 3"     for 32-byte keys
    var j2 = 2036477234; // "2-by"
    var j3 = 1797285236; // "te k"
    var j4 = key[3] << 24 | key[2] << 16 | key[1] << 8 | key[0];
    var j5 = key[7] << 24 | key[6] << 16 | key[5] << 8 | key[4];
    var j6 = key[11] << 24 | key[10] << 16 | key[9] << 8 | key[8];
    var j7 = key[15] << 24 | key[14] << 16 | key[13] << 8 | key[12];
    var j8 = key[19] << 24 | key[18] << 16 | key[17] << 8 | key[16];
    var j9 = key[23] << 24 | key[22] << 16 | key[21] << 8 | key[20];
    var j10 = key[27] << 24 | key[26] << 16 | key[25] << 8 | key[24];
    var j11 = key[31] << 24 | key[30] << 16 | key[29] << 8 | key[28];
    var j12 = input[3] << 24 | input[2] << 16 | input[1] << 8 | input[0];
    var j13 = input[7] << 24 | input[6] << 16 | input[5] << 8 | input[4];
    var j14 = input[11] << 24 | input[10] << 16 | input[9] << 8 | input[8];
    var j15 = input[15] << 24 | input[14] << 16 | input[13] << 8 | input[12];
    var x0 = j0;
    var x1 = j1;
    var x2 = j2;
    var x3 = j3;
    var x4 = j4;
    var x5 = j5;
    var x6 = j6;
    var x7 = j7;
    var x8 = j8;
    var x9 = j9;
    var x10 = j10;
    var x11 = j11;
    var x12 = j12;
    var x13 = j13;
    var x14 = j14;
    var x15 = j15;
    for(var i = 0; i < ROUNDS; i += 2){
        x0 = x0 + x4 | 0;
        x12 ^= x0;
        x12 = x12 >>> 16 | x12 << 16;
        x8 = x8 + x12 | 0;
        x4 ^= x8;
        x4 = x4 >>> 20 | x4 << 12;
        x1 = x1 + x5 | 0;
        x13 ^= x1;
        x13 = x13 >>> 16 | x13 << 16;
        x9 = x9 + x13 | 0;
        x5 ^= x9;
        x5 = x5 >>> 20 | x5 << 12;
        x2 = x2 + x6 | 0;
        x14 ^= x2;
        x14 = x14 >>> 16 | x14 << 16;
        x10 = x10 + x14 | 0;
        x6 ^= x10;
        x6 = x6 >>> 20 | x6 << 12;
        x3 = x3 + x7 | 0;
        x15 ^= x3;
        x15 = x15 >>> 16 | x15 << 16;
        x11 = x11 + x15 | 0;
        x7 ^= x11;
        x7 = x7 >>> 20 | x7 << 12;
        x2 = x2 + x6 | 0;
        x14 ^= x2;
        x14 = x14 >>> 24 | x14 << 8;
        x10 = x10 + x14 | 0;
        x6 ^= x10;
        x6 = x6 >>> 25 | x6 << 7;
        x3 = x3 + x7 | 0;
        x15 ^= x3;
        x15 = x15 >>> 24 | x15 << 8;
        x11 = x11 + x15 | 0;
        x7 ^= x11;
        x7 = x7 >>> 25 | x7 << 7;
        x1 = x1 + x5 | 0;
        x13 ^= x1;
        x13 = x13 >>> 24 | x13 << 8;
        x9 = x9 + x13 | 0;
        x5 ^= x9;
        x5 = x5 >>> 25 | x5 << 7;
        x0 = x0 + x4 | 0;
        x12 ^= x0;
        x12 = x12 >>> 24 | x12 << 8;
        x8 = x8 + x12 | 0;
        x4 ^= x8;
        x4 = x4 >>> 25 | x4 << 7;
        x0 = x0 + x5 | 0;
        x15 ^= x0;
        x15 = x15 >>> 16 | x15 << 16;
        x10 = x10 + x15 | 0;
        x5 ^= x10;
        x5 = x5 >>> 20 | x5 << 12;
        x1 = x1 + x6 | 0;
        x12 ^= x1;
        x12 = x12 >>> 16 | x12 << 16;
        x11 = x11 + x12 | 0;
        x6 ^= x11;
        x6 = x6 >>> 20 | x6 << 12;
        x2 = x2 + x7 | 0;
        x13 ^= x2;
        x13 = x13 >>> 16 | x13 << 16;
        x8 = x8 + x13 | 0;
        x7 ^= x8;
        x7 = x7 >>> 20 | x7 << 12;
        x3 = x3 + x4 | 0;
        x14 ^= x3;
        x14 = x14 >>> 16 | x14 << 16;
        x9 = x9 + x14 | 0;
        x4 ^= x9;
        x4 = x4 >>> 20 | x4 << 12;
        x2 = x2 + x7 | 0;
        x13 ^= x2;
        x13 = x13 >>> 24 | x13 << 8;
        x8 = x8 + x13 | 0;
        x7 ^= x8;
        x7 = x7 >>> 25 | x7 << 7;
        x3 = x3 + x4 | 0;
        x14 ^= x3;
        x14 = x14 >>> 24 | x14 << 8;
        x9 = x9 + x14 | 0;
        x4 ^= x9;
        x4 = x4 >>> 25 | x4 << 7;
        x1 = x1 + x6 | 0;
        x12 ^= x1;
        x12 = x12 >>> 24 | x12 << 8;
        x11 = x11 + x12 | 0;
        x6 ^= x11;
        x6 = x6 >>> 25 | x6 << 7;
        x0 = x0 + x5 | 0;
        x15 ^= x0;
        x15 = x15 >>> 24 | x15 << 8;
        x10 = x10 + x15 | 0;
        x5 ^= x10;
        x5 = x5 >>> 25 | x5 << 7;
    }
    binary_1.writeUint32LE(x0 + j0 | 0, out, 0);
    binary_1.writeUint32LE(x1 + j1 | 0, out, 4);
    binary_1.writeUint32LE(x2 + j2 | 0, out, 8);
    binary_1.writeUint32LE(x3 + j3 | 0, out, 12);
    binary_1.writeUint32LE(x4 + j4 | 0, out, 16);
    binary_1.writeUint32LE(x5 + j5 | 0, out, 20);
    binary_1.writeUint32LE(x6 + j6 | 0, out, 24);
    binary_1.writeUint32LE(x7 + j7 | 0, out, 28);
    binary_1.writeUint32LE(x8 + j8 | 0, out, 32);
    binary_1.writeUint32LE(x9 + j9 | 0, out, 36);
    binary_1.writeUint32LE(x10 + j10 | 0, out, 40);
    binary_1.writeUint32LE(x11 + j11 | 0, out, 44);
    binary_1.writeUint32LE(x12 + j12 | 0, out, 48);
    binary_1.writeUint32LE(x13 + j13 | 0, out, 52);
    binary_1.writeUint32LE(x14 + j14 | 0, out, 56);
    binary_1.writeUint32LE(x15 + j15 | 0, out, 60);
}
/**
 * Encrypt src with ChaCha20 stream generated for the given 32-byte key and
 * 8-byte (as in original implementation) or 12-byte (as in RFC7539) nonce and
 * write the result into dst and return it.
 *
 * dst and src may be the same, but otherwise must not overlap.
 *
 * If nonce is 12 bytes, users should not encrypt more than 256 GiB with the
 * same key and nonce, otherwise the stream will repeat. The function will
 * throw error if counter overflows to prevent this.
 *
 * If nonce is 8 bytes, the output is practically unlimited (2^70 bytes, which
 * is more than a million petabytes). However, it is not recommended to
 * generate 8-byte nonces randomly, as the chance of collision is high.
 *
 * Never use the same key and nonce to encrypt more than one message.
 *
 * If nonceInplaceCounterLength is not 0, the nonce is assumed to be a 16-byte
 * array with stream counter in first nonceInplaceCounterLength bytes and nonce
 * in the last remaining bytes. The counter will be incremented inplace for
 * each ChaCha block. This is useful if you need to encrypt one stream of data
 * in chunks.
 */ function streamXOR(key, nonce, src, dst, nonceInplaceCounterLength) {
    if (nonceInplaceCounterLength === void 0) nonceInplaceCounterLength = 0;
    // We only support 256-bit keys.
    if (key.length !== 32) throw new Error("ChaCha: key size must be 32 bytes");
    if (dst.length < src.length) throw new Error("ChaCha: destination is shorter than source");
    var nc;
    var counterLength;
    if (nonceInplaceCounterLength === 0) {
        if (nonce.length !== 8 && nonce.length !== 12) throw new Error("ChaCha nonce must be 8 or 12 bytes");
        nc = new Uint8Array(16);
        // First counterLength bytes of nc are counter, starting with zero.
        counterLength = nc.length - nonce.length;
        // Last bytes of nc after counterLength are nonce, set them.
        nc.set(nonce, counterLength);
    } else {
        if (nonce.length !== 16) throw new Error("ChaCha nonce with counter must be 16 bytes");
        // This will update passed nonce with counter inplace.
        nc = nonce;
        counterLength = nonceInplaceCounterLength;
    }
    // Allocate temporary space for ChaCha block.
    var block = new Uint8Array(64);
    for(var i = 0; i < src.length; i += 64){
        // Generate a block.
        core(block, nc, key);
        // XOR block bytes with src into dst.
        for(var j = i; j < i + 64 && j < src.length; j++)dst[j] = src[j] ^ block[j - i];
        // Increment counter.
        incrementCounter(nc, 0, counterLength);
    }
    // Cleanup temporary space.
    wipe_1.wipe(block);
    if (nonceInplaceCounterLength === 0) // Cleanup counter.
    wipe_1.wipe(nc);
    return dst;
}
exports.streamXOR = streamXOR;
/**
 * Generate ChaCha20 stream for the given 32-byte key and 8-byte or 12-byte
 * nonce and write it into dst and return it.
 *
 * Never use the same key and nonce to generate more than one stream.
 *
 * If nonceInplaceCounterLength is not 0, it behaves the same with respect to
 * the nonce as described in the streamXOR documentation.
 *
 * stream is like streamXOR with all-zero src.
 */ function stream(key, nonce, dst, nonceInplaceCounterLength) {
    if (nonceInplaceCounterLength === void 0) nonceInplaceCounterLength = 0;
    wipe_1.wipe(dst);
    return streamXOR(key, nonce, dst, dst, nonceInplaceCounterLength);
}
exports.stream = stream;
function incrementCounter(counter, pos, len) {
    var carry = 1;
    while(len--){
        carry = carry + (counter[pos] & 255) | 0;
        counter[pos] = carry & 255;
        carry >>>= 8;
        pos++;
    }
    if (carry > 0) throw new Error("ChaCha: counter overflow");
}

},{"@stablelib/binary":"jpDs0","@stablelib/wipe":"eWLFw"}],"dOy7o":[function(require,module,exports) {
"use strict";
// Copyright (C) 2016 Dmitry Chestnykh
// MIT License. See LICENSE file for details.
Object.defineProperty(exports, "__esModule", {
    value: true
});
/**
 * Package poly1305 implements Poly1305 one-time message authentication algorithm.
 */ var constant_time_1 = require("@stablelib/constant-time");
var wipe_1 = require("@stablelib/wipe");
exports.DIGEST_LENGTH = 16;
// Port of Andrew Moon's Poly1305-donna-16. Public domain.
// https://github.com/floodyberry/poly1305-donna
/**
 * Poly1305 computes 16-byte authenticator of message using
 * a one-time 32-byte key.
 *
 * Important: key should be used for only one message,
 * it should never repeat.
 */ var Poly13051 = function() {
    function Poly1305(key) {
        this.digestLength = exports.DIGEST_LENGTH;
        this._buffer = new Uint8Array(16);
        this._r = new Uint16Array(10);
        this._h = new Uint16Array(10);
        this._pad = new Uint16Array(8);
        this._leftover = 0;
        this._fin = 0;
        this._finished = false;
        var t0 = key[0] | key[1] << 8;
        this._r[0] = t0 & 8191;
        var t1 = key[2] | key[3] << 8;
        this._r[1] = (t0 >>> 13 | t1 << 3) & 8191;
        var t2 = key[4] | key[5] << 8;
        this._r[2] = (t1 >>> 10 | t2 << 6) & 7939;
        var t3 = key[6] | key[7] << 8;
        this._r[3] = (t2 >>> 7 | t3 << 9) & 8191;
        var t4 = key[8] | key[9] << 8;
        this._r[4] = (t3 >>> 4 | t4 << 12) & 255;
        this._r[5] = t4 >>> 1 & 8190;
        var t5 = key[10] | key[11] << 8;
        this._r[6] = (t4 >>> 14 | t5 << 2) & 8191;
        var t6 = key[12] | key[13] << 8;
        this._r[7] = (t5 >>> 11 | t6 << 5) & 8065;
        var t7 = key[14] | key[15] << 8;
        this._r[8] = (t6 >>> 8 | t7 << 8) & 8191;
        this._r[9] = t7 >>> 5 & 127;
        this._pad[0] = key[16] | key[17] << 8;
        this._pad[1] = key[18] | key[19] << 8;
        this._pad[2] = key[20] | key[21] << 8;
        this._pad[3] = key[22] | key[23] << 8;
        this._pad[4] = key[24] | key[25] << 8;
        this._pad[5] = key[26] | key[27] << 8;
        this._pad[6] = key[28] | key[29] << 8;
        this._pad[7] = key[30] | key[31] << 8;
    }
    Poly1305.prototype._blocks = function(m, mpos, bytes) {
        var hibit = this._fin ? 0 : 2048;
        var h0 = this._h[0], h1 = this._h[1], h2 = this._h[2], h3 = this._h[3], h4 = this._h[4], h5 = this._h[5], h6 = this._h[6], h7 = this._h[7], h8 = this._h[8], h9 = this._h[9];
        var r0 = this._r[0], r1 = this._r[1], r2 = this._r[2], r3 = this._r[3], r4 = this._r[4], r5 = this._r[5], r6 = this._r[6], r7 = this._r[7], r8 = this._r[8], r9 = this._r[9];
        while(bytes >= 16){
            var t0 = m[mpos + 0] | m[mpos + 1] << 8;
            h0 += t0 & 8191;
            var t1 = m[mpos + 2] | m[mpos + 3] << 8;
            h1 += (t0 >>> 13 | t1 << 3) & 8191;
            var t2 = m[mpos + 4] | m[mpos + 5] << 8;
            h2 += (t1 >>> 10 | t2 << 6) & 8191;
            var t3 = m[mpos + 6] | m[mpos + 7] << 8;
            h3 += (t2 >>> 7 | t3 << 9) & 8191;
            var t4 = m[mpos + 8] | m[mpos + 9] << 8;
            h4 += (t3 >>> 4 | t4 << 12) & 8191;
            h5 += t4 >>> 1 & 8191;
            var t5 = m[mpos + 10] | m[mpos + 11] << 8;
            h6 += (t4 >>> 14 | t5 << 2) & 8191;
            var t6 = m[mpos + 12] | m[mpos + 13] << 8;
            h7 += (t5 >>> 11 | t6 << 5) & 8191;
            var t7 = m[mpos + 14] | m[mpos + 15] << 8;
            h8 += (t6 >>> 8 | t7 << 8) & 8191;
            h9 += t7 >>> 5 | hibit;
            var c = 0;
            var d0 = c;
            d0 += h0 * r0;
            d0 += h1 * (5 * r9);
            d0 += h2 * (5 * r8);
            d0 += h3 * (5 * r7);
            d0 += h4 * (5 * r6);
            c = d0 >>> 13;
            d0 &= 8191;
            d0 += h5 * (5 * r5);
            d0 += h6 * (5 * r4);
            d0 += h7 * (5 * r3);
            d0 += h8 * (5 * r2);
            d0 += h9 * (5 * r1);
            c += d0 >>> 13;
            d0 &= 8191;
            var d1 = c;
            d1 += h0 * r1;
            d1 += h1 * r0;
            d1 += h2 * (5 * r9);
            d1 += h3 * (5 * r8);
            d1 += h4 * (5 * r7);
            c = d1 >>> 13;
            d1 &= 8191;
            d1 += h5 * (5 * r6);
            d1 += h6 * (5 * r5);
            d1 += h7 * (5 * r4);
            d1 += h8 * (5 * r3);
            d1 += h9 * (5 * r2);
            c += d1 >>> 13;
            d1 &= 8191;
            var d2 = c;
            d2 += h0 * r2;
            d2 += h1 * r1;
            d2 += h2 * r0;
            d2 += h3 * (5 * r9);
            d2 += h4 * (5 * r8);
            c = d2 >>> 13;
            d2 &= 8191;
            d2 += h5 * (5 * r7);
            d2 += h6 * (5 * r6);
            d2 += h7 * (5 * r5);
            d2 += h8 * (5 * r4);
            d2 += h9 * (5 * r3);
            c += d2 >>> 13;
            d2 &= 8191;
            var d3 = c;
            d3 += h0 * r3;
            d3 += h1 * r2;
            d3 += h2 * r1;
            d3 += h3 * r0;
            d3 += h4 * (5 * r9);
            c = d3 >>> 13;
            d3 &= 8191;
            d3 += h5 * (5 * r8);
            d3 += h6 * (5 * r7);
            d3 += h7 * (5 * r6);
            d3 += h8 * (5 * r5);
            d3 += h9 * (5 * r4);
            c += d3 >>> 13;
            d3 &= 8191;
            var d4 = c;
            d4 += h0 * r4;
            d4 += h1 * r3;
            d4 += h2 * r2;
            d4 += h3 * r1;
            d4 += h4 * r0;
            c = d4 >>> 13;
            d4 &= 8191;
            d4 += h5 * (5 * r9);
            d4 += h6 * (5 * r8);
            d4 += h7 * (5 * r7);
            d4 += h8 * (5 * r6);
            d4 += h9 * (5 * r5);
            c += d4 >>> 13;
            d4 &= 8191;
            var d5 = c;
            d5 += h0 * r5;
            d5 += h1 * r4;
            d5 += h2 * r3;
            d5 += h3 * r2;
            d5 += h4 * r1;
            c = d5 >>> 13;
            d5 &= 8191;
            d5 += h5 * r0;
            d5 += h6 * (5 * r9);
            d5 += h7 * (5 * r8);
            d5 += h8 * (5 * r7);
            d5 += h9 * (5 * r6);
            c += d5 >>> 13;
            d5 &= 8191;
            var d6 = c;
            d6 += h0 * r6;
            d6 += h1 * r5;
            d6 += h2 * r4;
            d6 += h3 * r3;
            d6 += h4 * r2;
            c = d6 >>> 13;
            d6 &= 8191;
            d6 += h5 * r1;
            d6 += h6 * r0;
            d6 += h7 * (5 * r9);
            d6 += h8 * (5 * r8);
            d6 += h9 * (5 * r7);
            c += d6 >>> 13;
            d6 &= 8191;
            var d7 = c;
            d7 += h0 * r7;
            d7 += h1 * r6;
            d7 += h2 * r5;
            d7 += h3 * r4;
            d7 += h4 * r3;
            c = d7 >>> 13;
            d7 &= 8191;
            d7 += h5 * r2;
            d7 += h6 * r1;
            d7 += h7 * r0;
            d7 += h8 * (5 * r9);
            d7 += h9 * (5 * r8);
            c += d7 >>> 13;
            d7 &= 8191;
            var d8 = c;
            d8 += h0 * r8;
            d8 += h1 * r7;
            d8 += h2 * r6;
            d8 += h3 * r5;
            d8 += h4 * r4;
            c = d8 >>> 13;
            d8 &= 8191;
            d8 += h5 * r3;
            d8 += h6 * r2;
            d8 += h7 * r1;
            d8 += h8 * r0;
            d8 += h9 * (5 * r9);
            c += d8 >>> 13;
            d8 &= 8191;
            var d9 = c;
            d9 += h0 * r9;
            d9 += h1 * r8;
            d9 += h2 * r7;
            d9 += h3 * r6;
            d9 += h4 * r5;
            c = d9 >>> 13;
            d9 &= 8191;
            d9 += h5 * r4;
            d9 += h6 * r3;
            d9 += h7 * r2;
            d9 += h8 * r1;
            d9 += h9 * r0;
            c += d9 >>> 13;
            d9 &= 8191;
            c = (c << 2) + c | 0;
            c = c + d0 | 0;
            d0 = c & 8191;
            c = c >>> 13;
            d1 += c;
            h0 = d0;
            h1 = d1;
            h2 = d2;
            h3 = d3;
            h4 = d4;
            h5 = d5;
            h6 = d6;
            h7 = d7;
            h8 = d8;
            h9 = d9;
            mpos += 16;
            bytes -= 16;
        }
        this._h[0] = h0;
        this._h[1] = h1;
        this._h[2] = h2;
        this._h[3] = h3;
        this._h[4] = h4;
        this._h[5] = h5;
        this._h[6] = h6;
        this._h[7] = h7;
        this._h[8] = h8;
        this._h[9] = h9;
    };
    Poly1305.prototype.finish = function(mac, macpos) {
        if (macpos === void 0) macpos = 0;
        var g = new Uint16Array(10);
        var c;
        var mask;
        var f;
        var i;
        if (this._leftover) {
            i = this._leftover;
            this._buffer[i++] = 1;
            for(; i < 16; i++)this._buffer[i] = 0;
            this._fin = 1;
            this._blocks(this._buffer, 0, 16);
        }
        c = this._h[1] >>> 13;
        this._h[1] &= 8191;
        for(i = 2; i < 10; i++){
            this._h[i] += c;
            c = this._h[i] >>> 13;
            this._h[i] &= 8191;
        }
        this._h[0] += c * 5;
        c = this._h[0] >>> 13;
        this._h[0] &= 8191;
        this._h[1] += c;
        c = this._h[1] >>> 13;
        this._h[1] &= 8191;
        this._h[2] += c;
        g[0] = this._h[0] + 5;
        c = g[0] >>> 13;
        g[0] &= 8191;
        for(i = 1; i < 10; i++){
            g[i] = this._h[i] + c;
            c = g[i] >>> 13;
            g[i] &= 8191;
        }
        g[9] -= 8192;
        mask = (c ^ 1) - 1;
        for(i = 0; i < 10; i++)g[i] &= mask;
        mask = ~mask;
        for(i = 0; i < 10; i++)this._h[i] = this._h[i] & mask | g[i];
        this._h[0] = (this._h[0] | this._h[1] << 13) & 65535;
        this._h[1] = (this._h[1] >>> 3 | this._h[2] << 10) & 65535;
        this._h[2] = (this._h[2] >>> 6 | this._h[3] << 7) & 65535;
        this._h[3] = (this._h[3] >>> 9 | this._h[4] << 4) & 65535;
        this._h[4] = (this._h[4] >>> 12 | this._h[5] << 1 | this._h[6] << 14) & 65535;
        this._h[5] = (this._h[6] >>> 2 | this._h[7] << 11) & 65535;
        this._h[6] = (this._h[7] >>> 5 | this._h[8] << 8) & 65535;
        this._h[7] = (this._h[8] >>> 8 | this._h[9] << 5) & 65535;
        f = this._h[0] + this._pad[0];
        this._h[0] = f & 65535;
        for(i = 1; i < 8; i++){
            f = (this._h[i] + this._pad[i] | 0) + (f >>> 16) | 0;
            this._h[i] = f & 65535;
        }
        mac[macpos + 0] = this._h[0] >>> 0;
        mac[macpos + 1] = this._h[0] >>> 8;
        mac[macpos + 2] = this._h[1] >>> 0;
        mac[macpos + 3] = this._h[1] >>> 8;
        mac[macpos + 4] = this._h[2] >>> 0;
        mac[macpos + 5] = this._h[2] >>> 8;
        mac[macpos + 6] = this._h[3] >>> 0;
        mac[macpos + 7] = this._h[3] >>> 8;
        mac[macpos + 8] = this._h[4] >>> 0;
        mac[macpos + 9] = this._h[4] >>> 8;
        mac[macpos + 10] = this._h[5] >>> 0;
        mac[macpos + 11] = this._h[5] >>> 8;
        mac[macpos + 12] = this._h[6] >>> 0;
        mac[macpos + 13] = this._h[6] >>> 8;
        mac[macpos + 14] = this._h[7] >>> 0;
        mac[macpos + 15] = this._h[7] >>> 8;
        this._finished = true;
        return this;
    };
    Poly1305.prototype.update = function(m) {
        var mpos = 0;
        var bytes = m.length;
        var want;
        if (this._leftover) {
            want = 16 - this._leftover;
            if (want > bytes) want = bytes;
            for(var i = 0; i < want; i++)this._buffer[this._leftover + i] = m[mpos + i];
            bytes -= want;
            mpos += want;
            this._leftover += want;
            if (this._leftover < 16) return this;
            this._blocks(this._buffer, 0, 16);
            this._leftover = 0;
        }
        if (bytes >= 16) {
            want = bytes - bytes % 16;
            this._blocks(m, mpos, want);
            mpos += want;
            bytes -= want;
        }
        if (bytes) {
            for(var i = 0; i < bytes; i++)this._buffer[this._leftover + i] = m[mpos + i];
            this._leftover += bytes;
        }
        return this;
    };
    Poly1305.prototype.digest = function() {
        // TODO(dchest): it behaves differently than other hashes/HMAC,
        // because it throws when finished — others just return saved result.
        if (this._finished) throw new Error("Poly1305 was finished");
        var mac = new Uint8Array(16);
        this.finish(mac);
        return mac;
    };
    Poly1305.prototype.clean = function() {
        wipe_1.wipe(this._buffer);
        wipe_1.wipe(this._r);
        wipe_1.wipe(this._h);
        wipe_1.wipe(this._pad);
        this._leftover = 0;
        this._fin = 0;
        this._finished = true; // mark as finished even if not
        return this;
    };
    return Poly1305;
}();
exports.Poly1305 = Poly13051;
/**
 * Returns 16-byte authenticator of data using a one-time 32-byte key.
 *
 * Important: key should be used for only one message, it should never repeat.
 */ function oneTimeAuth(key, data) {
    var h = new Poly13051(key);
    h.update(data);
    var digest = h.digest();
    h.clean();
    return digest;
}
exports.oneTimeAuth = oneTimeAuth;
/**
 * Returns true if two authenticators are 16-byte long and equal.
 * Uses contant-time comparison to avoid leaking timing information.
 */ function equal(a, b) {
    if (a.length !== exports.DIGEST_LENGTH || b.length !== exports.DIGEST_LENGTH) return false;
    return constant_time_1.equal(a, b);
}
exports.equal = equal;

},{"@stablelib/constant-time":"3JsQo","@stablelib/wipe":"eWLFw"}],"hHMfO":[function(require,module,exports) {
"use strict";
var __importDefault = this && this.__importDefault || function(mod) {
    return mod && mod.__esModule ? mod : {
        "default": mod
    };
};
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.logCipherState = exports.logRemoteEphemeralKey = exports.logRemoteStaticKey = exports.logLocalEphemeralKeys = exports.logLocalStaticKeys = exports.logger = void 0;
const debug_1 = __importDefault(require("debug"));
const constants_1 = require("./constants");
exports.logger = debug_1.default('libp2p:noise');
let keyLogger;
if (constants_1.DUMP_SESSION_KEYS) keyLogger = exports.logger;
else keyLogger = ()=>{
};
function logLocalStaticKeys(s) {
    keyLogger(`LOCAL_STATIC_PUBLIC_KEY ${s.publicKey.toString('hex')}`);
    keyLogger(`LOCAL_STATIC_PRIVATE_KEY ${s.privateKey.toString('hex')}`);
}
exports.logLocalStaticKeys = logLocalStaticKeys;
function logLocalEphemeralKeys(e) {
    if (e) {
        keyLogger(`LOCAL_PUBLIC_EPHEMERAL_KEY ${e.publicKey.toString('hex')}`);
        keyLogger(`LOCAL_PRIVATE_EPHEMERAL_KEY ${e.privateKey.toString('hex')}`);
    } else keyLogger('Missing local ephemeral keys.');
}
exports.logLocalEphemeralKeys = logLocalEphemeralKeys;
function logRemoteStaticKey(rs) {
    keyLogger(`REMOTE_STATIC_PUBLIC_KEY ${rs.toString('hex')}`);
}
exports.logRemoteStaticKey = logRemoteStaticKey;
function logRemoteEphemeralKey(re) {
    keyLogger(`REMOTE_EPHEMERAL_PUBLIC_KEY ${re.toString('hex')}`);
}
exports.logRemoteEphemeralKey = logRemoteEphemeralKey;
function logCipherState(session) {
    if (session.cs1 && session.cs2) {
        keyLogger(`CIPHER_STATE_1 ${session.cs1.n} ${session.cs1.k.toString('hex')}`);
        keyLogger(`CIPHER_STATE_2 ${session.cs2.n} ${session.cs2.k.toString('hex')}`);
    } else keyLogger('Missing cipher state.');
}
exports.logCipherState = logCipherState;

},{"debug":"lWlU4","./constants":"3FbHN"}],"3FbHN":[function(require,module,exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.DUMP_SESSION_KEYS = exports.NOISE_MSG_MAX_LENGTH_BYTES_WITHOUT_TAG = exports.NOISE_MSG_MAX_LENGTH_BYTES = void 0;
exports.NOISE_MSG_MAX_LENGTH_BYTES = 65535;
exports.NOISE_MSG_MAX_LENGTH_BYTES_WITHOUT_TAG = exports.NOISE_MSG_MAX_LENGTH_BYTES - 16;
exports.DUMP_SESSION_KEYS = undefined;

},{}],"fw0Lz":[function(require,module,exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.decode2 = exports.decode1 = exports.decode0 = exports.encode2 = exports.encode1 = exports.encode0 = exports.uint16BEDecode = exports.uint16BEEncode = void 0;
const buffer_1 = require("buffer");
const uint16BEEncode = (value, target, offset)=>{
    target = target || buffer_1.Buffer.allocUnsafe(2);
    target.writeUInt16BE(value, offset);
    return target;
};
exports.uint16BEEncode = uint16BEEncode;
exports.uint16BEEncode.bytes = 2;
const uint16BEDecode = (data)=>{
    if (data.length < 2) throw RangeError('Could not decode int16BE');
    return data.readUInt16BE(0);
};
exports.uint16BEDecode = uint16BEDecode;
exports.uint16BEDecode.bytes = 2;
// Note: IK and XX encoder usage is opposite (XX uses in stages encode0 where IK uses encode1)
function encode0(message) {
    return buffer_1.Buffer.concat([
        message.ne,
        message.ciphertext
    ]);
}
exports.encode0 = encode0;
function encode1(message) {
    return buffer_1.Buffer.concat([
        message.ne,
        message.ns,
        message.ciphertext
    ]);
}
exports.encode1 = encode1;
function encode2(message) {
    return buffer_1.Buffer.concat([
        message.ns,
        message.ciphertext
    ]);
}
exports.encode2 = encode2;
function decode0(input) {
    if (input.length < 32) throw new Error('Cannot decode stage 0 MessageBuffer: length less than 32 bytes.');
    return {
        ne: input.slice(0, 32),
        ciphertext: input.slice(32, input.length),
        ns: buffer_1.Buffer.alloc(0)
    };
}
exports.decode0 = decode0;
function decode1(input) {
    if (input.length < 80) throw new Error('Cannot decode stage 1 MessageBuffer: length less than 80 bytes.');
    return {
        ne: input.slice(0, 32),
        ns: input.slice(32, 80),
        ciphertext: input.slice(80, input.length)
    };
}
exports.decode1 = decode1;
function decode2(input) {
    if (input.length < 48) throw new Error('Cannot decode stage 2 MessageBuffer: length less than 48 bytes.');
    return {
        ne: buffer_1.Buffer.alloc(0),
        ns: input.slice(0, 48),
        ciphertext: input.slice(48, input.length)
    };
}
exports.decode2 = decode2;

},{"buffer":"eKea5"}],"2Xb7e":[function(require,module,exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.IKHandshake = void 0;
const ik_1 = require("./handshakes/ik");
const buffer_1 = require("buffer");
const encoder_1 = require("./encoder");
const utils_1 = require("./utils");
const errors_1 = require("./errors");
const logger_1 = require("./logger");
class IKHandshake {
    constructor(isInitiator, payload, prologue, staticKeypair, connection, remoteStaticKey, remotePeer, handshake){
        this.isInitiator = isInitiator;
        this.payload = buffer_1.Buffer.from(payload);
        this.prologue = prologue;
        this.staticKeypair = staticKeypair;
        this.connection = connection;
        if (remotePeer) this.remotePeer = remotePeer;
        this.ik = handshake !== null && handshake !== void 0 ? handshake : new ik_1.IK();
        this.session = this.ik.initSession(this.isInitiator, this.prologue, this.staticKeypair, remoteStaticKey);
        this.remoteEarlyData = buffer_1.Buffer.alloc(0);
    }
    async stage0() {
        logger_1.logLocalStaticKeys(this.session.hs.s);
        logger_1.logRemoteStaticKey(this.session.hs.rs);
        if (this.isInitiator) {
            logger_1.logger('IK Stage 0 - Initiator sending message...');
            const messageBuffer = this.ik.sendMessage(this.session, this.payload);
            this.connection.writeLP(encoder_1.encode1(messageBuffer));
            logger_1.logger('IK Stage 0 - Initiator sent message.');
            logger_1.logLocalEphemeralKeys(this.session.hs.e);
        } else {
            logger_1.logger('IK Stage 0 - Responder receiving message...');
            const receivedMsg = await this.connection.readLP();
            try {
                const receivedMessageBuffer = encoder_1.decode1(receivedMsg.slice());
                const { plaintext , valid  } = this.ik.recvMessage(this.session, receivedMessageBuffer);
                if (!valid) throw new Error('ik handshake stage 0 decryption validation fail');
                logger_1.logger('IK Stage 0 - Responder got message, going to verify payload.');
                const decodedPayload = await utils_1.decodePayload(plaintext);
                this.remotePeer = this.remotePeer || await utils_1.getPeerIdFromPayload(decodedPayload);
                await utils_1.verifySignedPayload(this.session.hs.rs, decodedPayload, this.remotePeer);
                this.setRemoteEarlyData(decodedPayload.data);
                logger_1.logger('IK Stage 0 - Responder successfully verified payload!');
                logger_1.logRemoteEphemeralKey(this.session.hs.re);
            } catch (e) {
                const err = e;
                logger_1.logger('Responder breaking up with IK handshake in stage 0.');
                throw new errors_1.FailedIKError(receivedMsg, `Error occurred while verifying initiator's signed payload: ${err.message}`);
            }
        }
    }
    async stage1() {
        if (this.isInitiator) {
            logger_1.logger('IK Stage 1 - Initiator receiving message...');
            const receivedMsg = (await this.connection.readLP()).slice();
            const receivedMessageBuffer = encoder_1.decode0(buffer_1.Buffer.from(receivedMsg));
            const { plaintext , valid  } = this.ik.recvMessage(this.session, receivedMessageBuffer);
            logger_1.logger('IK Stage 1 - Initiator got message, going to verify payload.');
            try {
                if (!valid) throw new Error('ik stage 1 decryption validation fail');
                const decodedPayload = await utils_1.decodePayload(plaintext);
                this.remotePeer = this.remotePeer || await utils_1.getPeerIdFromPayload(decodedPayload);
                await utils_1.verifySignedPayload(receivedMessageBuffer.ns.slice(0, 32), decodedPayload, this.remotePeer);
                this.setRemoteEarlyData(decodedPayload.data);
                logger_1.logger('IK Stage 1 - Initiator successfully verified payload!');
                logger_1.logRemoteEphemeralKey(this.session.hs.re);
            } catch (e) {
                const err = e;
                logger_1.logger('Initiator breaking up with IK handshake in stage 1.');
                throw new errors_1.FailedIKError(receivedMsg, `Error occurred while verifying responder's signed payload: ${err.message}`);
            }
        } else {
            logger_1.logger('IK Stage 1 - Responder sending message...');
            const messageBuffer = this.ik.sendMessage(this.session, this.payload);
            this.connection.writeLP(encoder_1.encode0(messageBuffer));
            logger_1.logger('IK Stage 1 - Responder sent message...');
            logger_1.logLocalEphemeralKeys(this.session.hs.e);
        }
        logger_1.logCipherState(this.session);
    }
    decrypt(ciphertext, session) {
        const cs = this.getCS(session, false);
        return this.ik.decryptWithAd(cs, buffer_1.Buffer.alloc(0), ciphertext);
    }
    encrypt(plaintext, session1) {
        const cs = this.getCS(session1);
        return this.ik.encryptWithAd(cs, buffer_1.Buffer.alloc(0), plaintext);
    }
    getLocalEphemeralKeys() {
        if (!this.session.hs.e) throw new Error('Ephemeral keys do not exist.');
        return this.session.hs.e;
    }
    getCS(session2, encryption = true) {
        if (!session2.cs1 || !session2.cs2) throw new Error('Handshake not completed properly, cipher state does not exist.');
        if (this.isInitiator) return encryption ? session2.cs1 : session2.cs2;
        else return encryption ? session2.cs2 : session2.cs1;
    }
    setRemoteEarlyData(data) {
        if (data) this.remoteEarlyData = buffer_1.Buffer.from(data.buffer, data.byteOffset, data.length);
    }
}
exports.IKHandshake = IKHandshake;

},{"./handshakes/ik":"37c56","buffer":"eKea5","./encoder":"fw0Lz","./utils":"3C9kU","./errors":"7fCtW","./logger":"hHMfO"}],"37c56":[function(require,module,exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.IK = void 0;
const buffer_1 = require("buffer");
const utils_1 = require("../utils");
const abstract_handshake_1 = require("./abstract-handshake");
class IK extends abstract_handshake_1.AbstractHandshake {
    initSession(initiator, prologue, s, rs) {
        const psk = this.createEmptyKey();
        let hs;
        if (initiator) hs = this.initializeInitiator(prologue, s, rs, psk);
        else hs = this.initializeResponder(prologue, s, rs, psk);
        return {
            hs,
            i: initiator,
            mc: 0
        };
    }
    sendMessage(session, message) {
        let messageBuffer;
        if (session.mc === 0) messageBuffer = this.writeMessageA(session.hs, message);
        else if (session.mc === 1) {
            const { messageBuffer: mb , h , cs1 , cs2  } = this.writeMessageB(session.hs, message);
            messageBuffer = mb;
            session.h = h;
            session.cs1 = cs1;
            session.cs2 = cs2;
        } else if (session.mc > 1) {
            if (session.i) {
                if (!session.cs1) throw new Error('CS1 (cipher state) is not defined');
                messageBuffer = this.writeMessageRegular(session.cs1, message);
            } else {
                if (!session.cs2) throw new Error('CS2 (cipher state) is not defined');
                messageBuffer = this.writeMessageRegular(session.cs2, message);
            }
        } else throw new Error('Session invalid.');
        session.mc++;
        return messageBuffer;
    }
    recvMessage(session1, message1) {
        let plaintext = buffer_1.Buffer.alloc(0);
        let valid = false;
        if (session1.mc === 0) ({ plaintext , valid  } = this.readMessageA(session1.hs, message1));
        if (session1.mc === 1) {
            const { plaintext: pt , valid: v , h , cs1 , cs2  } = this.readMessageB(session1.hs, message1);
            plaintext = pt;
            valid = v;
            session1.h = h;
            session1.cs1 = cs1;
            session1.cs2 = cs2;
        }
        session1.mc++;
        return {
            plaintext,
            valid
        };
    }
    writeMessageA(hs, payload) {
        hs.e = utils_1.generateKeypair();
        const ne = hs.e.publicKey;
        this.mixHash(hs.ss, ne);
        this.mixKey(hs.ss, this.dh(hs.e.privateKey, hs.rs));
        const spk = buffer_1.Buffer.from(hs.s.publicKey);
        const ns = this.encryptAndHash(hs.ss, spk);
        this.mixKey(hs.ss, this.dh(hs.s.privateKey, hs.rs));
        const ciphertext = this.encryptAndHash(hs.ss, payload);
        return {
            ne,
            ns,
            ciphertext
        };
    }
    writeMessageB(hs1, payload1) {
        hs1.e = utils_1.generateKeypair();
        const ne = hs1.e.publicKey;
        this.mixHash(hs1.ss, ne);
        this.mixKey(hs1.ss, this.dh(hs1.e.privateKey, hs1.re));
        this.mixKey(hs1.ss, this.dh(hs1.e.privateKey, hs1.rs));
        const ciphertext = this.encryptAndHash(hs1.ss, payload1);
        const ns = this.createEmptyKey();
        const messageBuffer = {
            ne,
            ns,
            ciphertext
        };
        const { cs1 , cs2  } = this.split(hs1.ss);
        return {
            messageBuffer,
            cs1,
            cs2,
            h: hs1.ss.h
        };
    }
    readMessageA(hs2, message2) {
        if (utils_1.isValidPublicKey(message2.ne)) hs2.re = message2.ne;
        this.mixHash(hs2.ss, hs2.re);
        this.mixKey(hs2.ss, this.dh(hs2.s.privateKey, hs2.re));
        const { plaintext: ns , valid: valid1  } = this.decryptAndHash(hs2.ss, message2.ns);
        if (valid1 && ns.length === 32 && utils_1.isValidPublicKey(ns)) hs2.rs = ns;
        this.mixKey(hs2.ss, this.dh(hs2.s.privateKey, hs2.rs));
        const { plaintext , valid: valid2  } = this.decryptAndHash(hs2.ss, message2.ciphertext);
        return {
            plaintext,
            valid: valid1 && valid2
        };
    }
    readMessageB(hs3, message3) {
        if (utils_1.isValidPublicKey(message3.ne)) hs3.re = message3.ne;
        this.mixHash(hs3.ss, hs3.re);
        if (!hs3.e) throw new Error('Handshake state should contain ephemeral key by now.');
        this.mixKey(hs3.ss, this.dh(hs3.e.privateKey, hs3.re));
        this.mixKey(hs3.ss, this.dh(hs3.s.privateKey, hs3.re));
        const { plaintext , valid  } = this.decryptAndHash(hs3.ss, message3.ciphertext);
        const { cs1 , cs2  } = this.split(hs3.ss);
        return {
            h: hs3.ss.h,
            valid,
            plaintext,
            cs1,
            cs2
        };
    }
    initializeInitiator(prologue1, s1, rs1, psk) {
        const name = 'Noise_IK_25519_ChaChaPoly_SHA256';
        const ss = this.initializeSymmetric(name);
        this.mixHash(ss, prologue1);
        this.mixHash(ss, rs1);
        const re = buffer_1.Buffer.alloc(32);
        return {
            ss,
            s: s1,
            rs: rs1,
            re,
            psk
        };
    }
    initializeResponder(prologue2, s2, rs2, psk1) {
        const name = 'Noise_IK_25519_ChaChaPoly_SHA256';
        const ss = this.initializeSymmetric(name);
        this.mixHash(ss, prologue2);
        this.mixHash(ss, s2.publicKey);
        const re = buffer_1.Buffer.alloc(32);
        return {
            ss,
            s: s2,
            rs: rs2,
            re,
            psk: psk1
        };
    }
}
exports.IK = IK;

},{"buffer":"eKea5","../utils":"3C9kU","./abstract-handshake":"5ysQS"}],"7fCtW":[function(require,module,exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.FailedIKError = void 0;
class FailedIKError extends Error {
    constructor(initialMsg, message){
        super(message);
        this.initialMsg = initialMsg;
        this.name = 'FailedIKhandshake';
    }
}
exports.FailedIKError = FailedIKError;

},{}],"lKp03":[function(require,module,exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.XXFallbackHandshake = void 0;
const buffer_1 = require("buffer");
const handshake_xx_1 = require("./handshake-xx");
const utils_1 = require("./utils");
const logger_1 = require("./logger");
const encoder_1 = require("./encoder");
class XXFallbackHandshake extends handshake_xx_1.XXHandshake {
    constructor(isInitiator, payload, prologue, staticKeypair, connection, initialMsg, remotePeer, ephemeralKeys, handshake){
        super(isInitiator, payload, prologue, staticKeypair, connection, remotePeer, handshake);
        if (ephemeralKeys) this.ephemeralKeys = ephemeralKeys;
        this.initialMsg = initialMsg;
    }
    // stage 0
    // eslint-disable-next-line require-await
    async propose() {
        if (this.isInitiator) {
            this.xx.sendMessage(this.session, buffer_1.Buffer.alloc(0), this.ephemeralKeys);
            logger_1.logger('XX Fallback Stage 0 - Initialized state as the first message was sent by initiator.');
            logger_1.logLocalEphemeralKeys(this.session.hs.e);
        } else {
            logger_1.logger('XX Fallback Stage 0 - Responder decoding initial msg from IK.');
            const receivedMessageBuffer = encoder_1.decode0(this.initialMsg);
            const { valid  } = this.xx.recvMessage(this.session, {
                ne: receivedMessageBuffer.ne,
                ns: buffer_1.Buffer.alloc(0),
                ciphertext: buffer_1.Buffer.alloc(0)
            });
            if (!valid) throw new Error('xx fallback stage 0 decryption validation fail');
            logger_1.logger('XX Fallback Stage 0 - Responder used received message from IK.');
            logger_1.logRemoteEphemeralKey(this.session.hs.re);
        }
    }
    // stage 1
    async exchange() {
        if (this.isInitiator) {
            const receivedMessageBuffer = encoder_1.decode1(this.initialMsg);
            const { plaintext , valid  } = this.xx.recvMessage(this.session, receivedMessageBuffer);
            if (!valid) throw new Error('xx fallback stage 1 decryption validation fail');
            logger_1.logger('XX Fallback Stage 1 - Initiator used received message from IK.');
            logger_1.logRemoteEphemeralKey(this.session.hs.re);
            logger_1.logRemoteStaticKey(this.session.hs.rs);
            logger_1.logger("Initiator going to check remote's signature...");
            try {
                const decodedPayload = await utils_1.decodePayload(plaintext);
                this.remotePeer = this.remotePeer || await utils_1.getPeerIdFromPayload(decodedPayload);
                await utils_1.verifySignedPayload(this.session.hs.rs, decodedPayload, this.remotePeer);
                this.setRemoteEarlyData(decodedPayload.data);
            } catch (e) {
                const err = e;
                throw new Error(`Error occurred while verifying signed payload from responder: ${err.message}`);
            }
            logger_1.logger('All good with the signature!');
        } else {
            logger_1.logger('XX Fallback Stage 1 - Responder start');
            await super.exchange();
            logger_1.logger('XX Fallback Stage 1 - Responder end');
        }
    }
}
exports.XXFallbackHandshake = XXFallbackHandshake;

},{"buffer":"eKea5","./handshake-xx":"40XvU","./utils":"3C9kU","./logger":"hHMfO","./encoder":"fw0Lz"}],"7ejgP":[function(require,module,exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.decryptStream = exports.encryptStream = void 0;
const buffer_1 = require("buffer");
const constants_1 = require("./constants");
// Returns generator that encrypts payload from the user
function encryptStream(handshake) {
    return async function*(source) {
        for await (const chunk of source){
            const chunkBuffer = buffer_1.Buffer.from(chunk.buffer, chunk.byteOffset, chunk.length);
            for(let i = 0; i < chunkBuffer.length; i += constants_1.NOISE_MSG_MAX_LENGTH_BYTES_WITHOUT_TAG){
                let end = i + constants_1.NOISE_MSG_MAX_LENGTH_BYTES_WITHOUT_TAG;
                if (end > chunkBuffer.length) end = chunkBuffer.length;
                const data = handshake.encrypt(chunkBuffer.slice(i, end), handshake.session);
                yield data;
            }
        }
    };
}
exports.encryptStream = encryptStream;
// Decrypt received payload to the user
function decryptStream(handshake) {
    return async function*(source) {
        for await (const chunk of source){
            const chunkBuffer = buffer_1.Buffer.from(chunk.buffer, chunk.byteOffset, chunk.length);
            for(let i = 0; i < chunkBuffer.length; i += constants_1.NOISE_MSG_MAX_LENGTH_BYTES){
                let end = i + constants_1.NOISE_MSG_MAX_LENGTH_BYTES;
                if (end > chunkBuffer.length) end = chunkBuffer.length;
                const chunk = chunkBuffer.slice(i, end);
                const { plaintext: decrypted , valid  } = await handshake.decrypt(chunk, handshake.session);
                if (!valid) throw new Error('Failed to validate decrypted chunk');
                yield decrypted;
            }
        }
    };
}
exports.decryptStream = decryptStream;

},{"buffer":"eKea5","./constants":"3FbHN"}],"6mUAQ":[function(require,module,exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.KeyCache = void 0;
/**
 * Storage for static keys of previously connected peers.
 */ class Keycache {
    constructor(){
        this.storage = new Map();
    }
    store(peerId, key) {
        this.storage.set(peerId.id, key);
    }
    load(peerId1) {
        var _a;
        if (!peerId1) return null;
        return (_a = this.storage.get(peerId1.id)) !== null && _a !== void 0 ? _a : null;
    }
    resetStorage() {
        this.storage.clear();
    }
}
const KeyCache = new Keycache();
exports.KeyCache = KeyCache;

},{}],"eg2db":[function(require,module,exports) {
'use strict';
const { EventEmitter  } = require('events');
const errcode = require('err-code');
const libp2pRecord = require('libp2p-record');
const { MemoryDatastore  } = require('datastore-core/memory');
const { equals: uint8ArrayEquals  } = require('uint8arrays/equals');
const { toString: uint8ArrayToString  } = require('uint8arrays/to-string');
const RoutingTable = require('./routing-table');
const utils = require('./utils');
const c = require('./constants');
const Network = require('./network');
const contentFetching = require('./content-fetching');
const contentRouting = require('./content-routing');
const peerRouting = require('./peer-routing');
const Message = require('./message');
const Providers = require('./providers');
const QueryManager = require('./query-manager');
const Record = libp2pRecord.Record;
/**
 * @typedef {*} Libp2p
 * @typedef {*} PeerStore
 * @typedef {import('peer-id')} PeerId
 * @typedef {import('interface-datastore').Datastore} Datastore
 * @typedef {*} Dialer
 * @typedef {*} Registrar
 * @typedef {import('multiformats/cid').CID} CID
 * @typedef {import('multiaddr').Multiaddr} Multiaddr
 * @typedef {object} PeerData
 * @property {PeerId} id
 * @property {Multiaddr[]} multiaddrs
 */ /**
 * A DHT implementation modeled after Kademlia with S/Kademlia modifications.
 * Original implementation in go: https://github.com/libp2p/go-libp2p-kad-dht.
 */ class KadDHT extends EventEmitter {
    /**
   * Create a new KadDHT.
   *
   * @param {Object} props
   * @param {Libp2p} props.libp2p - the libp2p instance
   * @param {Dialer} props.dialer - libp2p dialer instance
   * @param {PeerId} props.peerId - peer's peerId
   * @param {PeerStore} props.peerStore - libp2p peerStore
   * @param {Registrar} props.registrar - libp2p registrar instance
   * @param {string} [props.protocolPrefix = '/ipfs'] - libp2p registrar handle protocol
   * @param {boolean} [props.forceProtocolLegacy = false] - WARNING: this is not recommended and should only be used for legacy purposes
   * @param {number} props.kBucketSize - k-bucket size (default 20)
   * @param {boolean} props.clientMode - If true, the DHT will not respond to queries. This should be true if your node will not be dialable. (default: false)
   * @param {number} props.concurrency - alpha concurrency of queries (default 3)
   * @param {Datastore} props.datastore - datastore (default MemoryDatastore)
   * @param {object} props.validators - validators object with namespace as keys and function(key, record, callback)
   * @param {object} props.selectors - selectors object with namespace as keys and function(key, records)
   * @param {function(import('libp2p-record').Record, PeerId): void} [props.onPut] - Called when an entry is added to or changed in the datastore
   * @param {function(import('libp2p-record').Record): void} [props.onRemove] - Called when an entry is removed from the datastore
   */ constructor({ libp2p , dialer , peerId , peerStore , registrar , protocolPrefix ='/ipfs' , forceProtocolLegacy =false , datastore =new MemoryDatastore() , kBucketSize =c.K , clientMode =false , concurrency =c.ALPHA , validators ={
    } , selectors ={
    } , onPut =()=>{
    } , onRemove =()=>{
    }  }){
        super();
        if (!dialer) throw new Error('libp2p-kad-dht requires an instance of Dialer');
        /**
     * Local reference to the libp2p instance. May be undefined.
     *
     * @type {Libp2p}
     */ this.libp2p = libp2p;
        /**
     * Local reference to the libp2p dialer instance
     *
     * @type {Dialer}
     */ this.dialer = dialer;
        /**
     * Local peer-id
     *
     * @type {PeerId}
     */ this.peerId = peerId;
        /**
     * Local PeerStore
     *
     * @type {PeerStore}
     */ this.peerStore = peerStore;
        /**
     * Local peer info
     *
     * @type {Registrar}
     */ this.registrar = registrar;
        /**
     * Registrar protocol
     *
     * @type {string}
     */ this.protocol = protocolPrefix + (forceProtocolLegacy ? '' : c.PROTOCOL_DHT);
        /**
     * k-bucket size
     *
     * @type {number}
     */ this.kBucketSize = kBucketSize;
        this._clientMode = clientMode;
        /**
     * ALPHA concurrency at which each query path with run, defaults to 3
     *
     * @type {number}
     */ this.concurrency = concurrency;
        /**
     * Number of disjoint query paths to use
     * This is set to `kBucketSize`/2 per the S/Kademlia paper
     *
     * @type {number}
     */ this.disjointPaths = Math.ceil(this.kBucketSize / 2);
        /**
     * The routing table.
     *
     * @type {RoutingTable}
     */ this.routingTable = new RoutingTable(this, {
            kBucketSize: this.kBucketSize
        });
        /**
     * Reference to the datastore, uses an in-memory store if none given.
     *
     * @type {Datastore}
     */ this.datastore = datastore;
        /**
     * Provider management
     *
     * @type {Providers}
     */ this.providers = new Providers(this.datastore, this.peerId);
        this.validators = {
            pk: libp2pRecord.validator.validators.pk,
            ...validators
        };
        this.selectors = {
            pk: libp2pRecord.selection.selectors.pk,
            ...selectors
        };
        this.network = new Network(this);
        this._log = utils.logger(this.peerId);
        /**
     * Keeps track of running queries
     *
     * @type {QueryManager}
     */ this._queryManager = new QueryManager();
        this._running = false;
        // DHT components
        this.contentFetching = contentFetching(this);
        this.contentRouting = contentRouting(this);
        this.peerRouting = peerRouting(this);
        // datastore events
        this.onPut = onPut;
        this.onRemove = onRemove;
    }
    /**
   * Is this DHT running.
   */ get isStarted() {
        return this._running;
    }
    /**
   * Start listening to incoming connections.
   */ start() {
        this._running = true;
        return Promise.all([
            this.providers.start(),
            this._queryManager.start(),
            this.network.start(),
            this.routingTable.start()
        ]);
    }
    /**
   * Stop accepting incoming connections and sending outgoing
   * messages.
   */ stop() {
        this._running = false;
        return Promise.all([
            this.providers.stop(),
            this._queryManager.stop(),
            this.network.stop(),
            this.routingTable.stop()
        ]);
    }
    /**
   * Store the given key/value  pair in the DHT.
   *
   * @param {Uint8Array} key
   * @param {Uint8Array} value
   * @param {Object} [options] - put options
   * @param {number} [options.minPeers] - minimum number of peers required to successfully put (default: closestPeers.length)
   * @returns {Promise<void>}
   */ async put(key, value, options = {
    }) {
        return this.contentFetching.put(key, value, options);
    }
    /**
   * Get the value to the given key.
   * Times out after 1 minute by default.
   *
   * @param {Uint8Array} key
   * @param {Object} [options] - get options
   * @param {number} [options.timeout] - optional timeout (default: 60000)
   * @returns {Promise<Uint8Array>}
   */ async get(key1, options1 = {
    }) {
        return this.contentFetching.get(key1, options1);
    }
    /**
   * Get the `n` values to the given key without sorting.
   *
   * @param {Uint8Array} key
   * @param {number} nvals
   * @param {Object} [options] - get options
   * @param {number} [options.timeout] - optional timeout (default: 60000)
   */ async getMany(key2, nvals, options2 = {
    }) {
        return this.contentFetching.getMany(key2, nvals, options2);
    }
    /**
   * Remove the given key from the local datastore.
   *
   * @param {Uint8Array} key
   */ async removeLocal(key3) {
        this._log(`removeLocal: ${uint8ArrayToString(key3, 'base32')}`);
        const dsKey = utils.bufferToKey(key3);
        try {
            await this.datastore.delete(dsKey);
        } catch (err) {
            if (err.code === 'ERR_NOT_FOUND') return undefined;
            throw err;
        }
    }
    /**
   * @param {Uint8Array} key
   * @param {Uint8Array} value
   */ async _putLocal(key4, value1) {
        this._log(`_putLocal: ${uint8ArrayToString(key4, 'base32')}`);
        const dsKey = utils.bufferToKey(key4);
        await this.datastore.put(dsKey, value1);
    }
    // ----------- Content Routing
    /**
   * Announce to the network that we can provide given key's value.
   *
   * @param {CID} key
   * @returns {Promise<void>}
   */ async provide(key5) {
        return this.contentRouting.provide(key5);
    }
    /**
   * Search the dht for up to `K` providers of the given CID.
   *
   * @param {CID} key
   * @param {Object} [options] - findProviders options
   * @param {number} [options.timeout=60000] - how long the query should maximally run, in milliseconds (default: 60000)
   * @param {number} [options.maxNumProviders=5] - maximum number of providers to find
   * @returns {AsyncIterable<{ id: PeerId, multiaddrs: Multiaddr[] }>}
   */ async *findProviders(key6, options3 = {
        timeout: 6000,
        maxNumProviders: 5
    }) {
        for await (const peerData of this.contentRouting.findProviders(key6, options3))yield peerData;
    }
    // ----------- Peer Routing -----------
    /**
   * Search for a peer with the given ID.
   *
   * @param {PeerId} id
   * @param {Object} [options] - findPeer options
   * @param {number} [options.timeout=60000] - how long the query should maximally run, in milliseconds (default: 60000)
   * @returns {Promise<{ id: PeerId, multiaddrs: Multiaddr[] }>}
   */ async findPeer(id, options4 = {
        timeout: 60000
    }) {
        return this.peerRouting.findPeer(id, options4);
    }
    /**
   * Kademlia 'node lookup' operation.
   *
   * @param {Uint8Array} key
   * @param {Object} [options]
   * @param {boolean} [options.shallow = false] - shallow query
   */ async *getClosestPeers(key7, options5 = {
        shallow: false
    }) {
        yield* this.peerRouting.getClosestPeers(key7, options5);
    }
    /**
   * Get the public key for the given peer id.
   *
   * @param {PeerId} peer
   */ getPublicKey(peer1) {
        return this.peerRouting.getPublicKey(peer1);
    }
    // ----------- Discovery -----------
    /**
   * @param {PeerId} peerId
   * @param {Multiaddr[]} multiaddrs
   */ _peerDiscovered(peerId1, multiaddrs) {
        this.emit('peer', {
            id: peerId1,
            multiaddrs
        });
    }
    // ----------- Internals -----------
    /**
   * Returns the routing tables closest peers, for the key of
   * the message.
   *
   * @param {Message} msg
   */ async _nearestPeersToQuery(msg) {
        const key = await utils.convertBuffer(msg.key);
        const ids = this.routingTable.closestPeers(key, this.kBucketSize);
        return ids.map((p)=>{
            /** @type {{ id: PeerId, addresses: { multiaddr: Multiaddr }[] }} */ const peer = this.peerStore.get(p);
            return {
                id: p,
                multiaddrs: peer ? peer.addresses.map((address)=>address.multiaddr
                ) : []
            };
        });
    }
    /**
   * Get the nearest peers to the given query, but iff closer
   * than self.
   *
   * @param {Message} msg
   * @param {PeerId} peerId
   */ async _betterPeersToQuery(msg1, peerId2) {
        this._log('betterPeersToQuery');
        const closer1 = await this._nearestPeersToQuery(msg1);
        return closer1.filter((closer)=>{
            if (this._isSelf(closer.id)) {
                // Should bail, not sure
                this._log.error('trying to return self as closer');
                return false;
            }
            return !closer.id.isEqual(peerId2);
        });
    }
    /**
   * Try to fetch a given record by from the local datastore.
   * Returns the record iff it is still valid, meaning
   * - it was either authored by this node, or
   * - it was received less than `MAX_RECORD_AGE` ago.
   *
   * @param {Uint8Array} key
   */ async _checkLocalDatastore(key8) {
        this._log(`checkLocalDatastore: ${uint8ArrayToString(key8)} %b`, key8);
        const dsKey = utils.bufferToKey(key8);
        // Fetch value from ds
        let rawRecord;
        try {
            rawRecord = await this.datastore.get(dsKey);
        } catch (err) {
            if (err.code === 'ERR_NOT_FOUND') return undefined;
            throw err;
        }
        // Create record from the returned bytes
        const record = Record.deserialize(rawRecord);
        if (!record) throw errcode(new Error('Invalid record'), 'ERR_INVALID_RECORD');
        // Check validity: compare time received with max record age
        if (record.timeReceived == null || utils.now() - record.timeReceived.getTime() > c.MAX_RECORD_AGE) {
            // If record is bad delete it and return
            await this.datastore.delete(dsKey);
            this.onRemove(record);
            return undefined;
        }
        // Record is valid
        return record;
    }
    /**
   * Add the peer to the routing table and update it in the peerStore.
   *
   * @param {PeerId} peerId
   */ async _add(peerId3) {
        await this.routingTable.add(peerId3);
    }
    /**
   * Verify a record without searching the DHT.
   *
   * @param {import('libp2p-record').Record} record
   */ async _verifyRecordLocally(record) {
        this._log('verifyRecordLocally');
        await libp2pRecord.validator.verifyRecord(this.validators, record);
    }
    /**
   * Is the given peer id our PeerId?
   *
   * @param {PeerId} other
   */ _isSelf(other) {
        return other && uint8ArrayEquals(this.peerId.id, other.id);
    }
    /**
   * Store the given key/value pair at the peer `target`.
   *
   * @param {Uint8Array} key
   * @param {Uint8Array} rec - encoded record
   * @param {PeerId} target
   */ async _putValueToPeer(key9, rec, target) {
        const msg = new Message(Message.TYPES.PUT_VALUE, key9, 0);
        msg.record = Record.deserialize(rec);
        const resp = await this.network.sendRequest(target, msg);
        if (resp.record && !uint8ArrayEquals(resp.record.value, Record.deserialize(rec).value)) throw errcode(new Error('value not put correctly'), 'ERR_PUT_VALUE_INVALID');
    }
    /**
   * Query a particular peer for the value for the given key.
   * It will either return the value or a list of closer peers.
   *
   * Note: The peerStore is updated with new addresses found for the given peer.
   *
   * @param {PeerId} peer
   * @param {Uint8Array} key
   */ async _getValueOrPeers(peer, key10) {
        const msg = await this._getValueSingle(peer, key10);
        const peers = msg.closerPeers;
        const record = msg.record;
        if (record) {
            // We have a record
            try {
                await this._verifyRecordOnline(record);
            } catch (err) {
                const errMsg = 'invalid record received, discarded';
                this._log(errMsg);
                throw errcode(new Error(errMsg), 'ERR_INVALID_RECORD');
            }
            return {
                record,
                peers
            };
        }
        if (peers.length > 0) return {
            peers
        };
        throw errcode(new Error('Not found'), 'ERR_NOT_FOUND');
    }
    /**
   * Get a value via rpc call for the given parameters.
   *
   * @param {PeerId} peer
   * @param {Uint8Array} key
   */ async _getValueSingle(peer2, key11) {
        const msg = new Message(Message.TYPES.GET_VALUE, key11, 0);
        return this.network.sendRequest(peer2, msg);
    }
    /**
   * Verify a record, fetching missing public keys from the network.
   * Calls back with an error if the record is invalid.
   *
   * @param {import('libp2p-record').Record} record
   * @returns {Promise<void>}
   */ async _verifyRecordOnline(record1) {
        await libp2pRecord.validator.verifyRecord(this.validators, record1);
    }
}
module.exports = KadDHT;
module.exports.multicodec = '/ipfs' + c.PROTOCOL_DHT;

},{"events":"bHM3D","err-code":"eQvyh","libp2p-record":"4hkIr","datastore-core/memory":"8Qezj","uint8arrays/equals":"fjLeN","uint8arrays/to-string":"g3mCQ","./routing-table":"eDrhg","./utils":"16BUU","./constants":"b8cEs","./network":"jOEj6","./content-fetching":"1Ifs8","./content-routing":"lbaJI","./peer-routing":"liYRf","./message":"5TcLe","./providers":"lKxfg","./query-manager":"jkIo4"}],"eDrhg":[function(require,module,exports) {
'use strict';
// @ts-ignore
const KBuck = require('k-bucket');
const { xor: uint8ArrayXor  } = require('uint8arrays/xor');
const GENERATED_PREFIXES = require('./generated-prefix-list.json');
const { sha256  } = require('multiformats/hashes/sha2');
const crypto = require('libp2p-crypto');
const PeerId = require('peer-id');
const utils = require('../utils');
const debug = require('debug');
const log = Object.assign(debug('libp2p:dht:routing-table'), {
    error: debug('libp2p:dht:routing-table:error')
});
// @ts-ignore
const length = require('it-length');
/**
 * @typedef {object} KBucketPeer
 * @property {Uint8Array} id
 * @property {PeerId} peer
 *
 * @typedef {object} KBucket
 * @property {Uint8Array} id
 * @property {KBucketPeer[]} contacts
 * @property {boolean} dontSplit
 * @property {KBucket} left
 * @property {KBucket} right
 *
 * @typedef {object} KBucketTree
 * @property {KBucket} root
 * @property {Uint8Array} localNodeId
 * @property {(event: string, callback: Function) => void} on
 * @property {(key: Uint8Array, count: number) => KBucketPeer[]} closest
 * @property {(key: Uint8Array) => KBucketPeer} closestPeer
 * @property {(key: Uint8Array) => void} remove
 * @property {(peer: KBucketPeer) => void} add
 * @property {() => number} count
 * @property {() => Iterable<KBucket>} toIterable
 */ /**
 * Cannot generate random KadIds longer than this + 1
 */ const MAX_COMMON_PREFIX_LENGTH = 15;
/**
 * A wrapper around `k-bucket`, to provide easy store and
 * retrieval for peers.
 */ class RoutingTable {
    /**
   * @param {import('../')} dht
   * @param {object} [options]
   * @param {number} [options.kBucketSize=20]
   * @param {number} [options.refreshInterval=30000]
   */ constructor(dht, { kBucketSize , refreshInterval  } = {
    }){
        this.peerId = dht.peerId;
        this.dht = dht;
        this._kBucketSize = kBucketSize || 20;
        this._refreshInterval = refreshInterval || 30000;
        /** @type {KBucketTree} */ this.kb = new KBuck({
            numberOfNodesPerKBucket: this._kBucketSize,
            numberOfNodesToPing: 1
        });
        /** @type {Date[]} */ this.commonPrefixLengthRefreshedAt = [];
        this._refreshTable = this._refreshTable.bind(this);
        this._onPing = this._onPing.bind(this);
    }
    async start() {
        this.kb.localNodeId = await utils.convertPeerId(this.peerId);
        this.kb.on('ping', this._onPing);
        await this._refreshTable(true);
    }
    async stop() {
        if (this._refreshTimeoutId) clearTimeout(this._refreshTimeoutId);
    }
    /**
   * To speed lookups, we seed the table with random PeerIds. This means
   * when we are asked to locate a peer on the network, we can find a KadId
   * that is close to the requested peer ID and query that, then network
   * peers will tell us who they know who is close to the fake ID
   *
   * @param {boolean} [force=false]
   */ async _refreshTable(force) {
        log('refreshing routing table');
        const prefixLength = this._maxCommonPrefix();
        const refreshCpls = this._getTrackedCommonPrefixLengthsForRefresh(prefixLength);
        log(`max common prefix length ${prefixLength}`);
        log(`tracked CPLs [ ${refreshCpls.map((date)=>`${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')} ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}:${date.getSeconds().toString().padStart(2, '0')}`
        ).join(', ')} ]`);
        /**
     * If we see a gap at a common prefix length in the Routing table, we ONLY refresh up until
     * the maximum cpl we have in the Routing Table OR (2 * (Cpl+ 1) with the gap), whichever
     * is smaller.
     *
     * This is to prevent refreshes for Cpls that have no peers in the network but happen to be
     * before a very high max Cpl for which we do have peers in the network.
     *
     * The number of 2 * (Cpl + 1) can be proved and a proof would have been written here if
     * the programmer had paid more attention in the Math classes at university.
     *
     * So, please be patient and a doc explaining it will be published soon.
     *
     * https://github.com/libp2p/go-libp2p-kad-dht/commit/2851c88acb0a3f86bcfe3cfd0f4604a03db801d8#diff-ad45f4ba97ffbc4083c2eb87a4420c1157057b233f048030d67c6b551855ccf6R219
     */ await Promise.all(refreshCpls.map(async (lastRefresh, index)=>{
            try {
                await this._refreshCommonPrefixLength(index, lastRefresh, force === true);
                if (this._numPeersForCpl(prefixLength) === 0) {
                    const lastCpl = Math.min(2 * (index + 1), refreshCpls.length - 1);
                    for(let n = index + 1; n < lastCpl + 1; n++)try {
                        await this._refreshCommonPrefixLength(n, lastRefresh, force === true);
                    } catch (err) {
                        log.error(err);
                    }
                }
            } catch (err) {
                log.error(err);
            }
        }));
        this._refreshTimeoutId = setTimeout(this._refreshTable, this._refreshInterval);
        // @ts-ignore
        this._refreshTimeoutId.unref();
    }
    /**
   * @param {number} cpl
   * @param {Date} lastRefresh
   * @param {boolean} force
   */ async _refreshCommonPrefixLength(cpl, lastRefresh, force1) {
        if (!force1 && lastRefresh.getTime() > Date.now() - this._refreshInterval) {
            log(`not running refresh for cpl ${cpl} as time since last refresh not above interval`);
            return;
        }
        // gen a key for the query to refresh the cpl
        const peerId = await this._generateRandomPeerId(cpl);
        log(`starting refreshing cpl ${cpl} with key ${peerId.toB58String()} (routing table size was ${this.kb.count()})`);
        const peers = await length(this.dht.getClosestPeers(peerId.toBytes(), {
        }));
        log(`found ${peers} peers that were close to imaginary peer ${peerId.toB58String()}`);
        log(`finished refreshing cpl ${cpl} with key ${peerId.toB58String()} (routing table size was ${this.kb.count()})`);
    }
    /**
   * @param {number} maxCommonPrefix
   */ _getTrackedCommonPrefixLengthsForRefresh(maxCommonPrefix) {
        if (maxCommonPrefix > MAX_COMMON_PREFIX_LENGTH) maxCommonPrefix = MAX_COMMON_PREFIX_LENGTH;
        const dates = [];
        for(let i = 0; i <= maxCommonPrefix; i++)// defaults to the zero value if we haven't refreshed it yet.
        dates[i] = this.commonPrefixLengthRefreshedAt[i] || new Date();
        return dates;
    }
    /**
   *
   * @param {number} targetCommonPrefixLength
   */ async _generateRandomPeerId(targetCommonPrefixLength) {
        const randomBytes = crypto.randomBytes(2);
        const randomUint16 = (randomBytes[1] << 8) + randomBytes[0];
        const key = await this._makePeerId(this.kb.localNodeId, randomUint16, targetCommonPrefixLength);
        return PeerId.createFromBytes(key);
    }
    /**
   * @param {Uint8Array} localKadId
   * @param {number} randomPrefix
   * @param {number} targetCommonPrefixLength
   */ async _makePeerId(localKadId, randomPrefix, targetCommonPrefixLength1) {
        if (targetCommonPrefixLength1 > MAX_COMMON_PREFIX_LENGTH) throw new Error(`Cannot generate peer ID for common prefix length greater than ${MAX_COMMON_PREFIX_LENGTH}`);
        const view = new DataView(localKadId.buffer, localKadId.byteOffset, localKadId.byteLength);
        const localPrefix = view.getUint16(0, false);
        // For host with ID `L`, an ID `K` belongs to a bucket with ID `B` ONLY IF CommonPrefixLen(L,K) is EXACTLY B.
        // Hence, to achieve a targetPrefix `T`, we must toggle the (T+1)th bit in L & then copy (T+1) bits from L
        // to our randomly generated prefix.
        const toggledLocalPrefix = localPrefix ^ 32768 >> targetCommonPrefixLength1;
        // Combine the toggled local prefix and the random bits at the correct offset
        // such that ONLY the first `targetCommonPrefixLength` bits match the local ID.
        const mask = 65535 << 16 - (targetCommonPrefixLength1 + 1);
        const targetPrefix = toggledLocalPrefix & mask | randomPrefix & ~mask;
        // Convert to a known peer ID.
        const keyPrefix = GENERATED_PREFIXES[targetPrefix];
        const keyBuffer = new ArrayBuffer(34);
        const keyView = new DataView(keyBuffer, 0, keyBuffer.byteLength);
        keyView.setUint8(0, sha256.code);
        keyView.setUint8(1, 32);
        keyView.setUint32(2, keyPrefix, false);
        return new Uint8Array(keyView.buffer, keyView.byteOffset, keyView.byteLength);
    }
    /**
   * returns the maximum common prefix length between any peer in the table
   * and the current peer
   */ _maxCommonPrefix() {
        if (!this.kb.localNodeId) return 0;
        // xor our KadId with every KadId in the k-bucket tree,
        // return the longest id prefix that is the same
        let prefixLength = 0;
        for (const length of this._prefixLengths())if (length > prefixLength) prefixLength = length;
        return prefixLength;
    }
    /**
   * Returns the number of peers in the table with a given prefix length
   *
   * @param {number} prefixLength
   */ _numPeersForCpl(prefixLength) {
        let count = 0;
        for (const length of this._prefixLengths())if (length === prefixLength) count++;
        return count;
    }
    /**
   * Yields the common prefix length of every peer in the table
   */ *_prefixLengths() {
        for (const { id  } of this.kb.toIterable()){
            const distance = uint8ArrayXor(this.kb.localNodeId, id);
            let leadingZeros = 0;
            for (const byte of distance){
                if (byte === 0) leadingZeros++;
                else break;
            }
            yield leadingZeros;
        }
    }
    /**
   * Called on the `ping` event from `k-bucket`.
   * Currently this just removes the oldest contact from
   * the list, without actually pinging the individual peers.
   * This is the same as go does, but should probably
   * be upgraded to actually ping the individual peers.
   *
   * @param {KBucketPeer[]} oldContacts
   * @param {KBucketPeer} newContact
   */ _onPing(oldContacts, newContact) {
        // just use the first one (k-bucket sorts from oldest to newest)
        const oldest = oldContacts[0];
        if (oldest) // remove the oldest one
        this.kb.remove(oldest.id);
        // add the new one
        this.kb.add(newContact);
    }
    // -- Public Interface
    /**
   * Amount of currently stored peers.
   */ get size() {
        return this.kb.count();
    }
    /**
   * Find a specific peer by id.
   *
   * @param {PeerId} peer
   */ async find(peer) {
        const key = await utils.convertPeerId(peer);
        const closest = this.closestPeer(key);
        if (closest && peer.equals(closest)) return closest;
    }
    /**
   * Retrieve the closest peers to the given key.
   *
   * @param {Uint8Array} key
   */ closestPeer(key) {
        const res = this.closestPeers(key, 1);
        if (res.length > 0) return res[0];
    }
    /**
   * Retrieve the `count`-closest peers to the given key.
   *
   * @param {Uint8Array} key
   * @param {number} count
   */ closestPeers(key1, count) {
        const closest = this.kb.closest(key1, count);
        return closest.map((p)=>p.peer
        );
    }
    /**
   * Add or update the routing table with the given peer.
   *
   * @param {PeerId} peer
   */ async add(peer1) {
        const id = await utils.convertPeerId(peer1);
        this.kb.add({
            id: id,
            peer: peer1
        });
    }
    /**
   * Remove a given peer from the table.
   *
   * @param {PeerId} peer
   */ async remove(peer2) {
        const id = await utils.convertPeerId(peer2);
        this.kb.remove(id);
    }
}
module.exports = RoutingTable;

},{"k-bucket":"jKuTB","uint8arrays/xor":"lpkFK","./generated-prefix-list.json":"cXW7r","multiformats/hashes/sha2":"i8JnP","libp2p-crypto":"hsRcr","peer-id":"4VGWt","../utils":"16BUU","debug":"lWlU4","it-length":"6wGCy"}],"jKuTB":[function(require,module,exports) {
/*
index.js - Kademlia DHT K-bucket implementation as a binary tree.

The MIT License (MIT)

Copyright (c) 2013-2021 Tristan Slominski

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/ 'use strict';
const randomBytes = require('randombytes');
const { EventEmitter  } = require('events');
/**
 * @param  {Uint8Array} array1
 * @param  {Uint8Array} array2
 * @return {Boolean}
 */ function arrayEquals(array1, array2) {
    if (array1 === array2) return true;
    if (array1.length !== array2.length) return false;
    for(let i = 0, length = array1.length; i < length; ++i){
        if (array1[i] !== array2[i]) return false;
    }
    return true;
}
function createNode() {
    return {
        contacts: [],
        dontSplit: false,
        left: null,
        right: null
    };
}
function ensureInt8(name, val) {
    if (!(val instanceof Uint8Array)) throw new TypeError(name + ' is not a Uint8Array');
}
/**
 * Implementation of a Kademlia DHT k-bucket used for storing
 * contact (peer node) information.
 *
 * @extends EventEmitter
 */ class KBucket extends EventEmitter {
    /**
   * `options`:
   *   `distance`: _Function_
   *     `function (firstId, secondId) { return distance }` An optional
   *     `distance` function that gets two `id` Uint8Arrays
   *     and return distance (as number) between them.
   *   `arbiter`: _Function_ _(Default: vectorClock arbiter)_
   *     `function (incumbent, candidate) { return contact; }` An optional
   *     `arbiter` function that givent two `contact` objects with the same `id`
   *     returns the desired object to be used for updating the k-bucket. For
   *     more details, see [arbiter function](#arbiter-function).
   *   `localNodeId`: _Uint8Array_ An optional Uint8Array representing the local node id.
   *     If not provided, a local node id will be created via `randomBytes(20)`.
   *     `metadata`: _Object_ _(Default: {})_ Optional satellite data to include
   *     with the k-bucket. `metadata` property is guaranteed not be altered by,
   *     it is provided as an explicit container for users of k-bucket to store
   *     implementation-specific data.
   *   `numberOfNodesPerKBucket`: _Integer_ _(Default: 20)_ The number of nodes
   *     that a k-bucket can contain before being full or split.
   *     `numberOfNodesToPing`: _Integer_ _(Default: 3)_ The number of nodes to
   *     ping when a bucket that should not be split becomes full. KBucket will
   *     emit a `ping` event that contains `numberOfNodesToPing` nodes that have
   *     not been contacted the longest.
   *
   * @param {Object=} options optional
   */ constructor(options = {
    }){
        super();
        this.localNodeId = options.localNodeId || randomBytes(20);
        this.numberOfNodesPerKBucket = options.numberOfNodesPerKBucket || 20;
        this.numberOfNodesToPing = options.numberOfNodesToPing || 3;
        this.distance = options.distance || KBucket.distance;
        // use an arbiter from options or vectorClock arbiter by default
        this.arbiter = options.arbiter || KBucket.arbiter;
        this.metadata = Object.assign({
        }, options.metadata);
        ensureInt8('option.localNodeId as parameter 1', this.localNodeId);
        this.root = createNode();
    }
    /**
   * Default arbiter function for contacts with the same id. Uses
   * contact.vectorClock to select which contact to update the k-bucket with.
   * Contact with larger vectorClock field will be selected. If vectorClock is
   * the same, candidat will be selected.
   *
   * @param  {Object} incumbent Contact currently stored in the k-bucket.
   * @param  {Object} candidate Contact being added to the k-bucket.
   * @return {Object}           Contact to updated the k-bucket with.
   */ static arbiter(incumbent, candidate) {
        return incumbent.vectorClock > candidate.vectorClock ? incumbent : candidate;
    }
    /**
   * Default distance function. Finds the XOR
   * distance between firstId and secondId.
   *
   * @param  {Uint8Array} firstId  Uint8Array containing first id.
   * @param  {Uint8Array} secondId Uint8Array containing second id.
   * @return {Number}              Integer The XOR distance between firstId
   *                               and secondId.
   */ static distance(firstId, secondId) {
        let distance = 0;
        let i = 0;
        const min = Math.min(firstId.length, secondId.length);
        const max = Math.max(firstId.length, secondId.length);
        for(; i < min; ++i)distance = distance * 256 + (firstId[i] ^ secondId[i]);
        for(; i < max; ++i)distance = distance * 256 + 255;
        return distance;
    }
    /**
   * Adds a contact to the k-bucket.
   *
   * @param {Object} contact the contact object to add
   */ add(contact) {
        ensureInt8('contact.id', (contact || {
        }).id);
        let bitIndex = 0;
        let node = this.root;
        while(node.contacts === null)// this is not a leaf node but an inner node with 'low' and 'high'
        // branches; we will check the appropriate bit of the identifier and
        // delegate to the appropriate node for further processing
        node = this._determineNode(node, contact.id, bitIndex++);
        // check if the contact already exists
        const index = this._indexOf(node, contact.id);
        if (index >= 0) {
            this._update(node, index, contact);
            return this;
        }
        if (node.contacts.length < this.numberOfNodesPerKBucket) {
            node.contacts.push(contact);
            this.emit('added', contact);
            return this;
        }
        // the bucket is full
        if (node.dontSplit) {
            // we are not allowed to split the bucket
            // we need to ping the first this.numberOfNodesToPing
            // in order to determine if they are alive
            // only if one of the pinged nodes does not respond, can the new contact
            // be added (this prevents DoS flodding with new invalid contacts)
            this.emit('ping', node.contacts.slice(0, this.numberOfNodesToPing), contact);
            return this;
        }
        this._split(node, bitIndex);
        return this.add(contact);
    }
    /**
   * Get the n closest contacts to the provided node id. "Closest" here means:
   * closest according to the XOR metric of the contact node id.
   *
   * @param  {Uint8Array} id  Contact node id
   * @param  {Number=} n      Integer (Default: Infinity) The maximum number of
   *                          closest contacts to return
   * @return {Array}          Array Maximum of n closest contacts to the node id
   */ closest(id, n = Infinity) {
        ensureInt8('id', id);
        if (!Number.isInteger(n) && n !== Infinity || n <= 0) throw new TypeError('n is not positive number');
        let contacts = [];
        for(let nodes = [
            this.root
        ], bitIndex = 0; nodes.length > 0 && contacts.length < n;){
            const node = nodes.pop();
            if (node.contacts === null) {
                const detNode = this._determineNode(node, id, bitIndex++);
                nodes.push(node.left === detNode ? node.right : node.left);
                nodes.push(detNode);
            } else contacts = contacts.concat(node.contacts);
        }
        return contacts.map((a)=>[
                this.distance(a.id, id),
                a
            ]
        ).sort((a, b)=>a[0] - b[0]
        ).slice(0, n).map((a)=>a[1]
        );
    }
    /**
   * Counts the total number of contacts in the tree.
   *
   * @return {Number} The number of contacts held in the tree
   */ count() {
        // return this.toArray().length
        let count = 0;
        for(const nodes = [
            this.root
        ]; nodes.length > 0;){
            const node = nodes.pop();
            if (node.contacts === null) nodes.push(node.right, node.left);
            else count += node.contacts.length;
        }
        return count;
    }
    /**
   * Determines whether the id at the bitIndex is 0 or 1.
   * Return left leaf if `id` at `bitIndex` is 0, right leaf otherwise
   *
   * @param  {Object} node     internal object that has 2 leafs: left and right
   * @param  {Uint8Array} id   Id to compare localNodeId with.
   * @param  {Number} bitIndex Integer (Default: 0) The bit index to which bit
   *                           to check in the id Uint8Array.
   * @return {Object}          left leaf if id at bitIndex is 0, right leaf otherwise.
   */ _determineNode(node, id1, bitIndex) {
        // **NOTE** remember that id is a Uint8Array and has granularity of
        // bytes (8 bits), whereas the bitIndex is the _bit_ index (not byte)
        // id's that are too short are put in low bucket (1 byte = 8 bits)
        // (bitIndex >> 3) finds how many bytes the bitIndex describes
        // bitIndex % 8 checks if we have extra bits beyond byte multiples
        // if number of bytes is <= no. of bytes described by bitIndex and there
        // are extra bits to consider, this means id has less bits than what
        // bitIndex describes, id therefore is too short, and will be put in low
        // bucket
        const bytesDescribedByBitIndex = bitIndex >> 3;
        const bitIndexWithinByte = bitIndex % 8;
        if (id1.length <= bytesDescribedByBitIndex && bitIndexWithinByte !== 0) return node.left;
        const byteUnderConsideration = id1[bytesDescribedByBitIndex];
        // byteUnderConsideration is an integer from 0 to 255 represented by 8 bits
        // where 255 is 11111111 and 0 is 00000000
        // in order to find out whether the bit at bitIndexWithinByte is set
        // we construct (1 << (7 - bitIndexWithinByte)) which will consist
        // of all bits being 0, with only one bit set to 1
        // for example, if bitIndexWithinByte is 3, we will construct 00010000 by
        // (1 << (7 - 3)) -> (1 << 4) -> 16
        if (byteUnderConsideration & 1 << 7 - bitIndexWithinByte) return node.right;
        return node.left;
    }
    /**
   * Get a contact by its exact ID.
   * If this is a leaf, loop through the bucket contents and return the correct
   * contact if we have it or null if not. If this is an inner node, determine
   * which branch of the tree to traverse and repeat.
   *
   * @param  {Uint8Array} id The ID of the contact to fetch.
   * @return {Object|Null}   The contact if available, otherwise null
   */ get(id2) {
        ensureInt8('id', id2);
        let bitIndex = 0;
        let node = this.root;
        while(node.contacts === null)node = this._determineNode(node, id2, bitIndex++);
        // index of uses contact id for matching
        const index = this._indexOf(node, id2);
        return index >= 0 ? node.contacts[index] : null;
    }
    /**
   * Returns the index of the contact with provided
   * id if it exists, returns -1 otherwise.
   *
   * @param  {Object} node    internal object that has 2 leafs: left and right
   * @param  {Uint8Array} id  Contact node id.
   * @return {Number}         Integer Index of contact with provided id if it
   *                          exists, -1 otherwise.
   */ _indexOf(node1, id3) {
        for(let i = 0; i < node1.contacts.length; ++i){
            if (arrayEquals(node1.contacts[i].id, id3)) return i;
        }
        return -1;
    }
    /**
   * Removes contact with the provided id.
   *
   * @param  {Uint8Array} id The ID of the contact to remove.
   * @return {Object}        The k-bucket itself.
   */ remove(id4) {
        ensureInt8('the id as parameter 1', id4);
        let bitIndex = 0;
        let node = this.root;
        while(node.contacts === null)node = this._determineNode(node, id4, bitIndex++);
        const index = this._indexOf(node, id4);
        if (index >= 0) {
            const contact = node.contacts.splice(index, 1)[0];
            this.emit('removed', contact);
        }
        return this;
    }
    /**
   * Splits the node, redistributes contacts to the new nodes, and marks the
   * node that was split as an inner node of the binary tree of nodes by
   * setting this.root.contacts = null
   *
   * @param  {Object} node     node for splitting
   * @param  {Number} bitIndex the bitIndex to which byte to check in the
   *                           Uint8Array for navigating the binary tree
   */ _split(node2, bitIndex1) {
        node2.left = createNode();
        node2.right = createNode();
        // redistribute existing contacts amongst the two newly created nodes
        for (const contact of node2.contacts)this._determineNode(node2, contact.id, bitIndex1).contacts.push(contact);
        node2.contacts = null // mark as inner tree node
        ;
        // don't split the "far away" node
        // we check where the local node would end up and mark the other one as
        // "dontSplit" (i.e. "far away")
        const detNode = this._determineNode(node2, this.localNodeId, bitIndex1);
        const otherNode = node2.left === detNode ? node2.right : node2.left;
        otherNode.dontSplit = true;
    }
    /**
   * Returns all the contacts contained in the tree as an array.
   * If this is a leaf, return a copy of the bucket. If this is not a leaf,
   * return the union of the low and high branches (themselves also as arrays).
   *
   * @return {Array} All of the contacts in the tree, as an array
   */ toArray() {
        let result = [];
        for(const nodes = [
            this.root
        ]; nodes.length > 0;){
            const node = nodes.pop();
            if (node.contacts === null) nodes.push(node.right, node.left);
            else result = result.concat(node.contacts);
        }
        return result;
    }
    /**
   * Similar to `toArray()` but instead of buffering everything up into an
   * array before returning it, yields contacts as they are encountered while
   * walking the tree.
   *
   * @return {Iterable} All of the contacts in the tree, as an iterable
   */ *toIterable() {
        for(const nodes = [
            this.root
        ]; nodes.length > 0;){
            const node = nodes.pop();
            if (node.contacts === null) nodes.push(node.right, node.left);
            else yield* node.contacts;
        }
    }
    /**
   * Updates the contact selected by the arbiter.
   * If the selection is our old contact and the candidate is some new contact
   * then the new contact is abandoned (not added).
   * If the selection is our old contact and the candidate is our old contact
   * then we are refreshing the contact and it is marked as most recently
   * contacted (by being moved to the right/end of the bucket array).
   * If the selection is our new contact, the old contact is removed and the new
   * contact is marked as most recently contacted.
   *
   * @param  {Object} node    internal object that has 2 leafs: left and right
   * @param  {Number} index   the index in the bucket where contact exists
   *                          (index has already been computed in a previous
   *                          calculation)
   * @param  {Object} contact The contact object to update.
   */ _update(node3, index, contact1) {
        // sanity check
        if (!arrayEquals(node3.contacts[index].id, contact1.id)) throw new Error('wrong index for _update');
        const incumbent = node3.contacts[index];
        const selection = this.arbiter(incumbent, contact1);
        // if the selection is our old contact and the candidate is some new
        // contact, then there is nothing to do
        if (selection === incumbent && incumbent !== contact1) return;
        node3.contacts.splice(index, 1) // remove old contact
        ;
        node3.contacts.push(selection) // add more recent contact version
        ;
        this.emit('updated', incumbent, selection);
    }
}
module.exports = KBucket;

},{"randombytes":"hkZOB","events":"bHM3D"}],"lpkFK":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
function xor(a, b) {
    if (a.length !== b.length) throw new Error('Inputs should have the same length');
    const result = new Uint8Array(a.length);
    for(let i = 0; i < a.length; i++)result[i] = a[i] ^ b[i];
    return result;
}
exports.xor = xor;

},{}],"cXW7r":[function(require,module,exports) {
module.exports = JSON.parse("[77591,22417,43971,28421,740,29829,71467,228973,196661,78537,27689,36431,44415,14362,19456,106025,96308,2882,49509,21149,87173,131409,75844,23676,121838,30291,17492,2953,7564,110620,129477,127283,53113,72417,165166,109690,21200,102125,24049,71504,90342,25307,72039,26812,26715,32264,133800,71161,88956,171987,51779,24425,16671,30251,186294,247761,14202,2121,8465,35024,4876,85917,169730,3638,256836,96184,943,18678,6583,52907,35807,112254,214097,18796,11595,9243,23554,887,268203,382004,24590,111335,11625,16619,29039,102425,69006,97976,92362,32552,63717,41433,128974,137630,59943,10019,13986,35430,33665,108037,43799,43280,38195,29078,58629,18265,14425,46832,235538,40830,77881,110717,58937,3463,325358,51300,47623,117252,19007,10170,20540,91237,294813,4951,79841,56232,36270,128547,69209,66275,100156,32063,73531,34439,80937,28892,44466,88595,216307,32583,49620,16605,82127,45807,21630,78726,20235,40163,111007,96926,5567,72083,21665,58844,39419,179767,48328,42662,51550,5251,37811,49608,81056,50854,55513,20922,18891,197409,164656,32593,71449,220474,58919,85682,67854,13758,35066,3565,61905,214793,119572,141419,21504,10302,27354,67003,46131,32668,15165,64871,34450,17821,2757,11452,34189,5160,12257,85523,560,53385,65887,119549,135620,312353,115979,122356,10867,193231,124537,54783,90675,120791,4715,142253,50943,17271,43358,25331,4917,120566,34580,12878,33786,160528,32523,4869,301307,104817,81491,23276,8832,97911,31265,52065,7998,49622,9715,43998,34091,84587,20664,69041,29419,53205,10838,58288,116145,6185,5154,141795,35924,21307,144738,43730,12085,8279,10002,119,133779,199668,72938,31768,39176,67875,38453,9700,44144,4121,116048,41733,12868,82669,92308,128,34262,11332,7712,90764,36141,13553,71312,77470,117314,96549,49135,23602,54468,28605,6327,62308,17171,67531,21319,14105,894,107722,46157,8503,51069,100472,45138,15246,14577,35609,191464,1757,13364,161349,32067,91705,81144,52339,5408,91066,21983,14157,100545,4372,26630,129112,1423,29676,213626,4397,88436,99190,6877,49958,26122,114348,60661,29818,293118,50042,179738,16400,163423,89627,31040,43973,36638,45952,5153,1894,109322,1898,134021,12402,112077,68309,190269,69866,31938,107383,11522,105232,11248,14868,39852,71707,186525,16530,38162,106212,11700,5130,16608,26998,59586,108399,230033,43683,48135,82179,2073,5015,196684,189293,16378,23452,8301,35640,11632,214551,29240,57644,33137,91949,55157,52384,117313,5090,17717,89668,49363,82238,241035,66216,29066,184088,97206,62820,26595,4241,135635,173672,8202,459,71355,146294,29587,3008,135385,141203,14803,6634,45094,69362,50925,546,51884,62011,83296,234584,44515,56050,89476,87751,19373,12691,149923,19794,13833,35846,87557,58339,2884,19145,25647,12224,11024,77338,64608,122297,53025,7205,36189,36294,170779,21750,7739,173883,75192,35664,224240,113121,30181,26267,27036,117827,92015,106516,55628,203549,67949,60462,60844,35911,20457,1820,920,19773,8738,73173,181993,38521,98254,76257,46008,92796,5384,26868,151566,22124,2411,15919,186872,180021,28099,152961,78811,80237,62352,102653,74259,184890,16792,123702,224945,29940,19512,75283,14059,112691,92811,233329,20411,138569,53341,109802,50600,134528,66747,5529,166531,31578,64732,67189,1596,126357,967,167999,206598,109752,119431,207825,78791,91938,10301,27311,24233,252343,28831,32812,66002,112267,90895,8786,8095,16824,22866,21813,60507,174833,19549,130985,117051,52110,6938,81923,123864,38061,919,18680,53534,46739,112893,161529,85429,26761,11900,81121,91968,15390,217947,56524,1713,6654,37089,85630,138866,61850,16491,75577,16884,98296,73523,6140,44645,6062,36366,29844,57946,37932,42472,5266,20834,19309,33753,127182,134259,35810,41805,45878,312001,14881,47757,49251,120050,44252,3708,25856,107864,120347,1228,36550,41682,34496,47025,8393,173365,246526,12894,161607,35670,90785,126572,2095,124731,157033,58694,554,12786,9642,4817,16136,47864,174698,66992,4639,69284,10625,40710,27763,51738,30404,264105,137904,109882,52487,42824,57514,2740,10479,146799,107390,16586,88038,174951,9410,16185,44158,5568,40658,46108,12763,97385,26175,108859,664,230732,67470,46663,14395,50750,141320,93140,15361,47997,55784,6791,307840,118569,107326,18056,58281,260415,54691,8790,73332,45633,7511,45674,143373,14031,11799,94491,35646,96544,14560,26049,32983,25791,83814,42094,231370,63955,139212,2359,169908,3108,183486,105867,28197,32941,124968,26402,88267,149768,23053,3078,19091,52924,25383,19209,111548,97361,3959,24880,235061,9099,24921,161254,151405,20508,7159,34381,20133,11434,74036,19974,34769,36585,1076,22454,17354,38727,235160,111547,96454,117448,156940,91330,37299,7310,26915,117060,51369,22620,61861,322264,106850,111694,15091,2624,40345,300446,177064,1707,27389,54792,327783,132669,183543,59003,17744,20603,151134,106923,53084,71803,279424,319816,11579,21946,16728,38274,72711,5085,83391,88646,40159,25027,34680,10752,12988,54126,30365,18338,100445,230674,44874,84974,143877,123253,139372,28082,91477,144002,13096,219729,46016,50029,42377,14601,6660,58244,58978,23918,88206,113611,64452,17541,41032,10942,12021,49189,10978,40175,37156,10947,71709,106894,112538,57007,137486,150608,152719,40615,7746,279716,13101,19524,28708,40578,72320,1096,182051,94527,51275,22833,45164,81917,77519,48508,5421,140302,37845,149830,5587,27579,5357,428725,248187,6326,206760,39814,32585,89923,44341,288753,284443,96368,31201,94189,119504,20359,52073,103216,179,27934,32801,96035,34111,34309,101326,18198,20704,210266,37643,27880,141873,106000,19414,56614,167714,66483,107885,86602,4379,20796,75467,4987,5017,118857,26003,34308,114428,29198,6686,29697,73632,3739,69795,16798,41504,7207,30722,21436,36735,28067,28545,3239,11221,36031,41889,100010,19247,317673,29495,174554,6424,129725,53845,94986,7955,59676,2604,191497,19735,102214,62954,23844,11872,179525,261436,34492,428,78404,142035,16747,17246,27578,37021,33672,57944,26056,135760,2369,61674,122066,31327,19374,157065,40553,130982,69619,71290,38855,72100,92903,95940,51422,165999,65713,57873,50726,7288,20272,2081,42326,22624,81120,57914,79352,19447,1684,72302,11774,302559,161481,96396,13692,414988,3721,79066,56627,46883,21150,11747,12184,5856,113458,176117,84416,52079,27933,3354,59765,141359,2212,216309,2555,23458,196722,142463,45701,44548,28798,19418,215,29916,9396,10574,114226,84475,13520,18694,34056,4524,90302,62930,13539,19407,77209,7728,38088,9535,2263,23875,183945,17750,26274,67172,10585,28042,22199,7478,51331,66030,26774,192929,31434,25850,50197,52926,178158,4679,181256,70184,229600,9959,105594,72158,73974,2726,35085,78087,23284,35568,51713,155676,5401,27254,11966,17569,223253,71993,103357,111477,55722,30504,26034,46774,35392,36285,214814,41143,163465,1051,16094,81044,6636,76489,179102,20712,39178,35683,125177,54219,30617,52994,25324,50123,2543,87529,58995,10688,125199,12388,60158,125481,131646,7642,133350,65874,3438,97277,101450,10075,56344,116821,50778,60547,98016,106135,13859,14255,16300,77373,173521,8285,45932,37426,4054,114295,55947,7703,39114,52,51119,128135,19714,60715,9554,50492,88180,2823,118271,52993,122625,97919,23859,37895,25040,33614,32102,20431,3577,9275,15686,43031,157741,110358,1884,40291,125391,13736,5008,64881,87336,77381,70711,43032,49155,118587,70494,4318,10168,30126,12580,10524,280104,104001,145413,2862,84140,6603,106005,13566,12780,11251,42830,571,179910,82443,13146,469,42714,32591,265217,424024,92553,54721,134100,6007,15242,114681,59030,16718,85465,200214,85982,55174,165013,23493,56964,82529,109150,32706,27568,82442,5350,14976,13165,44890,60021,21343,33978,17264,4655,22328,27819,75730,16567,55483,14510,17926,45827,150609,3704,7385,272531,161543,76904,122163,52405,2039,19165,41623,14423,228354,3369,176360,85491,7122,35789,303724,4465,13628,2233,55311,118771,20713,10006,221519,45115,71021,35650,29775,7337,10864,20665,21142,1746,15080,1624,32449,10905,105743,229797,7701,3940,22997,178467,57208,389057,39683,59403,63344,63125,54847,69691,18336,56448,3362,37202,18282,29648,138224,35867,10495,5911,28814,26653,31514,176702,26550,45621,11734,4525,40543,73944,121080,27858,155561,14887,44670,30742,8796,107455,113472,56369,75581,183777,240095,133699,153299,8768,160464,26058,49078,103971,21875,71486,44888,17156,9678,89541,123019,102337,3972,83930,21245,87852,109660,287918,183019,686,10100,39177,283941,11274,24736,26793,26214,25995,77011,141580,4070,23742,46285,46632,30700,26669,19056,35951,115575,174034,56097,35463,87425,24575,44245,38701,82317,85922,281616,100333,147697,61503,7730,84330,8530,59917,61597,17173,9092,32658,90288,193136,39023,20381,56654,31132,7779,1919,1375,117128,30819,11169,40938,23935,115201,101155,151034,4835,11231,74550,89388,59951,91704,107312,167882,115062,12732,72738,88703,464019,158267,57995,60496,737,14371,123867,4174,243339,159946,7568,16025,134556,110916,38103,191,80226,88794,29688,27230,10454,76308,57647,77409,113483,66864,14745,19808,12023,46583,84805,16015,17102,2231,20611,3547,95740,250131,34559,108894,8498,15853,159169,148920,20942,2813,93160,45188,210613,45531,52587,149062,39782,28194,57849,60965,84954,89766,84453,100927,16501,27658,165311,103841,54192,207341,19558,20084,319622,5672,205467,98462,61849,36279,13609,147177,24726,165015,209489,59591,31157,6551,117580,75060,141146,277310,21072,22023,106474,63041,137443,122965,68371,5383,42146,98961,113467,30863,23794,4843,99630,30392,82679,13699,241612,33601,93146,24319,18643,32155,95669,40440,15333,34089,67799,142144,58245,38633,114531,117400,77861,188726,5507,2568,8853,10987,107222,2663,2421,11530,13345,30075,41785,118661,104786,17459,12490,16281,71936,193555,17431,5944,71758,26485,77317,20803,367167,158,7362,93430,11735,172445,46002,11532,54482,930,62911,2235,23004,179236,4764,101859,208113,22477,55163,95579,14098,67320,162556,90709,156949,3826,57492,4025,34092,87442,104565,6718,186015,28214,14209,10039,107186,233912,58877,81637,55265,39828,6194,145813,50831,105849,4974,88319,122296,10272,197216,95714,51540,72418,23324,91555,8743,140452,250249,51666,34124,7229,38592,129641,78169,174242,22464,149964,51450,14034,10026,95376,26190,120062,14401,8700,265,31386,143573,7203,229889,61567,4227,140981,2466,72052,10787,10062,30958,6099,38471,30103,23202,208101,70847,467,58934,32271,32984,36637,24107,30771,17109,73353,13650,2098,157040,67366,66904,106018,265380,107238,18535,44025,32681,144983,62505,91295,56120,3082,77508,10322,63023,36700,81885,224127,16721,45023,239261,111272,13852,7866,149243,204199,32309,22084,42029,38316,126644,104973,14406,43454,67322,61310,15789,40285,24026,181047,6301,70927,23319,115823,27248,66693,115875,278566,63007,146844,56841,59007,87368,180001,22370,42114,80605,12022,10374,308,25079,14689,12618,63368,7936,264973,212291,136713,95999,105801,18965,32075,48700,52230,35119,96912,32992,8586,16606,101333,101812,14969,39930,759,193090,27387,42914,12937,5058,62646,64528,38624,25743,37502,3716,4435,30352,178687,26461,132611,42002,138442,35833,59582,16345,8048,60319,49349,309,47800,49739,90482,26405,34470,63786,32479,85028,39866,47846,11649,23934,29466,2816,42864,31828,7410,74885,49632,47629,111801,90749,19536,18767,105764,59606,21223,10746,76298,22220,39408,7190,79654,64856,11602,82156,272765,17079,70089,245473,51813,184407,384678,1576,122249,5064,27481,6188,25790,74361,27541,318284,45430,31488,620,93579,45723,192118,22670,51913,4162,70244,35966,26397,16199,50899,209613,121702,287507,2993,36101,132229,67345,33062,76295,118628,78705,52316,34375,107083,107454,44863,127561,33964,3073,154010,190914,55967,39074,6272,31047,5550,41123,26154,98638,47110,19998,148091,50229,31329,59900,195442,19106,61347,73497,70015,682,45850,25776,38022,148951,6288,37411,232526,109277,27286,32342,9262,5220,16651,23175,46740,129438,78614,121925,66914,88710,127952,5563,21500,34521,10739,14863,191006,62956,17359,16749,67027,56284,69134,43301,35039,58883,54466,60823,404451,75743,59856,86979,7923,34273,83785,32142,7693,268986,197428,282681,17049,22346,22990,92245,107180,3357,37104,96724,49153,7683,31197,43267,82231,164276,23696,20848,188364,22309,24821,158707,1018,22514,70922,27792,45589,59709,10765,736,35218,63479,51987,24275,63588,55361,92929,81964,4658,20122,12330,44058,13065,311456,72224,8337,211229,38979,22590,138478,52757,32595,133600,8838,31549,94412,43391,90056,1585,94802,127271,6223,31889,137038,132910,2165,57616,230152,6080,10748,36737,74579,134062,50525,180532,119270,34556,76155,82394,52595,29258,31435,87820,67996,26943,183878,38007,2410,13526,180297,69856,3503,187396,167700,7838,16701,9199,56267,3661,37407,65994,23767,5708,62508,221700,67088,86978,46776,84434,32088,5612,9149,88244,21685,95151,46750,189612,2979,506311,2594,3628,40074,105039,78243,28523,6651,38058,71999,30992,12764,68261,108991,6165,26450,61961,13400,22426,7490,60890,109623,2070,12958,50355,67979,257096,7213,42578,52121,35716,65461,7516,124758,39268,302,64712,14977,1467,219452,2840,34229,11121,21602,19270,63574,8024,1532,17331,79839,78885,52029,180767,57957,6069,91265,61380,55767,8927,32881,287603,22149,35029,68876,6428,199567,46926,13412,104132,21434,366616,45060,110046,81924,128910,45886,52821,130416,29416,77342,21762,67329,121432,79924,11724,38625,81006,102033,28338,13326,3250,82056,82526,38212,21112,12382,111495,3263,7414,86274,93490,40844,30224,45212,24019,48411,71367,24941,76729,57776,3769,38114,202019,197745,31953,237533,33270,201580,255648,100798,44741,32241,98468,106931,10085,15090,170358,33154,66787,18819,69760,25061,234005,82660,6295,131975,16874,9076,4094,25005,17740,40908,19533,220019,44330,99792,50040,19619,13950,55228,24423,31253,95308,103177,184795,28590,82285,5059,3210,75525,49894,70007,56178,10580,36051,139681,21617,98736,3555,106306,164189,37352,63915,47824,24883,145530,61904,28444,11483,19837,145446,30420,112972,85939,11835,191233,2262,20705,58630,1753,148334,1197,144714,6887,11223,107667,60879,77914,4151,57417,81594,96681,169430,1784,20444,95138,254041,27038,596,7117,72808,13759,3353,126776,21074,55322,27081,36942,39547,139830,179275,4453,713,8722,71399,19204,25785,22794,23923,104114,11291,25458,102309,88396,75288,230440,206396,104551,58447,130857,37247,94734,31548,176529,226077,65159,20104,10096,66881,94191,237909,27109,37404,1520,27421,25220,113003,23423,24884,50585,6286,231877,150800,11789,3226,90004,60642,5053,202400,61442,132531,175329,57138,30116,103847,9973,75367,16452,32360,59119,21246,10191,164804,23305,61051,37348,154530,13214,5468,50403,66754,130976,50559,80515,14436,155492,84017,5472,43107,41240,2890,90431,70188,382,76234,48040,50211,281038,237007,32115,142178,1536,22761,96429,1811,31243,1679,49143,55209,17402,235054,61494,7462,77030,34925,87609,78002,9499,9027,73289,201078,101379,63544,27666,5469,10642,30029,49816,132979,95620,58086,351930,116300,2110,2043,30845,6154,11279,16727,4122,2277,27281,4971,3650,39060,61970,65951,39674,75686,38151,11370,130809,177895,32665,63725,122267,7857,39618,118483,44792,157755,178624,136994,24260,41308,22471,12404,21707,12486,30473,52781,50246,20247,39065,909,56825,103158,128603,31542,1089,41935,32744,12428,37963,84420,33134,72921,208449,42622,168151,127335,147107,46699,38216,12591,94342,85814,31423,24944,2605,87542,67473,192551,4496,56321,91819,17630,6300,256183,114569,202090,33209,35289,34897,24967,40520,43470,5344,10199,34810,14283,10381,10017,62923,49924,23233,64539,13051,35686,19698,11570,135555,120868,44924,87065,52318,52335,47586,140906,245885,109834,78668,9065,46990,25258,72022,61243,40838,4545,146387,10537,11557,17470,36930,68104,46711,24264,79401,81043,18225,120488,24746,84338,81652,28266,13776,21878,46973,1047,230465,73357,95777,24973,210160,62210,58404,110633,169651,6937,41870,9909,26822,191062,76553,27519,96256,239070,2478,205678,67955,58532,20601,50120,19148,78501,195724,110740,8249,109665,27446,30568,57631,31425,49752,32820,65504,50079,3663,102256,219898,23849,211315,14645,4359,91767,9528,12449,49366,7941,49763,107848,8930,27086,50686,9744,10447,81935,39513,46514,1670,29229,6172,22312,137280,97759,9806,14445,22976,56458,73391,34983,93760,174219,52573,33149,59747,2429,136277,75123,165263,91040,7446,57632,48633,97140,246081,84766,151684,79918,93268,120346,54059,54875,77858,32996,103590,45276,11968,19600,25849,17159,132907,42828,16817,4913,99462,103303,27395,5737,74184,20749,21160,14377,77062,131403,158735,10999,27799,77785,9320,34366,51593,61070,33746,47048,29268,36675,30262,53297,9832,82000,20188,122292,39917,7331,18160,68301,185935,134830,15031,4935,10004,165845,185534,46923,30109,44134,122631,18874,22903,112790,26561,18549,348902,82871,140345,255565,135390,63556,103747,145055,179600,145662,296111,61661,211987,23952,52342,126343,48450,32919,44277,82185,9591,62139,205363,376969,394874,108461,18040,120885,14798,39863,16571,16794,58271,81025,55206,14640,118656,6361,44092,85970,6262,153863,108244,180200,72264,79947,38044,10050,5735,61221,80712,5471,115689,11391,11661,184257,20010,60116,30320,19327,134598,45455,27542,18004,125092,452272,1549,91523,46567,180063,156026,2608,11174,58848,37788,65907,80194,30490,5786,40775,119519,106241,11323,156297,8425,61495,2617,29675,2425,59886,112582,49142,59618,4863,50597,86710,50650,168632,27693,85641,83643,18993,25768,84284,28090,93592,36627,312804,43381,9887,9402,100931,97165,3311,173330,66805,28935,4963,184460,3201,78102,19126,21607,37496,24938,22615,16153,32862,134792,153318,61120,6067,2812,12826,12792,23825,37559,64662,202250,102694,155488,85881,149193,46233,65383,15521,106982,11358,176786,25752,39717,34208,24510,32464,77742,39371,72028,138229,60688,71386,102834,132477,2208,11548,63670,271279,28351,30338,38620,32491,99845,143885,152266,13252,2825,178663,108097,1775,78201,14897,113573,163346,62292,171129,22183,96598,38733,64971,166776,117445,9968,146393,44677,74867,20908,97328,12761,25656,26785,9148,112344,26115,99176,110121,22437,49547,6180,79320,5835,31392,43328,33377,75870,119860,69497,80273,7325,155219,43167,111173,28347,20222,3763,71752,55041,47252,14618,28088,15012,97805,194698,54636,2036,41349,6173,96604,61530,51859,43782,13361,24334,22668,24792,7070,23441,16789,3209,36211,208475,26242,32880,122181,182407,21444,31060,88459,29929,77907,12716,10934,97005,20599,31690,8403,58445,30303,22700,10336,86731,103115,337709,72556,46788,112566,47684,67089,53548,36874,56487,41387,125985,26893,40071,106683,73712,18787,40105,72992,67246,137276,50802,36790,70328,138827,22466,39263,183295,29858,50975,9322,57397,10654,24364,30383,55799,41600,23584,127295,296610,129078,143558,244131,86397,36049,1085,80677,3820,108139,5476,34767,24683,7758,13060,7239,131671,250593,59556,103392,29810,4188,252323,39404,116877,7651,43600,40338,13554,157253,39196,25978,144387,61211,234,50104,6129,10449,93777,9240,356378,274148,4439,72970,3724,147770,78680,62570,115877,40027,40547,36817,224392,64609,34795,165027,67440,2477,37206,23431,50754,164797,46018,94995,170982,27051,7957,22767,3674,27900,56419,18930,60701,41302,2692,84749,339721,61996,111094,80221,50129,1045,8153,62945,19202,8250,37208,37418,32560,79477,41106,88569,33963,36693,5892,30570,1581,66471,49647,11922,160717,29442,5643,114865,82962,95982,132098,22633,22838,94726,54556,28566,205039,162340,33216,16849,35847,221339,94851,26533,71469,1805,3804,12935,45483,71020,36310,65381,192960,34240,35165,59773,1248,46954,155332,96864,4246,388800,16129,57133,74592,44807,442014,38203,42574,80818,91592,26377,36424,65760,977,77387,22628,147610,28018,30561,98454,6969,119628,63648,18170,36854,26601,64018,22027,37279,51395,152934,21153,9430,58760,194742,5330,55115,34158,28917,174111,13171,122326,1526,43896,66094,25325,4234,148354,11450,275,18999,112191,44365,22723,68409,8733,57746,96565,75007,14196,108844,29475,88599,177563,100792,106156,86323,93726,14248,135341,194131,40126,47099,14779,8272,39597,95983,171398,65882,28052,10393,47213,40689,22120,72212,106829,34964,109146,753,648,21660,30047,17527,181025,5619,145357,4085,216883,9359,186951,24779,53931,24545,36197,223296,62628,168101,4243,107313,30321,26642,13049,51059,31027,107912,807,73550,26551,84369,122422,165872,49754,74213,234264,33151,52014,33100,87183,22365,52500,40013,23302,5652,72723,21404,26107,48434,587,94049,168493,96418,32871,70860,31709,25128,443,71597,166253,15670,70994,26341,133675,28280,75491,54756,47955,56028,26182,11952,113272,472197,64640,110753,17919,337,50642,22576,142,87371,53391,93210,126694,15285,19642,85667,14148,1506,42092,52962,33243,11970,20734,135843,57044,58880,13002,219134,22876,64754,232519,4257,43120,321573,24799,64526,124728,52579,81472,70831,276848,17403,74359,23021,182101,74597,23744,148267,12055,7976,5349,11772,67540,167347,65318,18720,127832,108238,22828,90233,9987,259080,118185,73209,79270,13775,90100,137742,90799,70569,15699,19961,9087,67475,57872,39731,8810,134897,131868,146849,19898,3334,2281,167061,91073,60356,467742,74712,188,53179,137679,92769,29241,9537,132595,80119,1041,88962,5976,40171,44911,102859,139059,104558,98987,47761,19272,71472,113864,175377,73338,10857,23402,23758,1591,139864,5644,4076,118760,16427,134198,18853,20291,100849,37423,22038,36677,19071,195521,57445,11069,31869,55718,66882,148490,44,41296,75242,49704,166810,9906,20943,122258,49112,105667,15969,10344,6408,187694,21399,72742,58970,14867,14376,81889,41856,23225,15042,56993,16074,131389,74276,72407,53875,383108,53597,37363,68993,44854,122548,430927,198279,38430,80409,12245,2981,628,2818,17760,37437,238229,7968,46892,2200,3730,34190,65983,37959,112291,87850,70827,6522,20750,73913,111621,41652,19587,2780,58668,25916,85259,18200,168962,95781,42445,102050,7776,57662,103313,47742,96358,41964,66174,100396,29069,204735,19679,27978,7479,40264,22534,61183,36081,107436,58223,14680,23002,101311,24716,124108,12908,5646,31750,40380,14215,232799,102772,14122,96775,61398,50917,12096,149880,67833,598749,124194,155871,49216,790,14677,65319,56917,7440,145744,95701,12206,49405,129269,76199,45732,9767,11058,9047,210885,11051,7392,26307,2130,8132,147526,20802,232698,115660,50060,59789,57344,107623,80343,112676,23291,9866,160971,34032,118291,15719,59730,164911,28975,2659,58046,78480,21854,66209,53863,109085,116045,29021,46481,107552,22130,18764,70254,31272,11300,52460,43933,84738,20721,53869,190840,79673,105300,7561,321817,66924,13940,33281,101046,183181,32176,71878,5678,62924,79535,56646,40303,19559,27703,93042,73368,42187,3670,37376,46440,7023,36816,109628,20680,5940,276440,275233,170848,112093,136996,14984,20226,111441,77693,112960,48577,39370,55707,50314,123404,26570,54281,61372,123391,4857,35928,246740,132507,106646,44241,7196,92258,9825,37688,51197,303141,5590,15476,132986,10955,85782,34486,26696,7991,28813,18858,39546,11703,11365,38185,5716,93555,11925,40121,60002,6985,10976,171384,3887,43394,13337,56346,6381,252336,39573,75042,53711,1028,31781,44295,95925,131713,7214,68125,43571,70954,213234,1628,8760,13391,65485,17320,56038,1710,25248,60803,57399,19839,3870,326,281556,50945,72400,21460,316244,75619,56246,98775,481,13513,55765,50427,7388,123519,32929,57908,27124,61316,101097,57467,30228,48792,10788,20402,37318,50526,155730,34456,158065,145305,17832,43733,64052,4506,35072,205355,177028,184004,187081,68616,35938,83703,10367,36892,93186,260137,51934,89970,4985,23445,26755,21558,7948,78741,23376,124405,85594,68596,57536,49351,12619,56593,132668,99924,109728,71844,71935,196018,65464,17617,14987,89701,143773,33997,8687,22701,33258,2914,4436,72108,85610,9671,49067,2327,82988,1361,1672,44033,35777,30269,24057,10605,82236,616,15793,13919,47249,112086,116698,9484,80207,90574,33304,68624,93127,56101,42210,160929,4827,38995,38095,4701,125119,5027,33680,9236,231236,14135,87837,23318,70261,78893,30151,81482,14332,1084,74256,27532,46644,79185,3148,62615,6981,55672,31668,36825,1849,14536,37446,14738,23779,43058,162749,72199,1168,21346,5592,85932,85302,9668,18351,57135,150360,2080,228015,77953,34670,119302,151751,31009,106725,84265,45214,59289,74178,113071,263206,111009,4021,44449,188119,192629,123592,392506,292847,114487,12831,205858,9852,20780,79648,75767,357014,97721,18166,21005,67950,33226,204009,16536,2987,11335,66717,144910,47950,17262,55060,15063,2934,51038,26775,178497,66008,3427,49433,128592,20036,157553,63861,3089,23015,51210,28696,35933,49942,71135,231518,99620,17248,21835,176536,20676,16944,38700,165831,233253,295625,36723,13023,52745,10907,19423,67972,125868,95473,82875,1183,108455,52685,33417,64095,21433,52438,33191,127809,44505,211823,7810,2752,95548,162031,7185,91196,47563,61721,33359,17897,23682,42806,178101,22874,49707,199897,75419,82456,8618,11171,79712,116847,18783,44190,46564,5346,59046,95032,7893,14916,3214,26800,24172,121453,34362,10250,17408,18888,4840,68696,22831,13162,36005,32512,14800,62357,41723,45046,27247,37486,5372,2564,34261,298500,66509,133920,89138,31305,117697,19097,108304,81386,84106,23802,46411,63304,946,51417,41777,41041,19501,115864,60743,294354,37955,94165,18116,1156,17937,20645,57114,90804,58042,48643,92288,9861,2557,88546,61333,101008,12853,5148,87856,4152,144503,73841,18718,9789,147565,10846,42085,12789,30223,8993,56352,67203,2448,28215,6052,23540,126319,75933,36689,80235,23231,23561,21383,38800,77548,102798,21234,31468,158608,46188,63960,191679,8051,67014,11185,170078,42186,28827,34777,41930,212079,12421,34750,24111,110344,73918,45171,70826,141949,40063,23979,24254,37309,26724,27179,24718,83648,54938,14591,17425,29525,102675,48975,48654,12316,8929,60640,41709,50168,63264,89812,50716,48632,38755,138583,160123,55579,71829,24230,233277,46322,39650,166388,34718,24108,98252,7031,106695,62498,18258,35062,217827,78731,34824,33354,19520,60852,2432,60224,8587,2836,62955,702,20227,42285,40560,95592,62486,11094,53035,143291,18842,46177,77994,1770,9657,107422,172915,32655,128716,25886,25164,156740,119928,165875,85817,11007,89110,33956,12652,65156,180266,8494,36889,19958,20955,96,1264,118288,135769,44754,86671,5632,19026,168220,289120,33569,93821,66144,70635,7687,5642,2714,55445,56636,71545,184182,93133,7332,37389,12643,52315,22729,11014,158742,17050,152889,50178,34601,41945,52136,9948,26914,63548,95721,115951,40759,8960,158258,38938,49232,48325,42234,81523,253019,66128,40978,20048,238048,38760,62928,122560,118532,43687,137472,163689,26680,9878,17448,51035,16211,60834,36749,29178,14241,59868,150086,2305,26477,42422,34342,165341,83279,33894,14257,29928,12743,13957,125571,89134,66712,10952,16507,147839,30146,7249,16565,45399,39874,114565,215780,31990,230881,171477,102,196546,44538,10880,84948,281705,86651,10617,31395,2342,453658,43569,60561,132901,21845,17727,58556,258242,22262,58728,4008,77997,11806,37431,30599,81375,109137,185787,114085,217292,97453,169085,30593,60212,11544,102056,65580,2384,91655,4855,95725,7295,157994,16228,20669,53276,141590,105246,17334,25440,76067,17967,39321,38911,11362,28559,63807,21627,26468,85816,40120,1025,15234,58319,69516,66512,124548,75845,78873,22137,46681,51242,85683,32909,76747,35555,43396,101465,1765,73094,1077,2962,39028,66777,57831,42048,15828,13962,36041,63657,52412,5242,58846,2141,5506,219012,134451,3936,182230,17558,17153,152237,22621,49377,170216,35257,68233,65374,6510,11126,212151,7184,2480,22517,3437,33073,30156,16557,3768,55067,86829,91000,12350,148650,66017,79424,70885,49066,28250,21369,51213,34533,11510,3258,18176,18465,84413,6315,36411,163765,4346,356,107618,598,13727,285026,162695,8749,14583,7132,63521,184253,32378,25991,5604,30961,53675,4874,84693,5086,34811,26978,56564,7904,33519,51221,113942,69253,6664,125563,22055,220680,102008,742,51930,19494,176108,44424,35123,13025,75685,11759,74335,22250,181453,131147,16984,132115,154311,11991,76452,52609,85351,196,30969,9198,74919,2529,56838,71779,29187,116304,3504,62330,41190,86153,28393,254926,104228,105189,13264,84359,3574,12415,8534,57147,10175,188174,59504,60932,66318,16407,107921,17638,99103,49278,28403,39786,145865,8462,3558,43406,142271,29139,21989,36552,93955,72365,7176,13556,106185,37957,321774,17782,129017,51154,27938,24952,1935,39366,2791,33489,41582,56078,24558,9311,5449,218786,27808,190429,68013,36020,86003,29735,3404,87348,119357,115714,2324,86796,81973,40992,43376,93621,28784,16808,36367,2517,2909,191926,24978,55303,53308,205724,60068,3098,21375,64784,23949,26579,63121,12319,80145,39967,97861,6757,70143,67642,37082,34698,69140,122883,46151,62187,80934,429,19437,135071,137885,222647,13331,154065,327,61778,74257,40116,37493,14855,85079,237641,42342,102164,199965,71204,4662,29368,5042,113914,122214,8955,13149,102503,43173,5659,163787,69003,307084,63392,171080,21390,81918,86666,36622,24126,28887,5736,28054,207170,163428,79891,346467,95363,38980,111806,80828,9200,19288,294896,114468,87405,111715,141705,7015,72754,68463,48738,243147,33397,101210,37051,98801,82847,20397,4940,185559,18716,54718,83491,11725,40803,1128,12128,23060,5174,7745,67007,46701,1571,27807,180186,256996,18975,16837,7877,212758,250379,15440,87954,57755,24719,124057,83461,258,50864,8874,29038,71289,31627,15429,9005,4061,113851,107716,82819,13651,79656,117851,17539,111446,12938,39724,190787,4352,15402,21070,62708,8539,23777,73853,13552,38810,86117,16285,56400,1718,75342,142863,29033,378,110113,180321,32586,23606,26393,160984,207987,23783,8406,16904,24596,47274,11693,46539,60524,78595,48423,31718,20170,9009,146268,15183,191060,172765,1349,138436,37365,10970,40509,225817,20021,70394,152138,21541,66559,66544,89352,2725,17258,91345,7313,3815,115868,8660,40362,4071,103524,39388,118275,21950,6549,38226,32754,209574,29201,43495,18028,20296,40597,18370,47520,202450,24134,2219,8195,69545,38041,136934,46374,19041,159811,84865,58620,846,98749,13569,30714,97246,32186,4479,27355,92973,35214,151491,75963,37631,1561,27200,238083,23182,60756,12291,25766,39355,102333,87362,65741,59906,19538,201575,48772,102938,24438,292580,39964,66366,9004,61379,50548,37622,38732,28379,68180,76622,17488,69849,5963,7219,48143,43413,55358,540,58691,29506,19245,52193,48621,5518,13048,118625,44755,191081,42061,89197,2259,60665,66994,71210,51232,3585,142096,55024,7892,8345,58653,463307,65658,64319,137941,136323,53499,12746,43492,6978,95163,29925,60175,5128,7352,41463,184756,121146,20473,18426,4598,5309,54580,14277,121151,10691,56711,43880,63409,76682,11830,172218,264898,32632,66536,81062,31649,25788,92774,60222,11100,63159,9432,224657,25240,53613,152,138620,163829,2397,85345,12501,37507,64932,38575,43522,65789,80198,78796,35226,3851,108891,73311,3060,28391,93671,39663,46142,30982,66041,37281,68157,26553,71872,81142,211527,39747,118119,22695,2859,11066,20232,168911,7933,197005,17066,111071,44434,133994,120798,12766,227798,45756,132852,29917,36076,55352,65281,129800,41958,18944,84678,18580,168093,132621,39997,54092,27740,32354,3770,114118,103242,43918,15899,18574,145944,3190,123469,219903,24169,100571,62403,16776,92779,14535,17168,16475,14304,37231,1712,28218,242754,61688,28980,1318,51359,222657,99200,67989,31772,23932,35351,201251,49041,27306,19128,40135,3986,77333,19649,120683,151927,21081,7076,78375,77501,101599,8011,89585,96715,58179,5378,102138,106793,26051,217276,4197,16297,27014,46721,13322,22806,5278,29629,70632,9647,71519,58818,40603,128530,8903,36770,56900,31483,26935,43845,34265,34920,87658,6114,84767,64250,47318,50720,19264,162514,33357,13117,6705,46696,75032,71054,87004,42035,69138,11903,99854,102328,19611,34525,69312,6431,49842,101600,133178,108751,41829,89939,225664,48916,99556,9195,130387,5960,36857,116724,53518,94002,39077,53996,6945,22261,64291,8314,152785,57588,16522,9091,5048,87671,35441,39509,1945,12423,158923,178413,37549,14095,1475,73188,62878,4819,24012,68534,42606,4010,120809,57497,59564,101758,103718,32701,80116,12345,95834,46918,21468,53213,15665,31200,3867,5140,96013,250744,21016,10069,13968,35449,180829,27683,39704,59956,22893,3115,26293,32785,75934,62445,141162,62720,2018,83638,19949,114012,95006,3330,99829,130935,309272,9565,55874,121727,37017,23586,319858,40970,27602,8625,112329,61060,100088,118525,25922,16232,1907,60671,51583,44553,80993,5262,94679,8676,940,20736,11823,3020,16476,12340,152600,97416,3703,25744,66826,16245,16876,46446,84798,74227,176020,45192,61955,75496,23946,23626,40372,26036,6149,11822,30582,16541,41914,82385,232823,40921,80773,14930,3631,7517,39619,4348,36180,126106,138939,62611,1477,113512,47321,25052,14546,118881,29060,23589,128322,36795,18401,137921,104699,267929,36194,172791,18113,4766,188215,30083,332586,94089,5805,77909,22194,68234,154976,43220,40660,70001,184893,138095,11128,103010,22663,5108,212615,8485,5565,49222,54614,26530,42639,16319,55062,152662,105595,21114,22216,10294,68158,10436,86950,7206,62115,3977,3657,59874,456,118617,18156,106663,112229,80992,17442,8217,55551,5133,34344,251927,51153,39364,201321,7816,66803,23057,156724,145664,14276,95705,979,2796,6875,13429,212525,50602,26276,28284,3424,19465,52397,46963,31420,51399,206476,92317,48851,637,100820,83349,10317,60227,21972,6908,282439,32857,224767,95629,83882,42106,87338,69757,29840,68709,37665,45244,114577,49188,175943,54009,186746,106158,70168,3358,234002,50555,9221,129338,9562,20118,32923,78479,118280,65752,4977,10474,102174,60947,129006,10570,83451,8598,8078,159367,123785,80438,16742,5905,5281,181513,42402,6977,163136,93179,42191,14968,50421,112401,105440,33456,57347,121611,4221,94954,36517,24046,27796,6255,33394,72990,135408,116627,1233,57874,25654,95419,68156,401399,313338,55208,45573,93124,119251,47200,38196,11909,130667,45391,73904,64964,167846,4137,115606,52036,62214,7969,160925,7187,1132,134835,40309,73195,64494,80472,444841,61111,26500,45323,40743,53625,52797,22659,15631,29739,36706,28841,39147,102836,26794,10536,14845,87305,45874,12241,127587,83833,57183,79722,30844,41304,84655,20825,92500,3722,25655,27811,10157,81634,31362,34088,92487,70123,22190,185100,72658,139035,192523,88241,2078,230490,44528,85638,100198,22088,29982,291233,241062,13865,4445,137791,37835,107218,31726,19718,38234,72528,23046,19177,66695,5109,17251,28077,5617,21554,47839,72425,133825,1486,73065,181275,141508,21768,62971,63082,2512,34200,9904,120309,6392,91243,68416,268253,41199,116757,138551,185526,41246,28986,4093,19057,17295,4148,245766,122360,35356,112075,20301,75441,10998,7977,19769,62922,937,63547,100196,26427,157820,20983,236696,22935,8140,90315,156004,47204,140973,7726,45097,52725,22636,23436,257282,105247,522,88389,216031,202204,46812,211666,19693,68828,81691,45925,11256,30292,372,5236,167826,88328,232776,151611,5360,82104,18841,80393,25465,18285,20320,72377,31730,33160,45803,38715,27705,37379,24163,18360,103586,4015,32305,269494,91252,20080,36567,54650,7797,57073,12650,31164,42209,6375,261663,105528,81661,106002,2800,5375,17247,43151,4442,15727,194619,100855,144898,62320,78465,39929,16454,1967,28311,61363,17219,9395,8745,121445,76939,80385,162380,22009,54191,44248,16299,122830,48151,74429,78291,64755,14238,44966,2511,17712,67954,93583,829,105899,49935,84750,11591,33185,85447,42717,27409,208542,28965,62052,52525,5597,25694,65594,16343,63224,276188,12475,9331,127507,38522,57287,24128,133161,79723,105548,133695,48917,27558,43278,46520,13778,141954,110785,83366,17715,46317,105763,66298,147013,41086,94180,16478,220447,44611,730,19722,78975,117889,125643,26254,16574,18480,65006,15806,38549,246418,46052,36056,8440,34984,30170,3163,59800,4458,115442,4283,41970,33507,104078,1653,22,121158,276486,3655,6338,24048,133421,23641,2161,24422,36006,8086,10675,181474,12307,29514,59143,14729,52509,87128,122470,19446,80852,33314,24573,119864,14237,9652,57779,6612,51851,15284,98871,90581,124466,156831,21190,22015,71380,161906,87247,69201,18392,17908,108470,72962,40719,14338,17911,95260,43339,20610,78916,20710,72451,11315,31448,17263,58853,178878,48111,116002,45497,80506,82605,85880,36300,121755,25215,36118,301929,88728,405223,276136,553,34704,212438,49970,78329,922,20711,25036,257130,38295,145369,18128,15385,30829,55656,48345,8012,3561,28004,122041,192900,58338,112508,41085,29976,87040,47117,23905,4336,92061,138880,97407,42083,172121,6256,25192,172671,5,93568,1420,12677,31605,56743,40620,6015,78415,231077,31298,80026,13902,19048,24924,170586,32955,176119,87859,36731,6773,27711,24658,26475,115216,133207,93250,95820,88522,8317,5714,124047,55219,86860,19677,23961,22928,162209,8904,225992,359835,56084,96201,29392,96558,86071,93643,55114,13347,8183,95129,82012,2017,123336,34219,115554,157159,47747,101684,41008,18735,193781,104151,226906,7552,179874,124113,31159,21162,44010,14771,51268,166128,31382,73124,77438,92830,205709,12113,1292,38937,13114,1334,2118,15597,69581,14449,21934,76618,48728,67038,14967,51495,24243,87736,147249,26720,11119,46063,43749,5843,44147,152629,133428,65703,14269,45604,57982,28672,55616,45957,8438,95433,37698,220862,132034,39456,61870,4161,26501,73560,56418,9845,4654,20916,10456,88920,119358,9015,65931,96507,48029,38534,21676,109081,43078,34943,25089,6131,28766,23665,5477,10255,16695,67,45778,42443,42770,29534,23733,100513,62617,42630,48746,14191,43753,50295,26007,8792,57243,43119,54725,164253,58250,112304,131796,25165,4651,3188,24831,47748,3705,19540,13211,102095,5593,18699,23666,32005,117571,33541,60584,74573,86311,99443,25172,27222,168938,7143,11853,53560,18834,19960,86522,28217,53266,117700,72989,34323,18721,66450,34346,74056,47217,202002,46269,9429,68582,75458,37823,82843,96652,32549,145144,27958,19820,158086,31955,201406,135379,31207,192545,12950,51704,9094,248263,76147,64028,110009,79407,89345,99284,223492,47966,26848,15359,201137,2861,110507,71231,72297,31851,118777,71039,151051,240855,16333,50766,14727,7939,4149,80908,418780,88378,59276,1327,7284,38576,79814,65820,42199,84860,49574,62596,12396,70598,40117,8648,7994,16836,7630,14047,359699,106878,525,29037,28064,13380,11675,50669,74216,103539,180314,27449,56299,172344,19274,7301,246099,32043,19422,36506,129317,6806,30140,4614,46639,66926,932,86600,6322,27847,233103,10541,39025,34887,3517,12972,26220,2031,66561,115015,48658,47596,12714,33845,3893,16165,35237,89983,14769,11962,147224,47018,29977,27979,5552,82338,86023,131368,1218,24853,237840,132193,15455,40873,3668,65351,53388,15229,59889,272245,47934,11858,34347,18038,90853,86981,300602,19343,114181,29362,84921,6095,106059,79472,38015,1206,48741,6208,80000,21916,17423,6002,108083,24479,34931,56661,9511,26995,100694,163853,35997,81254,58321,18919,171890,86877,91341,74503,70477,53412,7027,59281,39892,131302,5864,15947,61301,67466,162369,47956,27874,35624,282324,21270,111847,102548,41482,30955,116737,28264,8592,55458,22301,75090,29821,30697,51709,3041,19208,8038,24634,30467,87509,126428,19389,18814,152686,20701,83474,45832,80891,105808,11378,153223,120770,98186,150633,49838,9141,12755,30962,5260,74490,21256,31678,65062,33326,289838,187831,20595,89768,2805,58535,10844,70085,12090,2451,138068,98544,24461,4511,6754,41684,28203,3383,65355,82833,30161,83924,234361,128424,28921,222594,33975,125491,34069,11508,67464,144226,41850,98703,34371,7901,21254,38398,65651,23549,53883,213340,123269,12028,71764,177701,28758,2623,68395,11549,15232,68603,9660,63116,36079,57093,31198,20475,48467,89984,35619,186847,107469,31389,43631,73867,41949,68841,114250,1605,30564,63403,17588,27680,99533,12641,70325,50428,73426,78379,11855,91651,72081,91720,60198,15743,12065,83398,140046,6761,46598,45900,5068,886,62448,148968,37347,19405,9680,15819,43496,63370,75667,163700,37639,3633,22774,34341,183131,134335,37200,23915,7054,14194,12970,26438,13350,285521,25594,8219,104410,91039,168804,138480,149734,15907,33818,61132,60082,4622,110187,56736,13551,73571,3945,73463,65498,17758,263266,17593,2710,27585,54469,38200,45367,63754,28881,3473,12791,98287,31895,65787,4463,94536,24951,36332,59901,28803,52130,86403,7668,181822,74831,18977,9850,177206,145485,109798,7292,31421,26280,77211,58511,12507,127004,11113,147,8729,56208,43066,79926,129937,31345,83947,39915,46146,98763,42566,1337,13192,18323,105163,80570,117753,16555,72883,11077,159438,40764,70933,83329,26066,12276,72059,21655,173836,126713,69454,153482,91585,70644,102558,110483,6764,127864,190133,3961,101798,20945,71138,82402,90884,69669,44753,923,16939,59700,164258,25969,27082,31399,43846,6306,246093,51342,6153,151581,202801,182731,56475,162188,89426,141356,14355,121815,27536,28023,65257,77523,106668,127314,24947,12790,38796,169698,23555,10725,44573,183083,42088,62716,43265,105958,32050,44067,50118,1668,3874,6243,318411,16599,1691,94999,52378,28671,216728,123258,2059,34969,69225,5913,136280,171443,141515,91662,22175,135282,80020,92270,1663,4808,4482,3495,34691,5226,109830,108512,17342,107488,11606,123190,100247,29666,146527,113014,15794,30894,13224,39585,243192,22351,9903,7836,47699,11078,25468,122291,48821,26780,122679,75521,81450,630,4895,92900,55074,74293,17441,3563,111657,103102,51613,12318,52370,36191,68245,34269,40445,41354,122901,168604,182500,62012,42557,11259,24428,115113,86345,12362,3909,78430,86852,134602,20459,47853,93879,22577,7659,3688,38555,13349,17381,56715,91639,12493,10895,92438,3142,37057,28928,2004,36427,32268,34222,209974,10432,67436,41989,173518,107930,27079,62729,30908,55558,5828,45031,14902,53546,8204,144263,60255,14520,88212,86582,109589,69356,8064,47449,8505,66558,16886,4844,52817,111260,215129,12941,91118,650,20770,6273,73089,40618,62790,2873,35002,14023,97208,19386,102646,36993,143736,135457,35385,113601,17893,32627,84439,100619,56016,6581,57264,172160,45452,111710,203627,70131,24100,322787,1996,35665,70078,22358,90922,83658,4097,63200,58499,14542,99153,52159,6615,12414,63415,31986,16823,1579,65405,137809,8841,16898,48082,259,33014,42375,12260,179850,73667,91389,98882,29532,17311,326251,41092,5928,20742,44964,48019,43505,9317,49265,6643,192712,48424,163487,19861,20113,70848,31928,105333,23685,78563,14638,54755,7158,24142,44018,20774,125255,20331,24280,10163,1285,2336,39851,4299,117269,46714,63816,87779,159624,11731,9971,990,137317,108831,50994,74554,162680,23640,131597,146962,170620,34829,91205,21184,1913,63616,18427,93136,156592,17519,67565,115882,138220,78622,88535,18115,2711,33554,109492,54298,971,24914,25863,36363,45715,27099,194995,14299,178181,111488,72395,322385,157719,130787,11897,81843,83999,11369,49280,118604,40922,61332,110343,53407,75639,40582,300440,54722,25637,13694,48248,48278,194521,56203,52779,48783,72627,10953,376,16733,280238,26351,230789,15132,25168,137270,3588,63704,73376,94031,74284,19443,159557,9697,39901,13351,119050,15406,146455,3460,29556,75195,37673,102524,92329,47289,98413,15311,100684,56345,7116,95480,11590,7200,167,23610,58426,17730,136656,27944,53151,2701,8824,103124,3017,90744,113588,53216,79736,65940,26931,498,29568,80540,143543,21292,1740,59268,16561,180816,42323,50174,40890,52866,10703,57169,4700,17191,4424,93511,49698,166650,26972,48631,165169,82879,69326,202970,4007,2376,231325,139592,22119,62851,37504,68816,58345,67398,186643,43331,277416,53749,15746,23102,17432,4793,151138,48822,54265,48203,198688,14305,54287,2291,18018,113378,123260,7180,97549,87027,120085,2920,76080,8190,102005,5641,64580,14955,59802,54028,58884,19367,81779,412567,85957,97053,103637,78871,29364,27637,141728,4767,30686,112738,130146,42745,12730,105040,14844,232,210944,36581,152317,135543,29744,3129,55647,58149,46319,27265,17499,28005,59948,7170,34138,5702,293047,110892,408,91760,218674,18469,46095,81403,14389,4610,35672,73060,11006,74848,104820,118143,190357,20043,105358,141735,5115,27093,45924,123073,52599,29433,9616,238350,78610,24851,58858,26769,31969,24613,18294,4982,32735,39639,143563,112073,202205,12567,4873,88601,44897,81503,101648,81362,34662,85277,17574,48173,21435,221188,40215,39576,80786,26544,64668,81841,10731,37733,247986,149188,127703,495,18382,54388,72446,43071,30974,198723,89608,41360,190,33045,8386,31658,19992,237838,119015,137622,50890,100913,6460,116233,267230,26621,104129,65114,14190,41542,14888,85962,23342,23041,26453,43725,71809,45186,4770,46452,53894,56616,221286,18973,9038,109299,55365,19366,26863,18808,60909,69353,41738,83463,12100,68561,72860,3980,13796,49340,12332,31311,27418,4255,53430,18976,45523,510,14224,30477,26581,4530,3651,101663,139840,22709,150861,31996,63923,120623,262522,3076,10528,2929,14672,130238,18087,9816,121894,100308,25085,55111,14565,18952,53293,2042,369988,23674,61789,133529,28783,108293,35477,47119,36448,71049,40015,33055,78598,198442,1833,159937,40654,77444,189245,113153,8621,18599,38553,35223,166072,2375,11659,21786,89523,6032,12116,63046,159398,18454,3678,32521,47626,11411,103527,38896,42946,15696,26370,10185,8413,37080,165583,4331,63555,14907,72220,50056,6623,62236,36565,49783,10049,17503,100581,55951,146244,24724,9626,17969,25524,109300,173965,99994,101056,46459,43647,53737,277968,8347,123521,74858,33829,44762,77574,877,81377,222525,123532,30602,43881,53145,2973,16284,81940,61281,127044,63620,9875,14756,114829,19032,9202,52759,119141,23928,120551,19607,3599,33401,76821,73233,117430,39968,36539,7071,5446,121735,194059,15206,45283,6706,15603,65615,1207,165723,92275,34773,104447,8396,32353,205240,164323,13600,60555,79205,25532,22907,33410,57480,107111,69630,32137,47832,70913,33161,20321,2371,117348,10714,86246,1625,11763,17900,268,78457,99175,97940,101092,86660,32221,14041,128504,125080,53744,124263,31017,13897,403,31859,21964,5633,111630,5547,77329,17961,18241,84995,25984,12983,67491,62168,47262,5241,297,51191,7351,8967,147212,82060,16821,782,11033,82431,62957,5026,43459,77963,203477,53528,6247,191852,87774,74164,215654,13467,1522,219964,28589,244104,16242,117821,67725,72570,156792,17186,15979,26990,44128,193014,35276,57125,16212,166451,68017,6905,77608,16364,53777,75921,76426,37975,26203,269296,64099,84122,12077,38533,830,4407,20139,963,43028,38902,42911,37503,83343,85045,16979,1165,60835,137387,58380,86990,110066,134540,56331,193845,81238,17922,163093,38744,110641,12502,56404,34862,26865,125964,12965,111648,25547,7771,27196,136980,9555,29551,107158,57885,18831,37705,35505,101742,13970,102109,62548,124657,23328,11124,89592,146376,248050,6241,22033,18337,80685,29898,11908,216623,67721,106162,146610,21377,15085,91552,42041,62560,122532,125336,102365,121537,142559,29693,223919,11515,110495,18776,22494,5895,185059,103592,229351,51220,100102,37027,257855,29359,54123,36066,106493,12244,79258,32002,432,56205,94836,90182,6726,14762,29391,48938,26864,38083,60364,3310,60192,14766,205567,57504,110760,22649,24666,46333,21517,3430,13135,28873,27052,158809,11597,20529,6695,23138,22960,37137,45574,6545,305877,43423,26153,24769,59844,14501,10430,134352,56169,13213,103432,49523,35181,13435,12408,129475,64620,230854,77390,51990,15653,83248,33466,44571,117828,51481,2187,10559,68019,18021,54895,48247,18354,33737,4554,108595,37288,39767,116707,9175,3726,108877,21616,83684,49862,1938,8543,276466,20134,108498,48770,102254,31914,131520,185291,100559,51890,209,19526,76471,50544,71814,99351,8172,198526,28816,20419,9109,98389,136777,76479,75596,30635,165417,48216,120220,25955,211071,39314,24308,32164,2559,146280,43403,9233,17947,90585,1786,86920,125662,2457,64741,32152,32918,122882,78538,44001,31723,56426,23375,103172,88177,145697,52506,49319,68016,31664,41488,18486,110400,7030,28241,986,109199,19900,42147,56864,65287,49183,7858,24000,30453,840,16673,25907,68916,89927,6309,158335,36407,199737,130464,13137,59603,201778,195292,21015,42466,179062,172561,89492,11075,180407,31868,72493,20998,60217,9865,19530,39274,130266,54539,21623,12535,13505,40641,73375,4087,85633,2153,3117,70680,55788,92096,47509,98493,37490,271936,151475,3032,16171,96642,34106,78425,125761,19591,3366,19316,54508,24183,50786,194248,91528,33253,34622,108355,41741,705,3814,3883,108929,13203,67831,10142,59754,68208,29128,84820,56880,38794,24972,48571,40821,40476,18137,164254,24064,236309,79181,11282,395,39169,2013,51587,28551,9645,701,109513,115899,113566,12762,62045,58322,103726,41343,40866,244102,143816,2490,70346,40973,52618,15412,30720,104315,38917,42027,93676,17513,107418,20706,123890,13399,97727,24044,87962,65606,44250,98044,65276,74790,101473,19350,91570,1326,87790,172042,7577,100813,86896,85891,41512,108130,27794,14875,71431,12835,156250,58135,3759,22476,42176,115873,34686,56523,73643,108505,51491,20838,12721,32863,45700,29496,13700,34294,55360,29206,155942,123812,7706,163234,203,132720,49358,144431,8130,175788,35818,3270,76832,25710,54095,97274,28779,94621,74396,19092,128242,58067,20885,14670,93255,15107,63291,23654,126900,129421,59294,262659,9798,3251,67344,28600,44629,50672,29072,26999,31526,23183,49175,165843,175455,17282,175411,32022,45989,30298,90690,78118,83156,23749,35636,31317,7069,80381,94561,133756,14960,97404,6138,41065,78041,32843,16601,34123,9559,146529,123377,96395,54441,42012,84257,123541,10745,22139,106459,11720,150883,172651,154996,110538,4728,53447,25704,2009,71152,119354,21166,66604,1429,216162,8637,122250,63520,27180,29172,36124,276428,107787,77184,4680,14952,104903,24418,14793,51561,52931,8371,26342,48526,7118,92066,67280,40653,8847,34597,105438,14198,50163,61188,146286,50315,41205,170829,161496,585,197359,95056,1687,365794,91349,48507,5804,49263,5146,104902,96365,117343,132222,46084,96919,16875,8073,262381,79982,52663,13928,16056,153908,15145,109256,132308,18763,24904,167644,13618,40750,18686,147124,114709,150038,52849,2938,12568,48617,8778,5459,44202,44591,74914,17183,248689,13878,7822,80060,23116,194037,18487,2067,7798,43077,33678,244028,31320,74273,2794,19466,8218,36280,183997,48124,19416,29656,19280,98734,7715,18311,30701,133602,150307,126956,7378,2933,79903,13178,12593,86571,26604,92446,13574,44205,65699,427599,21118,8245,14407,27877,47936,33542,7916,26460,117762,21596,37818,2249,127359,209394,60044,47677,308089,36791,154971,31417,6998,150042,174360,12255,43009,29335,48739,3912,101398,53340,2580,146939,151295,45360,125275,15273,45383,27456,48761,23314,8750,60801,85823,104759,27894,123685,66968,39480,26917,55290,83305,2696,98390,57569,145853,340733,4919,20024,52268,30884,7413,203685,70989,112855,4129,50536,349518,68205,332641,159581,135361,236026,37563,176404,64899,6578,122033,63871,1850,85234,82089,66124,74145,121098,107351,12687,36881,117334,13136,14698,85933,93866,18047,32620,310,15094,46000,88451,23632,36645,27940,87618,80520,58892,20976,27702,140090,96075,67841,103292,238964,87778,107338,17019,83427,67522,7302,8261,47570,116787,8730,80484,61772,174422,56005,131193,52875,14588,28471,59817,9586,15720,158155,51307,109734,15196,11025,59331,3884,52626,102602,84797,25158,27314,4437,20488,76214,189248,35023,114952,157376,2827,62439,102878,129749,36405,10329,109339,108633,36662,1254,13267,5470,87105,58004,15397,10434,159667,21864,52022,179464,3013,32147,31496,116832,18494,105502,129227,107267,50033,13481,9954,24267,22141,16257,116154,36185,950,115685,11305,176708,2048,178671,112573,287867,162328,497663,95170,50979,193861,50987,30368,136257,31830,46549,15119,169876,23788,17462,249887,57377,1949,35448,14791,43769,210091,3783,34612,282103,88380,245190,5457,20491,98908,11402,86899,117916,16028,162584,60644,320177,156096,31065,55876,22000,77655,9992,23397,13757,317623,63978,215255,2443,17648,93231,27388,104529,93807,55505,140477,12046,112040,70887,40152,94365,112353,25063,114679,266061,71248,119555,15589,2244,617,14129,211431,70110,100652,7777,4383,85911,89221,21010,120615,58357,86405,37554,41647,18,15143,69662,60491,14714,186134,148344,42347,5410,168175,44535,42449,343894,129417,99682,20659,27272,140483,63455,222159,17536,13722,42637,62324,11976,114691,148109,2283,32057,182393,4295,147364,33705,2075,44303,30274,28331,63740,69740,29148,10346,44862,33716,73937,153333,12930,38784,247159,2515,41053,20256,83368,256189,54639,115240,5096,24661,175419,153552,26516,141,138176,63885,34115,47222,55709,2765,28479,38875,236608,12229,22921,77291,54426,45388,2860,57787,114579,295139,105782,17826,71066,19119,54364,69385,16568,12323,28057,33346,34919,124763,155533,101386,31644,8627,49001,303600,29868,63213,9103,77280,71333,9696,138789,37059,24823,5057,21352,32368,114208,56803,19424,10445,58514,8661,209508,26187,171838,10460,63454,14016,122504,41328,21329,46618,32493,38225,7855,31763,7945,29876,8734,6438,24205,97490,139977,130740,47323,33195,85390,57194,13813,60600,21313,96251,7699,27584,170521,139271,1363,4402,336738,129223,84983,69150,13147,3590,163929,207225,155260,55916,20288,4503,8398,98490,11773,27512,37113,84976,86558,28365,11756,116005,182148,13733,115313,47644,67208,85069,9347,14995,226141,14704,101835,41159,35314,13113,63526,214039,29978,50446,83339,17440,129441,72522,118641,97816,24907,73844,15717,118884,167255,96509,162793,30847,36849,51297,78974,77793,10427,1873,2972,9999,35074,28190,64297,146836,46298,60038,163007,108919,61219,2403,75022,127339,4233,110389,69022,9833,128097,88016,79390,222936,22570,94657,28462,56956,38803,81536,30474,152794,19566,16481,147408,74574,81895,20731,1918,1366,76367,187321,54494,24366,21690,61696,33283,107477,77499,31112,414383,74362,18463,218441,120929,59848,258629,201924,69269,454,19989,13054,59894,3623,58908,20681,35723,78523,102680,38988,184112,108087,50944,132704,52966,21699,18860,96349,201411,82697,85395,95658,5093,6427,177894,44191,32755,26961,155739,6249,31310,81030,26574,84311,120155,86730,113535,7424,48888,13516,45747,98098,20077,183995,81945,43210,26704,40420,75831,45648,11180,6855,57927,65528,124096,34851,2598,156633,107572,127352,38169,123845,60142,62722,105584,232364,23211,68120,1601,22169,89299,747,258039,80572,7258,152249,11862,101204,8834,121434,33761,19175,133142,46343,40178,48723,3589,41977,30210,38868,62257,10087,82658,87827,90646,16415,47552,351723,28298,72225,91146,272760,1701,11295,1652,109651,300747,51863,198800,29446,11794,32345,37538,22356,33102,37590,113544,37970,11478,179743,25454,103417,59905,221970,105196,145604,7817,164809,102360,16974,75840,255333,56902,6659,1954,645,59400,67769,7689,18675,5215,13793,20536,27852,3387,29523,259718,16860,94625,43143,29245,15848,233581,22685,63631,78557,22836,133302,84513,1348,51826,47129,98836,58284,1830,1749,94642,10933,6145,12506,10975,13879,103781,144434,10268,28409,32346,52968,121567,107374,77268,23686,35097,10501,155275,15303,47136,21102,168741,55332,90385,15996,84817,681,137803,25054,142275,6163,38175,8056,124296,240642,65621,4934,178205,16101,62803,60964,18230,100622,76465,44689,14545,9543,47514,16852,93380,28048,12047,107106,37575,101485,77047,57326,34819,96137,76916,6469,46264,115983,75768,87668,69942,13027,165,8373,114231,26434,52844,42799,182044,23580,146254,38081,43236,33883,146220,382894,14606,46035,36481,166621,35417,95382,2957,59384,60428,36358,66343,75378,22267,22950,83528,17577,56474,25285,4619,179691,75355,95836,53295,34588,171410,4487,14679,84208,44015,18562,109133,54101,11531,86052,174479,303157,28095,9953,35642,14564,39802,16145,77606,117406,53038,121117,53624,22062,1212,7632,127157,237292,189087,10478,127345,102515,181997,86752,87623,10966,121602,68783,68681,83042,114380,138349,191305,67176,50085,39016,1427,42384,1412,67118,122616,72389,25260,2237,13576,137346,19938,20304,2191,68759,5373,61364,238507,75814,23931,69565,38993,131741,38364,12528,87762,5679,129853,5310,186831,32653,90338,260176,389531,108118,26843,43985,50175,30563,25106,56965,18130,140428,4542,165503,117991,24219,229605,1819,129663,1240,3797,76093,18398,71339,51919,93043,27175,47060,216257,6483,35051,1217,16512,80798,129064,13225,69339,8548,237079,72298,2575,34280,51379,117910,55671,53345,247552,29486,39328,140821,34681,57045,60177,5004,90269,78522,2479,322607,48474,61296,13057,31558,4678,59271,6699,27044,31988,35944,12503,83480,4389,136508,3781,114121,70279,4488,155829,42214,2898,68191,75695,305850,45041,74344,106509,30087,17429,93292,12477,290,23080,114802,35714,18751,26554,105424,17775,2144,2412,100610,65192,113975,52975,180272,135050,129815,76238,106483,21440,63186,4260,46189,9711,28249,4169,23429,23390,8324,141585,63809,67668,38457,38063,39226,59972,1189,203916,62368,14403,16949,61767,85801,1739,40147,35049,76757,33124,62102,15780,103593,103009,53484,22952,67973,114645,6566,5245,50462,7601,8288,3513,194571,80276,1908,54592,5124,58571,2513,6800,273997,193904,1119,17991,117245,2508,129156,82366,26278,71465,63341,56943,39662,106116,94966,156875,9736,2204,122308,94418,27134,1280,24539,49022,45314,3764,50904,46424,30699,28087,293839,9400,33646,40165,822,147499,50263,116179,29085,11863,31314,5578,17797,5104,12454,1604,15342,219206,10232,67800,94261,25872,13565,90339,78971,75377,26649,41184,47695,11514,35369,20767,14227,41953,309396,148270,147938,33074,14453,27499,109019,39018,25738,240196,158931,52820,8612,95853,21524,137010,84901,70869,70021,116794,48404,38771,6732,1070,70990,187297,49140,5238,576,3564,253975,16027,16483,2811,37775,19034,25259,4053,2000,70083,95774,19713,33431,92703,91314,42381,288770,48194,95985,3991,77418,13406,241328,245086,56533,35275,62725,9246,51924,70181,95331,16163,31410,79016,39312,120878,119371,275987,80124,27712,9186,220,23598,146167,85209,68238,282190,57048,31273,30555,80913,17594,75779,59160,135002,101219,189377,29225,96735,60126,62522,104000,27620,86814,17240,147533,11001,5425,43682,410,49460,87270,69480,46315,59448,1816,76201,9431,11788,87960,29063,65539,47347,11678,33846,7008,196704,9895,6753,8633,120892,59970,572824,115934,6646,202559,892,48351,37611,251282,57823,67263,57750,26527,34485,90747,7685,88370,6144,64182,1709,41969,21458,62327,181657,49247,225330,122600,114574,107124,85361,111833,63243,71420,15655,191178,72430,18063,51425,54002,12364,53225,86557,18193,97580,41232,138398,67821,128724,8944,233212,101353,52099,42127,14006,120107,32789,32132,3498,18123,33758,56058,5779,128760,59888,98869,18445,84702,51911,13234,218379,20093,39031,8074,70195,20708,23462,24355,131384,60189,26390,10403,41060,7140,10781,49410,42261,87202,82566,41663,43105,60276,2768,5733,74176,28329,2297,145430,131632,83615,122915,105441,655,224102,5284,136426,67763,16294,188511,32538,61049,27893,3394,13951,159099,28542,17930,145360,9492,190122,32285,78855,26440,13570,58648,73908,4239,124561,2444,74172,53131,11468,10794,73566,11623,35343,64710,30481,4163,10328,38309,29901,10538,154377,76132,92405,24839,11679,3465,13449,11637,7824,2337,57754,1260,14458,41118,19878,38661,13416,159180,37074,163164,54137,28627,52134,184900,8520,40385,29546,30502,22386,66527,107458,6850,24022,47983,30603,35083,8934,304066,39500,9,28261,33026,77251,9374,44833,116312,34990,29236,63563,125639,135405,165398,159055,55690,88141,69643,236964,31983,25572,20436,36746,60896,31850,16179,11828,5888,3043,66368,9750,31167,7915,53111,36430,1333,64344,93659,20061,60596,180191,51630,6792,30244,43509,101058,22409,420,44210,109783,43223,27030,72477,72831,32679,29235,7675,47556,12258,39907,149412,84926,118247,24692,71717,105038,86009,45941,41189,89453,29856,52543,30627,226798,67303,59230,67415,34408,1367,99685,16867,128419,52147,4111,125381,117881,16173,44093,102224,31575,23234,24870,83790,127407,239098,3200,994,1255,100903,242275,117266,55116,38205,16140,29662,11307,40414,208793,123355,56470,4862,75600,30119,58218,70828,24075,26974,7802,192353,4851,5475,78720,66596,3409,28573,64396,30381,30690,59859,88256,5406,99945,103064,34463,37727,24238,86643,60088,4057,23741,5967,162904,38240,28356,93858,25510,122879,6897,3278,7057,11971,4400,35461,211413,21395,59615,39471,87233,55795,128426,3051,22470,41950,14705,3974,180108,80476,78442,204996,91987,15634,67610,139015,142373,35611,51134,10387,4353,153456,57749,181039,14183,68447,151532,21107,36452,20551,3186,46247,46383,129666,88736,140662,146243,2066,8360,7978,64818,106963,17896,47801,10723,114821,223295,74192,3293,3393,16987,74064,11277,91622,4270,29828,27951,387869,103235,1374,61988,120083,477,145892,128378,11779,211263,61354,18221,17869,46530,83061,108538,157981,90608,67199,95080,49064,195814,12302,66307,10348,231346,160732,112859,63633,146558,21271,31037,198802,47622,12862,95710,3910,77850,73961,85585,34752,61000,4082,24595,103679,71107,8208,79568,150019,16615,24961,139857,32664,197366,4559,54735,32696,4126,162019,75698,13916,70108,159638,19834,9349,24675,175560,49643,18206,52459,27992,10809,88865,401975,133172,29000,34558,30915,3658,25834,42430,36562,125265,18182,10155,40149,97082,208980,19575,60853,90529,66545,9600,789,46420,2317,88593,55595,98980,115302,5742,169155,1073,177901,3472,11189,63711,78643,65472,50459,127979,93,42202,67053,21720,157650,11145,141378,42033,22824,85705,79114,35584,15974,1510,54172,28562,12451,104226,19190,97151,73024,20948,5151,81741,21499,29006,84183,198074,54003,45120,170125,26240,35177,28389,64863,79974,60778,176915,232183,45342,2038,80253,41564,40703,32689,5430,100689,5366,23007,134279,14266,26712,73993,24934,64242,52113,102887,61801,46415,201049,54251,62133,122757,164883,30815,139966,2319,30842,766,13362,10287,134518,86111,81665,82440,28333,43019,18963,8804,161944,23439,102144,101145,80029,39052,248708,30350,117340,11878,128467,974,138625,63961,5237,74778,61834,67040,43814,13690,65947,33809,232476,115258,181745,28824,94013,9510,10246,93722,81976,7217,114383,3493,16014,69045,72692,12145,80981,9507,6692,1620,60820,330444,35474,33962,4797,7053,295463,46445,27026,12491,77988,49524,35675,90947,29114,166705,101385,133782,32704,6186,84595,176031,185623,45966,151302,63069,1699,107491,947,15458,74452,196212,6046,10498,12163,10239,35191,243951,9277,9090,29539,54460,22820,26514,112549,60372,51753,48756,21812,70861,260326,41,44222,10441,16961,48148,138771,216194,5914,52153,53400,212036,56519,26245,10117,45888,15294,138019,90913,26368,43842,42111,23348,6082,194845,161089,156206,51546,11647,30759,302912,262094,8635,78876,26535,35283,54183,31183,85484,147873,12989,5197,6356,72894,65347,20150,27370,73787,1493,45918,12366,190217,20724,13858,10981,67449,81213,7553,14115,72242,271517,11842,48310,88743,143726,22177,3290,243231,58452,62937,12592,1654,40066,33477,13751,9921,128442,15868,7106,75236,83773,10775,36938,10482,170465,17368,17469,161508,32752,98340,800,19824,264456,3901,87319,2867,26782,9630,113102,185815,24197,44584,86366,40224,3636,140916,31731,267731,9567,53678,72984,29389,27963,17106,50282,284911,60170,8322,12608,23374,89652,5268,39044,229766,8869,151350,31436,177342,12269,183212,120418,116270,2843,78888,69192,7865,184099,1086,129897,18383,70508,20242,18508,229924,124569,35749,50589,55626,9884,83115,40971,30671,18135,14452,38861,17844,201826,5549,26413,17189,13561,38539,10679,143331,3314,36785,171194,49685,187713,67506,4618,104039,17060,195080,50648,33159,19238,67559,134840,28599,157523,17130,38064,117398,94355,31918,13575,34538,40326,13997,3494,348283,62481,26862,3603,104426,244363,153709,112487,304612,199674,41239,35545,54869,293005,28223,26277,26899,4533,18518,15492,38587,80488,70485,160395,263,60162,11382,222152,4696,250751,51921,182609,10707,48463,46243,1227,49111,111564,46502,33342,56846,68541,63559,858,139927,16654,229375,76759,26478,33205,95828,23399,92945,2637,35630,28470,143992,50214,14174,21456,166191,65665,1711,21594,78019,97599,111701,36,147151,110246,189022,43021,30397,40757,131935,42065,73335,48039,26596,28984,15102,2361,7421,202167,69744,43766,52826,3642,83304,33873,75140,63169,192389,36551,92748,13039,123959,233220,21738,84447,77230,20228,187852,19095,25799,92136,108774,29237,53947,2299,118106,2687,8830,42331,202924,33667,2023,73763,30704,19363,19779,16737,35629,48081,24068,101013,162338,291912,13749,24745,328289,167679,70086,48299,23306,16732,17801,43322,54589,3586,63653,43624,53474,925,109177,251316,43805,13082,19511,86565,142182,92461,17117,101033,103319,64589,4022,4351,235897,5352,82705,107142,46391,156084,5860,61365,10558,13045,7717,18357,33922,12590,33065,6928,46993,783,46937,67846,8952,26295,6107,119656,18799,17458,50747,4229,179559,112727,118080,20683,41464,125468,51560,49749,44231,7359,35339,62988,136487,67015,5208,29150,24956,105186,48858,6143,18097,6972,16404,73489,58742,97196,36357,164616,5834,32267,13746,147733,15113,132091,34127,106298,39729,106426,22294,9780,15602,36213,71502,42808,66802,599,60755,5851,39120,67363,108623,126368,72770,91263,32486,30596,151717,7951,52002,43103,11768,68942,40901,39344,24037,127500,116890,48403,16926,86750,17745,48648,159545,34460,58419,5634,114317,67865,31462,23352,24010,98185,125708,69686,68337,13610,26271,70691,2980,4768,27225,102402,75453,28106,8104,6931,1176,6274,6475,112635,22498,6176,238686,26832,28893,90319,14441,15682,15087,39517,45270,109134,104440,45965,47645,81772,7876,52683,87720,12898,4505,185665,2769,113401,15664,57592,105229,137381,97059,119268,6876,43309,33886,128363,35476,144249,67013,143587,83367,25703,91436,59347,53236,2289,16519,19844,46309,58558,99834,23313,218816,231303,36388,51333,183535,109792,139277,54306,90139,18235,8275,32710,37677,82464,86025,92204,88842,117723,37570,128723,234242,76350,73795,34896,148247,58424,11105,11744,45746,63372,17118,49772,199520,81902,38004,22911,33752,3125,1995,53792,4689,26909,108150,146062,69674,41811,161444,84855,8999,28561,16731,93937,3189,21967,24890,22943,1356,145300,51569,28802,517,118679,31703,40607,48098,108854,25003,10233,73969,177495,5248,24516,215347,146192,48712,60626,69188,40735,5866,586,101541,6509,47590,52129,5969,222045,110933,25733,24223,65339,62812,2414,155418,35819,16022,78423,43138,20995,128255,240673,46745,236093,72176,57085,97841,61248,107,36068,193177,105427,55726,215229,20446,47228,100420,87091,14429,121708,23605,21157,187721,21880,2997,203976,99166,95068,25877,7724,98925,83401,4829,13182,18229,13718,239662,38653,116505,153497,30589,89029,38962,181302,43853,78872,180301,4786,248240,7401,106136,112590,77745,19731,60880,77789,125748,135487,5975,48627,34084,12419,215770,47557,254582,10364,106495,21856,67539,88981,38805,21428,48732,42316,12149,16078,52808,25327,51322,33850,51147,12253,122354,46077,56483,254553,115417,81834,150991,94662,86668,7381,12841,100650,18218,15741,22372,68294,50705,15535,84660,61887,22553,72299,31361,24824,17743,46820,64288,31582,77006,111674,116384,30760,80920,86149,77192,51979,79691,60342,122805,103800,240873,160744,233114,78962,54920,8608,3484,316104,72548,24337,5088,230040,21926,10172,36838,26,86221,83458,102176,12062,17571,41929,41170,28428,68239,41750,103930,2634,18313,53019,34825,97837,63115,24606,73157,152474,14715,91439,37033,109806,140259,30668,174760,380,135597,95673,136073,65073,134249,13829,17279,122305,4420,46444,10237,64848,203623,70728,10349,182885,65075,24519,25783,40318,34139,22222,63394,55266,102764,41422,20126,65100,90408,53640,35128,48932,11192,38935,96839,34782,39492,19396,41332,6250,5511,19492,51304,25936,104466,54099,73771,86115,5080,7669,30891,111700,13931,25276,72289,135447,14820,258641,25265,31005,281179,75286,393,95359,14623,13584,6680,101227,80173,44933,76666,54542,13244,39348,458,25379,109451,134348,81143,6959,65554,12027,51311,8716,57589,140731,28467,23316,17272,30458,25980,55229,77197,83798,28302,114784,7428,34548,26241,14712,39336,103304,18928,54080,12870,334,87722,15208,16895,142098,114262,39820,83913,57817,28682,7721,14900,108672,11250,62246,42849,415188,1724,26555,24549,25505,26443,107450,145899,61035,43528,6901,60726,65906,267741,21338,147590,42079,18924,73017,135236,15393,5206,4026,84185,1531,5988,113890,82647,303391,7386,69844,71611,189865,76523,31877,13315,19314,198575,32821,1928,67641,25913,104475,103489,3297,70391,18406,15446,113347,19295,93790,27856,1792,167471,116449,8541,4408,41757,63233,25765,86680,64501,27034,24816,34975,6079,4486,49693,36229,16917,21581,62426,27862,11612,54284,35702,194034,355,24277,48262,87411,70504,310164,118018,12516,47559,43502,57433,107139,9290,66533,80863,14634,34312,91725,28606,21342,67241,72355,43244,375789,37402,174015,105070,8342,44167,67494,1890,16365,11723,271002,1865,47918,8350,45564,27742,25110,125803,8553,49504,81925,62211,4534,15491,19011,80373,206920,667,102405,128623,245524,5553,113309,192739,65766,19567,22832,261958,29679,21293,71134,20962,105123,24721,860,21752,33448,18372,157167,94822,35770,173224,232737,75729,28937,46828,28062,25453,5207,140366,36665,30652,6169,67920,150458,92040,23186,184604,92330,20891,176492,49427,27828,38305,42495,143982,49560,25503,90043,29747,65328,47830,12932,11068,77721,9003,25213,94205,140426,46090,89945,138173,192691,33329,112232,129905,35709,27514,1841,19957,31411,127476,53572,17497,173549,55063,175135,19841,69314,5192,237921,117660,150697,4060,273045,50414,98940,65348,153665,164423,58804,156695,48994,213928,86036,28608,8355,39574,34540,16927,135680,18374,151587,10830,53805,16878,16623,4282,48030,8537,14986,46102,13062,72897,72,33050,108227,39451,45935,651,113320,40535,95176,57450,48843,5003,19019,10407,211163,3848,1068,4988,32091,30095,41692,15099,43602,107434,50744,7627,171349,16313,150832,352665,207750,33937,38256,51091,156000,87889,90663,84175,24908,114900,50365,31494,83829,5398,169342,47521,54818,18935,8356,43094,41212,174536,10082,92550,6678,60614,23355,69721,14796,34149,128830,58187,3179,208,40325,28399,225029,401412,51150,31580,207268,6657,10993,69818,64282,289845,23308,12961,38447,6681,52944,31855,2572,47646,120728,179148,37240,45196,218274,4816,3695,21961,50084,35209,18073,51452,27004,6100,33941,1377,84831,171214,85,141510,9078,99227,32610,6417,11718,49868,65579,87902,73018,49062,46280,61742,21512,40862,107733,15941,29168,157765,144919,14487,5767,158014,140070,7241,573,71584,16921,223566,40331,179473,35081,47926,140885,41508,52104,59180,42310,32811,29048,123517,102413,80208,10104,14746,12649,153641,126022,37965,113017,4171,83,142592,2809,6362,50416,71323,116894,260776,16204,1524,5760,30351,12658,20703,54403,36083,45408,74772,4946,14485,50759,111222,10890,2195,167147,92962,130534,16283,177256,35016,15472,210156,151187,73922,117691,43250,52051,37392,24811,24358,30830,5775,818,21969,1476,127322,151783,58392,31021,106913,65215,89407,90802,28531,11690,20234,95249,44602,37256,18707,11928,5161,4410,26571,51903,49768,22008,25252,65780,209499,68769,203726,13249,137363,48845,86823,6658,5674,31881,1083,1823,108676,34518,166752,13791,14287,91576,91429,8665,11529,26401,16191,91972,30964,5254,28486,54697,79613,66520,18447,22870,45203,194466,22822,51703,12278,76716,44595,73455,33546,12235,144843,36154,51247,11116,33040,3180,225753,60864,1972,28469,12891,28879,10338,144157,56294,353058,38302,41447,87532,110616,27065,168438,6557,1213,50804,144643,24817,2390,136531,38174,247513,16190,4059,122791,131994,137430,39506,57650,16305,5188,54309,106128,20628,88071,67394,395446,250285,66176,91254,1399,114196,43915,60230,44853,27206,106353,43013,18733,345105,226453,51202,16607,57106,117175,35492,10476,89598,127439,15187,39624,13688,61570,10615,31111,59370,6238,175252,32143,224492,41388,95408,34384,148238,78307,38959,9340,160091,61443,15737,11216,41244,170,38299,102443,113097,26382,14027,33707,3957,76300,66160,19431,18900,6952,1717,108656,82206,188021,257335,27295,43999,41210,31777,46956,57457,12657,11489,15697,48060,204748,53583,82422,284790,30503,137341,8120,19615,220311,15991,10217,63424,9808,67431,70976,98221,4491,15177,28535,144789,751,13230,2394,1504,33977,132104,30316,22230,931,97193,185240,24826,22687,174322,15307,22988,1390,188745,180325,29580,59068,74903,18994,29195,79,15436,7622,38462,11566,138710,44828,45774,37768,99236,68137,84083,19282,22698,17134,74807,126662,173497,46248,16938,119735,3212,28292,213652,49013,9975,32180,45660,86250,4801,68788,95490,77482,113751,11994,44624,94452,46839,128497,100316,5798,58588,73184,202987,65417,37790,88524,1606,43156,97964,105717,34947,11203,100060,37742,130074,93653,107799,94311,196106,41347,8035,10780,16390,27883,118236,167395,1979,25006,19375,31628,18916,144723,78502,114047,103107,86492,107686,5844,20934,206963,23556,22591,16562,146333,20167,10471,117434,33085,2863,9740,36669,41849,37271,22790,18209,28979,8231,12952,54408,21731,25130,45208,55748,138120,75826,414,29593,9925,292865,25999,683,123149,7036,92159,86055,61827,103680,23176,54918,58466,57578,13305,5709,86479,16697,31064,17660,200919,10770,49793,33423,32370,52047,16488,62555,6459,8426,83493,7763,59725,82812,18628,67760,79405,68557,9612,7673,28102,56517,69620,171797,32458,29541,15870,81109,32080,207644,71495,21202,11039,91036,61230,2810,130800,32260,4613,60590,37112,75214,33979,126402,155062,30642,63875,12810,194463,82799,47664,16725,36685,43367,61099,449,172150,102867,21691,301838,36745,7130,18671,57316,34852,38034,54182,35578,65900,99486,19771,3456,2658,16914,99866,28390,28109,8262,21147,34353,20006,4228,137085,1675,203023,283196,198286,214375,163329,290603,152574,40471,83506,30068,14730,23177,131539,34759,27668,32178,71896,104799,116305,85430,119262,42860,25160,8911,23428,49437,105322,6519,16203,6349,74711,1230,38045,8540,75165,44736,25909,51026,317034,4984,32281,91312,27060,44431,17817,45363,155937,239085,35697,59784,91993,29531,126740,213757,76560,167776,285273,24262,8237,65030,41160,74437,48804,118916,13159,37842,1031,75349,1478,11655,108777,23435,277425,101734,67469,70231,124711,43532,28514,65526,54956,1000,21882,17728,25302,40952,52214,149632,1999,2111,3259,63362,89961,220561,39777,26335,9063,10572,12416,34551,34623,38604,24723,5947,15588,69927,66252,119177,69173,46629,28714,70715,212408,20521,406913,74380,11716,50659,50862,37009,88460,130101,7210,53853,538,65120,151950,55806,163748,52837,13153,21100,16674,64536,6091,138201,44837,58547,3723,163,2177,32288,85454,34033,8497,14282,25742,10535,10741,79559,117493,243787,49337,100718,79495,40139,42956,7551,55433,15421,31509,23034,45081,547,61176,53434,328001,8470,36263,30145,4519,74173,53935,11845,73774,60211,78025,3,4102,73782,109293,315332,48412,26683,13714,6865,20128,18490,104141,325,39470,171970,115860,15707,7268,73301,74336,31370,2368,111827,107757,136231,142844,97138,96638,84053,38691,23801,1588,10573,122098,77039,240,186135,146101,11996,18143,112963,46171,155836,348769,47795,121213,116266,132515,3344,144804,31286,99187,255838,129694,35894,48779,55235,148582,71967,65282,15174,13920,47080,6147,108242,157593,125025,7136,1286,28957,127956,28402,98813,20805,7532,109417,40610,5041,32958,15142,18408,108596,33543,50517,27748,80114,233434,91447,487,37094,100048,30541,43477,10639,89862,155868,37667,8726,60684,237903,73408,99589,12190,38739,97348,3914,13594,2680,149016,13907,30171,28343,23530,115225,61104,35821,147679,14337,4297,244282,24085,326976,56428,7851,21303,131620,71446,83253,68692,111870,5224,15813,38197,49026,45057,13660,3306,76345,40671,27905,91072,996,68527,62085,91351,122634,55109,168209,2024,27560,112707,17352,8306,167115,169921,166958,5031,46020,11844,67284,19130,76185,6920,32849,5450,14610,22451,21002,17392,31872,66682,84796,13709,40210,59898,12029,8719,53564,21462,91884,21647,88379,194428,12754,37797,132826,160016,22567,54383,53186,77611,31107,8339,4694,19185,90355,23597,17222,140675,28442,23668,55977,9128,61555,28774,155229,17658,9390,24379,69357,15752,127381,239631,62460,93181,55913,45133,140155,18676,25249,33164,29581,82837,67223,22362,29975,7317,52813,1943,29613,20012,207130,49617,49651,5636,15334,36313,29226,28084,95247,72072,19000,224932,15811,114,32127,38097,37508,88507,37225,27359,91626,12193,69279,20608,11055,88156,92808,2152,57259,55275,72789,24475,104414,1708,9882,3818,48661,66897,1631,34806,227930,85815,87753,18321,250664,72733,25107,206797,50891,8082,196411,92596,96764,152823,65514,22819,387277,62176,51225,40329,15563,189,3659,73670,64357,51793,275136,33482,86653,74615,67058,11318,125720,15388,22388,8267,1730,102663,170910,40784,7144,85373,13040,7088,94309,583,44224,140424,77439,18496,164026,36578,4722,9151,5824,63365,26510,35199,40500,79277,32495,44614,35233,9566,203293,152144,7097,2330,183480,98629,13423,330887,44130,68600,30939,97829,31012,345465,56747,94879,4939,160027,149761,99423,46099,32251,15332,8761,96094,128555,5763,235318,222223,55729,30241,55420,201746,3987,81382,8259,49325,23287,7719,24633,251100,92311,18591,110533,64759,170260,393860,7175,21144,132887,3593,75346,101277,91109,16387,259187,11627,57459,173829,44694,55780,49797,89192,120443,62622,3904,14814,23887,1027,112258,64955,99800,11132,66353,36202,48624,18158,88481,96882,43059,11040,2455,7077,21651,181159,99126,100434,61388,68186,19161,110468,120052,8819,55324,41494,7014,37689,3618,87729,92615,207943,9823,128657,12587,15857,6379,67628,51216,71775,157617,63244,1503,3864,218754,110864,5769,21492,7243,1192,87921,85529,31512,18537,42698,35350,73510,84474,34301,8991,21013,35034,566,38832,19838,35586,37216,39413,55006,12178,59742,856,84563,6900,25632,17437,49786,30723,13847,70845,4044,7843,23944,235976,55530,48942,6518,20939,73769,192653,52936,95207,23895,132542,142982,22632,87452,48042,54018,178468,10728,26230,23559,363,81269,142012,5718,346258,31456,84333,246476,51018,66692,101804,120570,39962,30373,70593,2864,60541,19425,54209,104092,7201,31545,48018,25865,15442,46257,40443,8328,6451,111782,47527,97754,33046,470,245116,31095,39,91934,87208,73470,36708,36521,12801,70624,36272,8892,79768,12427,55454,103756,5908,52390,62962,22720,141138,94634,41689,128402,126390,6628,106394,35527,134394,82727,254651,194502,148064,89549,3202,28359,957,21954,27906,49840,142747,8307,24206,48978,1186,71728,133038,71474,91306,6333,110959,74600,70387,18983,62609,56057,22970,1147,135850,1321,28834,3578,59715,102227,32827,81415,99952,55636,257598,390,22702,35701,85872,402916,39216,189795,14929,19467,10112,144422,61514,5279,63421,134686,41436,8424,51925,10598,132295,124416,4604,194739,210929,57866,31829,51626,50007,9976,91878,61906,56168,81906,60918,61859,40017,23059,16887,40927,62064,12785,32893,32913,21782,93965,20169,44387,79084,38463,11457,93950,27127,157050,2697,337088,5116,54128,48255,33279,8821,27352,25515,124022,65710,28906,38557,33390,1722,104435,72215,38551,12094,30978,25113,6671,37355,175109,42862,98024,65406,221276,59624,118012,64637,78760,86697,21426,1639,40350,12584,67193,84144,31396,7863,143011,69629,63112,9454,28666,65798,46372,134721,6314,51402,30837,151922,2847,38676,38008,92823,136245,17540,5504,109295,205242,37606,5211,214892,1586,20670,208711,137743,19328,40652,16995,20023,14657,154919,34422,12996,13918,38221,47690,16398,2959,37680,89122,6721,198469,91876,172043,83898,101992,26084,94570,3635,76958,22853,76497,38266,176590,168403,44464,142840,79180,184594,1984,41806,83147,11985,6546,366068,59732,24533,271505,8736,39084,222992,93429,28962,58985,86665,8432,30028,14548,32439,54424,165029,55175,27458,69046,121277,46168,33732,20661,24581,135574,123110,37556,79260,72611,16957,12939,46162,58238,44907,72936,253758,41324,32518,96480,11949,124438,65280,43256,34107,53533,43531,37037,28366,45970,32741,173438,6121,194202,62969,26355,30314,58370,28455,1848,50519,82830,90393,21761,295490,10936,256940,133568,44050,20269,4089,27457,21610,219460,36743,14821,101388,52005,13124,30979,140816,167362,26054,18458,60789,34917,40447,26606,33422,9066,3452,83614,5761,20263,137238,25038,91310,101,52322,74548,42572,38084,214054,186568,31802,17665,30620,141936,37730,14420,4265,187218,49640,188208,51441,55388,96452,66659,40869,42039,60967,221027,19234,178581,29105,96050,9165,196118,157335,3738,40354,117436,2965,34136,59659,15570,50843,230035,31444,71260,43886,18316,5387,38500,168508,17406,32174,8828,103373,143806,90367,3560,18719,122310,16508,26719,2541,105429,6645,37998,73190,10591,235916,49737,87112,233941,53188,32193,79154,4544,52905,126477,7580,63501,57314,3216,31337,6541,103083,60846,49,9756,15481,1355,43840,14319,13743,27486,10222,73114,230718,418644,16706,6674,279748,23058,45273,295831,86306,2743,5535,88773,21829,35253,120938,31153,3169,16839,42847,8751,80974,33942,36867,35514,16485,26474,77775,56877,5391,48346,3882,108713,31403,27804,55248,26235,43821,136104,40118,175507,28034,203908,18732,1788,34030,106427,36958,54359,7251,44936,15356,69139,455,157915,22173,140291,50348,43275,82066,49621,54952,15216,36226,96695,66855,6936,1987,8227,196087,4631,68827,99004,47541,110265,17953,147605,110242,58520,31312,38724,329975,642,3155,34497,75937,6207,73843,6120,17249,51429,117746,3218,910,68961,319671,14938,29555,34700,1649,66673,72268,9655,76800,153087,6941,210168,27130,35398,1780,73242,3135,56689,19556,165307,8765,35967,121458,13333,70453,17350,117253,22265,13340,44265,39869,441,3742,135025,23581,33309,16543,17731,13291,157637,283005,21408,101360,63887,52312,83873,5338,233779,23759,186949,34531,177320,38069,156465,91004,19353,59852,68160,14891,1338,1072,29823,1950,28901,81407,313445,73038,84807,162348,240257,37162,138934,16111,58013,41253,102951,16457,96056,19541,56402,67217,41638,94381,89674,29481,37456,80815,151579,13937,13683,132537,19699,134545,67020,29816,222341,141235,427578,48868,129557,233342,23077,87871,16213,18728,16184,9469,37913,19680,2798,171356,178328,13216,50049,72690,71904,124644,55455,7504,29052,41036,266546,19899,30391,188755,8659,59469,16,104298,112943,53865,76203,138226,68857,139953,14125,107625,119795,173133,4398,50273,48808,54390,16466,122086,31835,67035,50971,48859,7508,46427,66477,73021,84615,39985,83076,46779,201569,53336,36443,60865,168164,143810,51393,25548,169307,32896,24485,38424,21837,29087,275813,51674,6714,64883,46169,187369,55186,76192,12852,12018,62134,31067,118303,16542,12125,10579,4928,26291,43854,7091,10946,253716,109062,39283,17261,113012,258512,47764,125126,32646,55892,80279,201623,149872,3192,385,1208,48750,5376,58738,22335,5427,82416,47811,32435,143086,38930,94128,59975,156037,37977,38224,62485,7698,50405,71027,16462,21559,136153,34131,107506,162069,63703,3101,215029,40407,4178,3774,9187,80019,17880,97926,67579,2600,18405,8351,47924,86638,70820,92206,86453,29610,42241,119200,3198,15466,67813,57863,35454,4779,99518,4649,104641,144269,33730,38073,65864,6838,109456,193298,154007,5623,45741,30846,182578,25573,157224,1543,58575,138703,146140,44971,49356,18275,59064,20300,13122,11848,24453,11973,9797,86843,2919,25530,49210,1130,161220,76788,75373,85604,34926,36014,17777,17255,51533,11676,92226,51845,119859,21525,5936,18507,28050,1140,31418,14857,34207,47859,10750,36382,32079,106909,59426,87757,38393,110042,15965,97104,33757,35344,97993,53979,33651,45407,41884,82515,173089,7177,58371,35365,47543,51927,35587,10670,23544,29306,84233,39976,76076,62097,9007,8668,28119,78281,120790,19835,143020,54968,18670,64959,20649,34469,42570,33001,136570,87796,120044,1106,58700,63951,127623,12805,83057,40212,31773,49850,7361,54336,347524,101314,23751,19569,48791,29174,49369,20467,7465,75842,38281,623,112457,60210,28849,51003,94720,6426,90047,85560,43761,3579,85105,34607,90410,118528,7224,42907,111163,18168,6960,161135,191298,5247,100584,127552,171568,20121,91173,12636,54615,20199,63730,98105,2396,40387,14438,125012,4765,33235,12865,45299,37728,82098,77872,114037,59253,19675,24838,398016,102561,11446,17069,57508,178277,65836,99941,26114,2585,271882,136866,50126,11027,155648,118367,14585,8910,123015,335383,40434,41016,53021,14439,87098,176860,201543,121888,2358,9286,5739,22666,54270,37884,169381,33984,93859,16124,89364,72207,51639,76366,99029,65812,2198,12147,174891,194289,6986,30252,88822,21284,11445,288337,160821,33034,100869,43852,25761,52882,1144,103809,1924,84458,86079,43411,13542,139276,18141,34978,41298,7276,26481,173800,33210,17951,142652,33616,33677,2210,19941,98568,2486,192414,80136,12058,235883,50963,249638,29572,27221,47034,6124,72107,63346,97620,158513,299699,40388,23235,37176,224244,198386,121323,67992,23827,63170,17838,106622,158590,26807,5345,23489,91891,55474,74834,37981,13058,5977,72552,34706,26828,145172,19904,21367,34043,960,77092,91381,4733,47446,7680,41697,5170,16960,14741,46101,13656,473,51842,37433,11103,11551,121951,13191,97536,165932,50397,51628,129028,9069,44885,6590,59195,47045,32940,225472,90345,21833,13303,29407,96615,141951,5198,6028,18395,7181,3861,14966,156358,167182,36529,55253,25942,173153,30959,27261,50691,150176,162201,38467,48462,80602,42163,118482,168,108756,26011,17166,54149,456538,22512,91374,13816,90358,131615,18132,226707,1824,28139,26860,42253,93877,77351,65575,8980,80574,22020,27948,40422,91324,76376,13528,39281,91685,82215,122541,144066,1983,193851,17283,26320,2739,194978,4790,26845,42627,61300,65815,174612,55133,4200,191130,79771,158321,52280,166796,221620,62461,11278,4067,88152,83409,31717,121367,13522,47325,37945,10406,174348,249321,154101,64912,29938,51775,17220,15776,166138,78890,84425,54121,42861,16368,24572,291647,10197,32073,22651,11677,97509,26952,35787,18424,41910,71614,94977,72318,41594,70024,275419,37702,60199,7335,39107,61315,18271,18394,33768,87884,104277,123724,7277,56288,71981,189803,49320,3352,6798,14240,8954,69220,94433,57372,28620,68863,193727,85575,42309,41667,67689,42081,22543,44824,12719,28540,114236,101553,27638,27296,4300,5353,4663,19379,94098,3758,95888,95144,80344,87320,28447,259518,12718,71391,152731,37063,24132,31911,104896,15672,103782,1521,4945,72541,23717,122632,15619,87175,206120,29428,189780,61416,28350,44457,972,1175,47233,198738,95789,41907,21953,97034,59341,22864,53713,16873,32971,20693,20954,31336,21477,16169,38370,16412,9019,3841,24599,21938,17085,6484,81198,76413,5849,72514,12320,65247,276175,37234,59796,52642,16312,57349,198507,94148,46134,18958,125552,1747,18725,151873,14901,5490,68287,29470,3689,64794,40814,26018,25692,54450,2703,88278,124886,173087,174000,24159,179477,24276,46004,201876,209202,445,52876,31948,30206,157610,39180,18439,44124,50469,5774,96278,222758,200216,50290,45486,20435,46986,46276,140133,142326,15569,13363,47522,92583,2182,7135,16853,22998,30272,4952,63263,35623,39096,53789,44864,20053,110392,124213,4630,16087,28221,127787,25839,77481,44693,13464,113146,6983,27069,55717,50102,4760,7107,26186,66507,59145,36032,104182,71328,29425,64317,50781,47465,94298,69706,74899,22754,120756,25108,93077,56834,73286,39928,16218,41699,176763,7555,70819,50083,26895,23315,26014,16773,123079,41712,5719,31516,90427,158540,85051,183128,40864,27505,55392,9058,45224,96857,30901,136622,96557,56304,120061,11501,151448,5773,89743,7769,86069,2935,18471,41628,10114,33660,110170,49479,26745,92846,33221,26731,18795,87076,8550,2100,29972,120289,3077,72490,33784,2630,208722,50861,63483,79029,6419,39467,14302,45286,64207,9686,67513,44170,1050,77246,59266,17055,53801,7150,11111,42432,4278,94579,362117,36175,42902,41933,39002,98489,22913,74161,84773,57036,17556,162288,74485,178760,93867,73635,128860,50362,261,67455,80001,46080,35662,4368,25247,19230,74393,22588,1822,27682,235324,13798,85998,13194,235067,23514,71669,147632,23191,134748,214683,105101,1518,25489,247114,7380,54842,26922,3971,26361,20844,68642,170517,77339,123255,8963,77818,150998,48466,36806,2732,23261,11741,236162,18243,126216,28690,50546,16385,92760,197383,246558,201295,88255,67588,71687,176076,172653,169058,33906,63747,24835,157621,43338,30050,46152,132741,2770,51371,94835,6614,15112,11749,56936,1250,19027,399017,58036,100215,23388,55815,308768,124152,94803,9521,64186,8971,28,30427,62163,7616,103838,35079,29203,131235,7743,17389,10882,37420,61460,228512,85363,41581,131077,62822,119647,10130,54445,26925,19968,29016,24446,74028,24176,61448,67185,9254,8563,119129,9771,99184,37716,39514,10532,221512,258753,218630,55980,23394,32141,61924,66749,32411,3741,36475,26678,77010,44946,91203,128749,116953,20476,49625,53116,13735,102335,29376,51946,83407,67892,59212,34685,21083,1546,112982,32972,74397,1078,190545,16082,86140,58591,89611,101531,10061,105104,76319,20035,17551,52611,169061,190842,100780,23907,90413,115619,9675,34710,193435,49443,129734,11183,258877,16318,136182,126808,44635,27304,192375,2599,125648,47051,12091,23814,721,58800,40137,66726,97930,60877,74487,7942,54326,9841,41428,13762,8211,85383,6950,99177,79806,201786,296464,124087,13144,29741,41721,47634,55088,254286,106408,17041,99064,12942,64086,45233,14005,2612,55827,255,7984,13980,38574,12776,46654,73499,249951,2101,26676,25996,132326,116415,119062,50449,31033,23038,11589,179252,20007,14860,129270,21143,17796,144715,60106,70758,69842,34674,282133,44014,16774,57268,38528,24053,46373,201667,28327,471023,51889,102667,21193,114909,84132,69317,96723,67969,16134,68145,15058,28765,32035,2524,101089,98664,25045,76571,14957,86040,118506,262428,154764,81573,39681,283900,73287,127825,544,80448,52347,38512,175971,15180,45467,33086,46552,48894,81107,43213,36672,54025,76703,8053,7608,13299,56619,20752,238099,54164,105133,1444,32942,953,37564,8000,66316,119463,106817,404,13667,149108,128597,31267,10269,49836,106150,1484,52330,76965,160486,171648,38456,31263,22424,37738,66245,67467,143369,60471,75610,20895,115528,86070,60854,40796,49347,18989,15030,11371,37578,15779,79867,10187,86462,46402,155626,93200,40229,7090,57547,108053,99598,11088,47505,41218,206017,2173,20988,30219,22919,80563,57566,42369,93141,41675,2407,182519,120495,27154,16702,29456,14349,7958,16688,117177,140375,42467,261919,74916,153569,10836,34742,49526,7621,105997,12212,2270,392377,7755,17959,25086,232152,138791,33847,13860,35316,5811,1344,71259,50452,207539,92635,50359,5821,33674,30255,2086,2587,96264,17543,42,6029,9580,43007,139248,82831,12917,29607,25786,51467,42137,85161,100698,31561,88989,121990,278500,3602,109344,37982,15279,116442,28936,30880,87894,58079,128661,126731,67392,28051,146885,4861,16216,97344,42827,147561,153948,22684,21335,47685,1853,43349,15185,59642,10229,25520,187921,108972,5579,98037,24945,6697,19193,63734,137934,75056,89740,19767,224268,56138,63643,151661,39313,70618,84031,89723,84074,13703,85626,35460,8867,64845,3439,57906,99776,63968,49270,81130,34356,16210,23547,36446,34090,140028,72439,2221,22163,57058,363492,113754,18913,95451,48663,54464,54037,176097,68425,3023,34906,29482,117389,341780,80431,58330,16753,92616,60907,94846,147486,4498,48646,7773,46801,7778,18946,464978,47558,33223,177444,7328,15626,63337,94700,11743,9351,255024,39098,16447,42647,96230,39769,58840,10068,63439,35800,65843,58823,413844,9156,51258,7434,61791,85018,6872,3692,28096,7121,33024,6009,75532,31997,192535,9661,3304,9547,14753,31987,25314,55689,15896,20430,39472,31340,99744,25398,115569,54883,28719,205423,23071,57855,64638,149867,25671,82403,37616,20668,39989,77996,74948,140555,175248,64810,36515,46595,4958,248773,24045,28728,136673,168704,20804,114833,100325,27135,21205,96151,153134,45992,7093,13992,76047,1980,19432,145001,75159,87462,17710,1013,45556,34297,144882,20648,26061,11319,129567,108555,18872,464580,33386,22717,65948,167189,5603,135042,79542,8801,202632,18114,91882,5973,5239,67315,4431,60916,47819,71693,32597,32606,18183,45072,80329,76385,24749,51305,40314,156514,14693,130345,13168,66214,18029,12858,34801,27628,14544,10823,40522,40185,33739,148694,23548,9923,61012,28859,17933,19442,34364,99849,164107,141167,30629,21054,6744,36491,8096,42474,41706,155060,30650,10600,163442,1143,96655,61390,52359,7559,51568,64256,203854,4467,22453,14504,436398,7878,6980,8293,63610,293747,16167,35763,19627,147603,15419,18032,110744,51346,33681,54571,40472,48615,39073,21604,13754,173027,92560,11083,47299,63062,11813,52007,29883,9734,139722,15953,1550,20651,13616,49306,16113,90089,92326,7584,30712,72424,164858,6831,152871,55746,197721,34167,196442,6022,112107,55215,7538,123381,4920,43539,77165,8939,50392,34192,20225,79762,22505,58667,40770,29788,97180,82835,4568,8579,13273,363569,35898,49983,436,36598,3237,131691,62418,35591,8101,4073,379438,65218,76072,33887,2968,27573,212619,288680,68278,72851,150504,217896,6913,121339,22017,35340,51072,43616,75043,31437,10833,81487,4364,22968,41454,106687,85446,19863,109625,149241,524,141850,214404,54376,657,237023,9401,108137,53800,32474,49712,53334,126876,27337,45552,177696,8269,15036,12097,42240,2328,125374,119295,99715,2500,19624,39441,27220,102691,60957,94543,39101,18566,67362,13975,78230,25017,34017,239007,90027,39351,41681,35354,43822,1043,916,58587,141983,94818,38799,75459,41114,67432,16195,36606,59568,22272,126769,31424,68659,12287,134302,257977,5756,207285,95637,47248,117689,19583,77451,22373,12200,54993,117118,34244,29386,34562,53819,71267,64172,77665,49368,7716,59301,25749,45426,194789,17297,2650,1766,32501,45198,20403,20984,6600,14171,94604,19037,5402,29896,9938,59935,109708,88081,145182,44844,39167,352626,164173,35374,45982,6122,154,73419,220487,53834,53601,17992,8609,229321,5610,68098,66815,71012,95069,140968,27396,8957,134489,24656,86659,56598,134852,17316,123838,255436,6613,41610,138033,81452,32023,32396,123687,63398,8693,29712,30407,19296,121188,3551,36099,20032,111948,56624,16547,27453,35916,15378,52039,56849,13489,22214,73177,53097,277349,2157,14029,187886,10260,141743,246460,91880,50869,3788,49486,133566,54950,33120,129337,53768,18333,9525,26902,312251,10297,9020,70759,16647,112432,59260,84609,9818,82766,73569,468,46001,75780,55028,52106,11498,43645,108069,17150,17753,29417,16705,31799,9606,289,122254,115975,8620,6133,255357,56908,14456,133464,43554,79224,11247,29630,160,12756,25464,65960,350428,62521,321796,100359,67358,35169,46172,113128,48988,88868,31094,33266,6847,60887,98188,49659,69117,92977,220228,13947,80181,35103,62170,97351,13475,2440,199768,19498,36597,46971,25234,67806,62881,84717,73648,181966,10488,94149,21550,26655,63436,48375,14405,165650,9621,24439,28043,42735,4490,29963,56674,45373,1934,262446,50855,67098,26898,5261,52696,40644,33900,9440,180286,87162,22940,19704,26936,69769,10254,101759,27406,12243,48000,73926,113215,54935,5726,192787,4312,106216,9366,11550,52949,23457,212271,277152,133895,108374,6191,96477,29980,218916,58024,54696,40853,91124,65894,91170,65908,252552,6793,29212,15389,44516,122515,52617,35058,9017,103536,39510,49136,19242,130652,662077,74699,47024,31422,8517,73351,24399,13867,128360,4810,4434,61779,111983,61036,17798,110240,59722,102960,39688,10001,23803,23039,176498,56659,44814,134295,17188,77577,74466,226175,102472,154333,63900,111747,18062,41171,79669,32773,408933,42562,28931,30907,107388,43487,2946,240310,23938,24354,319,184983,7927,6488,1422,10790,68809,68209,64775,4361,202,17123,59634,51200,44391,18188,17843,2619,74278,3230,9540,47187,21702,36274,56894,43907,16310,34790,16866,6150,5561,13587,107545,108873,126867,86986,28640,33427,19017,5762,80637,17430,46903,2047,131055,25958,13558,5444,47152,13900,44563,122857,45348,70863,39593,54332,38068,33637,318,40310,143467,18502,24520,11377,62013,28942,27246,28269,83545,17999,59015,90707,30065,15161,34720,1263,37008,2012,6060,98575,92933,5721,299,199555,24578,29223,2985,743,115825,109523,136657,47454,26378,53586,3733,174945,93340,244456,5693,37386,28782,89767,27545,23573,18798,136425,34320,84778,20041,48453,38215,7477,71958,40621,8773,5874,187927,105965,51100,43533,18083,8443,10180,43597,2003,183999,69689,12216,129696,146188,62389,34044,68410,12765,43273,26949,266807,3345,34477,79197,5688,47539,213110,21634,22257,50092,32222,42346,39530,63668,98,134978,74022,5152,59088,174145,37220,9934,9545,118937,5724,87240,19875,15784,40143,23263,87513,181654,285152,37881,263241,4966,43934,10433,186657,6470,74416,225854,25908,142677,246262,32280,6192,75890,45546,143264,135305,29742,47013,77787,11732,126658,8763,37950,21806,57557,113464,89465,108995,164574,23894,22996,23169,15369,23117,17642,130607,40503,36239,280990,44666,9981,40427,147487,26869,168452,32886,32991,46798,240839,15111,70502,65697,88548,44145,28701,48767,31139,206777,35659,181164,166262,14554,171445,31786,66523,76607,17956,6507,31279,90476,116611,167918,6560,1243,115324,80128,41867,55897,187323,37069,32596,189444,145931,13390,105530,65709,26805,6999,55714,41300,22915,68951,22138,21120,22264,10058,19945,33635,56123,99085,10032,5818,6016,46649,57476,35264,94413,112522,262288,93686,83038,14341,23204,28807,66084,77987,6101,126673,7133,38126,5923,122091,170240,97772,46874,215746,43948,41622,3272,55596,8332,146411,251315,13533,8561,81521,115449,48616,175175,2063,186556,3036,134537,75772,29728,82360,22973,186559,86348,89100,38388,82297,45610,2613,87082,9986,177812,57884,23591,47485,42543,33582,44713,74439,257444,252451,31825,35631,38540,33066,5147,13973,4343,51830,70378,22827,26448,95560,36896,241741,48067,203953,298860,61620,20450,3220,67272,6586,107662,100160,108684,6929,57226,4762,7457,1320,40404,77204,99309,62750,208653,59977,44000,74315,34332,5819,172217,64904,114077,18147,84012,1791,98456,90930,21446,116669,103938,7422,85140,59713,5768,326211,16239,75411,13229,29398,10758,236107,1539,112472,95979,152154,151294,306,21196,38146,10700,6891,84282,109646,56492,40539,6589,119491,51354,30685,140209,136906,29622,73617,49553,70525,51671,166869,139616,74395,37439,49595,45678,11959,33211,86560,52434,9282,62690,112155,130810,5243,108261,99970,265613,72551,80049,6391,33365,90721,66737,69872,87011,1860,9032,112544,60905,37371,89015,140351,19076,850,373531,2802,36725,218795,72062,28990,16550,24614,7815,6187,26336,33373,32162,42791,73555,32062,23386,10244,56392,49442,27076,136262,12412,14883,1134,33675,97153,199281,15608,100152,74072,47942,254301,36451,16026,10687,65067,56708,254030,30290,50490,13864,57941,259331,35588,23485,43486,24869,21620,92971,22072,88645,1048,182050,13343,32452,14825,19509,3325,216938,45740,99716,189082,53740,78245,25609,24311,176777,47340,308354,40669,66085,14102,125339,9225,128709,97207,1271,200933,78439,113451,88975,18324,46521,11819,18570,141756,72512,170020,52754,63550,118515,103073,93330,32736,50499,14722,31600,68452,398867,29316,172786,18417,104924,2606,5670,84818,16288,67106,59580,82929,607401,291,85829,359,15897,35830,50696,65630,52672,22115,356968,29895,40837,231192,34024,38957,26722,406,23335,124952,72068,68804,13268,147101,164740,276569,162596,66943,11569,26654,66358,4777,23229,102127,5848,978,2921,59666,5371,28212,90108,42938,39320,2499,4271,108792,33510,125072,71653,65239,38250,66357,38577,13964,86251,35708,50755,36010,29448,12209,3844,38222,206337,100876,67827,137088,14167,252225,84163,195270,1306,5703,54198,779,46802,22028,51124,86759,70560,113164,35685,162145,45471,34561,422,2611,6464,47486,19223,38246,9191,18331,89942,243642,212364,15893,17518,22617,6409,30046,126182,59716,36560,104428,18846,26592,19458,50793,147333,30826,1388,27647,10922,14495,33545,19269,135828,39727,41601,46931,233379,49169,131130,182112,16276,82381,118209,142445,128310,19672,28740,82907,33436,3118,102206,28723,24819,41937,38854,5157,3881,111491,1142,9776,421673,152241,29309,14961,87854,6054,15424,3796,82656,54996,2108,55367,239450,154525,9643,118103,106041,64601,68549,48707,30266,25772,18740,9462,229669,91798,112152,191327,14493,72828,8175,66636,236474,25817,87351,129027,76653,20422,22983,71240,27846,44661,12399,46158,77704,53101,35032,11072,17300,109294,33638,24408,1895,11241,760,17584,82479,125877,63150,141075,34259,23274,81698,15732,43577,48340,91584,14688,16379,24481,150280,96420,262050,48635,43727,61819,56268,72003,88178,17281,79912,13218,122519,125295,166396,11811,2171,118930,67746,17636,178278,174656,95661,173039,83845,79689,17473,98555,127696,203415,54730,22925,232239,9309,12136,175026,20740,180188,10747,39816,314017,266131,10040,175732,112550,220651,31974,37393,888,23008,86799,4303,64905,148467,75337,251,3284,370102,50264,9835,5438,23655,4481,29851,329,12855,7162,64931,78141,12804,42372,296771,83547,18624,34874,86271,3360,48665,77735,88767,11463,63527,28889,22258,29140,194315,113924,25499,6406,31334,1845,4802,49184,43455,35469,127594,92970,61038,115005,38840,87761,106838,8811,20572,55637,11162,96721,132425,108925,2948,125457,36356,3502,75270,27622,127192,2561,123095,49394,61155,16897,110064,9699,89448,53356,19628,220310,21622,83036,9885,112214,6087,26713,17901,161912,91492,3440,68594,9266,92238,8087,6866,150194,72175,80701,13459,31836,43243,239700,95846,44749,50647,21945,230538,120612,132371,244604,5193,105637,34661,41341,68775,85393,1874,8771,33718,49672,77403,595452,99507,6490,58895,128742,7704,39239,73217,43816,62824,37804,199976,22361,80005,87514,94832,14089,4574,139975,59142,75523,100268,43906,53442,15152,2547,186002,17011,19513,204282,3343,60568,128318,119250,4298,51871,41336,71759,21921,45074,98169,145889,99427,11350,1237,5520,28799,7803,53702,21026,136352,38293,128690,12158,90132,44600,10184,26957,39459,126025,78904,82999,59373,39301,150198,120529,153042,20177,50089,14764,271571,30530,123161,38975,101562,22941,5648,124654,109243,69817,71675,49162,106884,21241,107795,30258,16572,188262,141456,7688,60718,8271,11044,32440,104608,103419,236109,93156,43293,128929,42107,67180,25201,115254,185488,130954,72813,167547,20537,39969,38432,22582,184022,1139,27199,5655,17767,97412,122606,209377,27070,35871,326617,188954,42680,73512,80911,22629,3011,95021,315242,157737,383,41821,41808,19335,27950,15674,25677,110950,35375,76835,59108,57370,35262,16569,160415,37706,78086,32041,49691,137143,9782,172080,50148,77917,6323,10110,69172,17711,21795,59511,76184,135114,31046,132319,59105,157578,20549,80778,57649,158421,65143,4575,72235,21899,10797,92745,34035,106079,80159,4508,78304,25350,75457,46458,32937,25623,47,8531,104751,84953,8138,36508,187199,66310,115274,13253,32461,38536,1916,42007,187160,35055,26325,84394,35963,94216,45590,97782]");

},{}],"16BUU":[function(require,module,exports) {
'use strict';
const debug = require('debug');
const { sha256  } = require('multiformats/hashes/sha2');
const { base58btc  } = require('multiformats/bases/base58');
const { Key  } = require('interface-datastore/key');
const { xor: uint8ArrayXor  } = require('uint8arrays/xor');
const { compare: uint8ArrayCompare  } = require('uint8arrays/compare');
const pMap = require('p-map');
const { Record  } = require('libp2p-record');
const PeerId = require('peer-id');
const errcode = require('err-code');
const { fromString: uint8ArrayFromString  } = require('uint8arrays/from-string');
const { toString: uint8ArrayToString  } = require('uint8arrays/to-string');
const { concat: uint8ArrayConcat  } = require('uint8arrays/concat');
const pTimeout = require('p-timeout');
/**
 * Creates a DHT ID by hashing a given Uint8Array.
 *
 * @param {Uint8Array} buf
 * @returns {Promise<Uint8Array>}
 */ exports.convertBuffer = async (buf)=>{
    return (await sha256.digest(buf)).digest;
};
/**
 * Creates a DHT ID by hashing a Peer ID
 *
 * @param {PeerId} peer
 * @returns {Promise<Uint8Array>}
 */ exports.convertPeerId = async (peer)=>{
    return (await sha256.digest(peer.id)).digest;
};
/**
 * Convert a Uint8Array to their SHA2-256 hash.
 *
 * @param {Uint8Array} buf
 * @returns {Key}
 */ exports.bufferToKey = (buf)=>{
    return new Key('/' + exports.encodeBase32(buf), false);
};
/**
 * Generate the key for a public key.
 *
 * @param {PeerId} peer
 * @returns {Uint8Array}
 */ exports.keyForPublicKey = (peer)=>{
    return uint8ArrayConcat([
        uint8ArrayFromString('/pk/'),
        peer.id
    ]);
};
/**
 * @param {Uint8Array} key
 */ exports.isPublicKeyKey = (key)=>{
    return uint8ArrayToString(key.slice(0, 4)) === '/pk/';
};
/**
 * @param {Uint8Array} key
 */ exports.fromPublicKeyKey = (key)=>{
    return new PeerId(key.slice(4));
};
/**
 * Get the current time as timestamp.
 *
 * @returns {number}
 */ exports.now = ()=>{
    return Date.now();
};
/**
 * Encode a given Uint8Array into a base32 string.
 *
 * @param {Uint8Array} buf
 * @returns {string}
 */ exports.encodeBase32 = (buf)=>{
    return uint8ArrayToString(buf, 'base32');
};
/**
 * Decode a given base32 string into a Uint8Array.
 *
 * @param {string} raw
 * @returns {Uint8Array}
 */ exports.decodeBase32 = (raw)=>{
    return uint8ArrayFromString(raw, 'base32');
};
/**
 * Sort peers by distance to the given `target`.
 *
 * @param {Array<PeerId>} peers
 * @param {Uint8Array} target
 */ exports.sortClosestPeers = async (peers, target)=>{
    const distances = await pMap(peers, async (peer)=>{
        const id = await exports.convertPeerId(peer);
        return {
            peer: peer,
            distance: uint8ArrayXor(id, target)
        };
    });
    return distances.sort(exports.xorCompare).map((d)=>d.peer
    );
};
/**
 * Compare function to sort an array of elements which have a distance property which is the xor distance to a given element.
 *
 * @param {{ distance: Uint8Array }} a
 * @param {{ distance: Uint8Array }} b
 */ exports.xorCompare = (a, b)=>{
    return uint8ArrayCompare(a.distance, b.distance);
};
/**
 * Computes how many results to collect on each disjoint path, rounding up.
 * This ensures that we look for at least one result per path.
 *
 * @param {number} resultsWanted
 * @param {number} numPaths - total number of paths
 */ exports.pathSize = (resultsWanted, numPaths)=>{
    return Math.ceil(resultsWanted / numPaths);
};
/**
 * Create a new put record, encodes and signs it if enabled.
 *
 * @param {Uint8Array} key
 * @param {Uint8Array} value
 * @returns {Uint8Array}
 */ exports.createPutRecord = (key, value)=>{
    const timeReceived = new Date();
    const rec = new Record(key, value, timeReceived);
    return rec.serialize();
};
/**
 * Creates a logger for the given subsystem
 *
 * @param {PeerId} [id]
 * @param {string} [subsystem]
 */ exports.logger = (id, subsystem)=>{
    const name = [
        'libp2p',
        'dht'
    ];
    if (subsystem) name.push(subsystem);
    if (id) name.push(`${id.toB58String().slice(0, 8)}`);
    // Add a formatter for converting to a base58 string
    debug.formatters.b = (v)=>{
        return base58btc.baseEncode(v);
    };
    const logger = Object.assign(debug(name.join(':')), {
        error: debug(name.concat([
            'error'
        ]).join(':'))
    });
    return logger;
};
exports.TimeoutError = class TimeoutError extends Error {
    get code() {
        return 'ETIMEDOUT';
    }
};
/**
 * Creates an async function that calls the given `asyncFn` and Errors
 * if it does not resolve within `time` ms
 *
 * @template T
 * @param {(...args: any[]) => Promise<T>} asyncFn
 * @param {number} [time]
 */ exports.withTimeout = (asyncFn, time)=>{
    /**
   * @param  {...any} args
   * @returns {Promise<T>}
   */ async function timeoutFn(...args) {
        if (!time) return asyncFn(...args);
        let res;
        try {
            res = await pTimeout(asyncFn(...args), time);
        } catch (err) {
            if (err instanceof pTimeout.TimeoutError) throw errcode(err, 'ETIMEDOUT');
            throw err;
        }
        return res;
    }
    return timeoutFn;
};
/**
 * Iterates the given `asyncIterator` and runs each item through the given `asyncFn` in parallel.
 * Returns a promise that resolves when all items of the `asyncIterator` have been passed
 * through `asyncFn`.
 *
 * @template T
 * @template O
 *
 * @param {AsyncIterable<T>} asyncIterator
 * @param {(arg0: T) => Promise<O>} asyncFn
 */ exports.mapParallel = async function(asyncIterator, asyncFn) {
    const tasks = [];
    for await (const item of asyncIterator)tasks.push(asyncFn(item));
    return Promise.all(tasks);
};

},{"debug":"lWlU4","multiformats/hashes/sha2":"i8JnP","multiformats/bases/base58":"6Rnqi","interface-datastore/key":"ccQWS","uint8arrays/xor":"lpkFK","uint8arrays/compare":"m8amP","p-map":"75sAO","libp2p-record":"4hkIr","peer-id":"4VGWt","err-code":"eQvyh","uint8arrays/from-string":"lo45E","uint8arrays/to-string":"g3mCQ","uint8arrays/concat":"fLIrL","p-timeout":"5asWS"}],"75sAO":[function(require,module,exports) {
'use strict';
const AggregateError = require('aggregate-error');
module.exports = async (iterable, mapper, { concurrency =Infinity , stopOnError =true  } = {
})=>{
    return new Promise((resolve, reject)=>{
        if (typeof mapper !== 'function') throw new TypeError('Mapper function is required');
        if (!((Number.isSafeInteger(concurrency) || concurrency === Infinity) && concurrency >= 1)) throw new TypeError(`Expected \`concurrency\` to be an integer from 1 and up or \`Infinity\`, got \`${concurrency}\` (${typeof concurrency})`);
        const result = [];
        const errors = [];
        const iterator = iterable[Symbol.iterator]();
        let isRejected = false;
        let isIterableDone = false;
        let resolvingCount = 0;
        let currentIndex = 0;
        const next = ()=>{
            if (isRejected) return;
            const nextItem = iterator.next();
            const index = currentIndex;
            currentIndex++;
            if (nextItem.done) {
                isIterableDone = true;
                if (resolvingCount === 0) {
                    if (!stopOnError && errors.length !== 0) reject(new AggregateError(errors));
                    else resolve(result);
                }
                return;
            }
            resolvingCount++;
            (async ()=>{
                try {
                    const element = await nextItem.value;
                    result[index] = await mapper(element, index);
                    resolvingCount--;
                    next();
                } catch (error) {
                    if (stopOnError) {
                        isRejected = true;
                        reject(error);
                    } else {
                        errors.push(error);
                        resolvingCount--;
                        next();
                    }
                }
            })();
        };
        for(let i = 0; i < concurrency; i++){
            next();
            if (isIterableDone) break;
        }
    });
};

},{"aggregate-error":"1BWsO"}],"1BWsO":[function(require,module,exports) {
'use strict';
const indentString = require('indent-string');
const cleanStack = require('clean-stack');
const cleanInternalStack = (stack)=>stack.replace(/\s+at .*aggregate-error\/index.js:\d+:\d+\)?/g, '')
;
class AggregateError extends Error {
    constructor(errors){
        if (!Array.isArray(errors)) throw new TypeError(`Expected input to be an Array, got ${typeof errors}`);
        errors = [
            ...errors
        ].map((error)=>{
            if (error instanceof Error) return error;
            if (error !== null && typeof error === 'object') // Handle plain error objects with message property and/or possibly other metadata
            return Object.assign(new Error(error.message), error);
            return new Error(error);
        });
        let message = errors.map((error)=>{
            // The `stack` property is not standardized, so we can't assume it exists
            return typeof error.stack === 'string' ? cleanInternalStack(cleanStack(error.stack)) : String(error);
        }).join('\n');
        message = '\n' + indentString(message, 4);
        super(message);
        this.name = 'AggregateError';
        Object.defineProperty(this, '_errors', {
            value: errors
        });
    }
    *[Symbol.iterator]() {
        for (const error of this._errors)yield error;
    }
}
module.exports = AggregateError;

},{"indent-string":"fLX5m","clean-stack":"52GTd"}],"fLX5m":[function(require,module,exports) {
'use strict';
module.exports = (string, count = 1, options)=>{
    options = {
        indent: ' ',
        includeEmptyLines: false,
        ...options
    };
    if (typeof string !== 'string') throw new TypeError(`Expected \`input\` to be a \`string\`, got \`${typeof string}\``);
    if (typeof count !== 'number') throw new TypeError(`Expected \`count\` to be a \`number\`, got \`${typeof count}\``);
    if (typeof options.indent !== 'string') throw new TypeError(`Expected \`options.indent\` to be a \`string\`, got \`${typeof options.indent}\``);
    if (count === 0) return string;
    const regex = options.includeEmptyLines ? /^/gm : /^(?!\s*$)/gm;
    return string.replace(regex, options.indent.repeat(count));
};

},{}],"52GTd":[function(require,module,exports) {
'use strict';
const os = require('os');
const extractPathRegex = /\s+at.*(?:\(|\s)(.*)\)?/;
const pathRegex = /^(?:(?:(?:node|(?:internal\/[\w/]*|.*node_modules\/(?:babel-polyfill|pirates)\/.*)?\w+)\.js:\d+:\d+)|native)/;
const homeDir = typeof os.homedir === 'undefined' ? '' : os.homedir();
module.exports = (stack, options)=>{
    options = Object.assign({
        pretty: false
    }, options);
    return stack.replace(/\\/g, '/').split('\n').filter((line)=>{
        const pathMatches = line.match(extractPathRegex);
        if (pathMatches === null || !pathMatches[1]) return true;
        const match = pathMatches[1];
        // Electron
        if (match.includes('.app/Contents/Resources/electron.asar') || match.includes('.app/Contents/Resources/default_app.asar')) return false;
        return !pathRegex.test(match);
    }).filter((line)=>line.trim() !== ''
    ).map((line)=>{
        if (options.pretty) return line.replace(extractPathRegex, (m, p1)=>m.replace(p1, p1.replace(homeDir, '~'))
        );
        return line;
    }).join('\n');
};

},{"os":"joWnX"}],"b8cEs":[function(require,module,exports) {
'use strict';
// MaxRecordAge specifies the maximum time that any node will hold onto a record
// from the time its received. This does not apply to any other forms of validity that
// the record may contain.
// For example, a record may contain an ipns entry with an EOL saying its valid
// until the year 2020 (a great time in the future). For that record to stick around
// it must be rebroadcasted more frequently than once every 'MaxRecordAge'
const second = exports.second = 1000;
const minute = exports.minute = 60 * second;
const hour = exports.hour = 60 * minute;
exports.MAX_RECORD_AGE = 36 * hour;
exports.PROTOCOL_DHT = '/kad/1.0.0';
exports.PROVIDERS_KEY_PREFIX = '/providers/';
exports.PROVIDERS_LRU_CACHE_SIZE = 256;
exports.PROVIDERS_VALIDITY = 24 * hour;
exports.PROVIDERS_CLEANUP_INTERVAL = hour;
exports.READ_MESSAGE_TIMEOUT = 10 * second;
// The number of records that will be retrieved on a call to getMany()
exports.GET_MANY_RECORD_COUNT = 16;
// K is the maximum number of requests to perform before returning failure
exports.K = 20;
// Alpha is the concurrency for asynchronous requests
exports.ALPHA = 3;

},{}],"jOEj6":[function(require,module,exports) {
'use strict';
const errcode = require('err-code');
const { pipe  } = require('it-pipe');
const lp = require('it-length-prefixed');
const pTimeout = require('p-timeout');
const { consume  } = require('streaming-iterables');
const first = require('it-first');
const MulticodecTopology = require('libp2p-interfaces/src/topology/multicodec-topology');
const rpc = require('./rpc');
const c = require('./constants');
const Message = require('./message');
const utils = require('./utils');
/**
 * @typedef {import('peer-id')} PeerId
 * @typedef {import('libp2p-interfaces/src/stream-muxer/types').MuxedStream} MuxedStream
 */ /**
 * Handle network operations for the dht
 */ class Network {
    /**
   * Create a new network
   *
   * @param {import('./index')} dht
   */ constructor(dht){
        this.dht = dht;
        this.readMessageTimeout = c.READ_MESSAGE_TIMEOUT;
        this._log = utils.logger(this.dht.peerId, 'net');
        this._rpc = rpc(this.dht);
        this._onPeerConnected = this._onPeerConnected.bind(this);
        this._running = false;
    }
    /**
   * Start the network
   */ start() {
        if (this._running) return;
        if (!this.dht.isStarted) throw errcode(new Error('Can not start network'), 'ERR_CANNOT_START_NETWORK');
        this._running = true;
        // Only respond to queries when not in client mode
        if (this.dht._clientMode === false) // Incoming streams
        this.dht.registrar.handle(this.dht.protocol, this._rpc);
        // register protocol with topology
        const topology = new MulticodecTopology({
            multicodecs: [
                this.dht.protocol
            ],
            handlers: {
                onConnect: this._onPeerConnected,
                onDisconnect: ()=>{
                }
            }
        });
        this._registrarId = this.dht.registrar.register(topology);
    }
    /**
   * Stop all network activity
   */ stop() {
        if (!this.dht.isStarted && !this.isStarted) return;
        this._running = false;
        // unregister protocol and handlers
        if (this._registrarId) this.dht.registrar.unregister(this._registrarId);
    }
    /**
   * Is the network online?
   *
   * @type {boolean}
   */ get isStarted() {
        return this._running;
    }
    /**
   * Are all network components there?
   *
   * @type {boolean}
   */ get isConnected() {
        // TODO add a way to check if switch has started or not
        return this.dht.isStarted && this.isStarted;
    }
    /**
   * Registrar notifies a connection successfully with dht protocol.
   *
   * @param {PeerId} peerId - remote peer id
   */ async _onPeerConnected(peerId) {
        await this.dht._add(peerId);
        this._log('added to the routing table: %s', peerId.toB58String());
    }
    /**
   * Send a request and record RTT for latency measurements.
   *
   * @async
   * @param {PeerId} to - The peer that should receive a message
   * @param {Message} msg - The message to send.
   */ async sendRequest(to, msg4) {
        // TODO: record latency
        if (!this.isConnected) throw errcode(new Error('Network is offline'), 'ERR_NETWORK_OFFLINE');
        const id = to.toB58String();
        this._log('sending to: %s', id);
        let conn = this.dht.registrar.connectionManager.get(to);
        if (!conn) conn = await this.dht.dialer.connectToPeer(to);
        const { stream  } = await conn.newStream(this.dht.protocol);
        return this._writeReadMessage(stream, msg4.serialize());
    }
    /**
   * Sends a message without expecting an answer.
   *
   * @param {PeerId} to
   * @param {Message} msg
   */ async sendMessage(to1, msg1) {
        if (!this.isConnected) throw errcode(new Error('Network is offline'), 'ERR_NETWORK_OFFLINE');
        const id = to1.toB58String();
        this._log('sending to: %s', id);
        let conn = this.dht.registrar.connectionManager.get(to1);
        if (!conn) conn = await this.dht.dialer.connectToPeer(to1);
        const { stream  } = await conn.newStream(this.dht.protocol);
        return this._writeMessage(stream, msg1.serialize());
    }
    /**
   * Write a message and read its response.
   * If no response is received after the specified timeout
   * this will error out.
   *
   * @param {MuxedStream} stream - the stream to use
   * @param {Uint8Array} msg - the message to send
   */ async _writeReadMessage(stream2, msg2) {
        return pTimeout(writeReadMessage(stream2, msg2), this.readMessageTimeout);
    }
    /**
   * Write a message to the given stream.
   *
   * @param {MuxedStream} stream - the stream to use
   * @param {Uint8Array} msg - the message to send
   */ _writeMessage(stream1, msg3) {
        return pipe([
            msg3
        ], lp.encode(), stream1, consume);
    }
}
/**
 * @param {MuxedStream} stream
 * @param {Uint8Array} msg
 */ async function writeReadMessage(stream, msg) {
    const res = await pipe([
        msg
    ], lp.encode(), stream, lp.decode(), /**
     * @param {AsyncIterable<Uint8Array>} source
     */ async (source)=>{
        const buf = await first(source);
        if (buf) return buf.slice();
    });
    if (res.length === 0) throw errcode(new Error('No message received'), 'ERR_NO_MESSAGE_RECEIVED');
    return Message.deserialize(res);
}
module.exports = Network;

},{"err-code":"eQvyh","it-pipe":"4jukm","it-length-prefixed":"2cvC1","p-timeout":"5asWS","streaming-iterables":"9JcGF","it-first":"imIGO","libp2p-interfaces/src/topology/multicodec-topology":"czyip","./rpc":"lWd7O","./constants":"b8cEs","./message":"5TcLe","./utils":"16BUU"}],"9JcGF":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "batch", ()=>batch
);
parcelHelpers.export(exports, "buffer", ()=>buffer
);
parcelHelpers.export(exports, "collect", ()=>collect
);
parcelHelpers.export(exports, "concat", ()=>concat
);
parcelHelpers.export(exports, "consume", ()=>consume
);
parcelHelpers.export(exports, "filter", ()=>filter
);
parcelHelpers.export(exports, "flatMap", ()=>flatMap
);
parcelHelpers.export(exports, "flatTransform", ()=>flatTransform
);
parcelHelpers.export(exports, "flatten", ()=>flatten
);
parcelHelpers.export(exports, "fromStream", ()=>fromStream
);
parcelHelpers.export(exports, "getIterator", ()=>getIterator
);
parcelHelpers.export(exports, "map", ()=>map
);
parcelHelpers.export(exports, "merge", ()=>merge
);
parcelHelpers.export(exports, "parallelFlatMap", ()=>parallelFlatMap
);
parcelHelpers.export(exports, "parallelMap", ()=>parallelMap
);
parcelHelpers.export(exports, "parallelMerge", ()=>parallelMerge
);
parcelHelpers.export(exports, "pipeline", ()=>pipeline
);
parcelHelpers.export(exports, "reduce", ()=>reduce
);
parcelHelpers.export(exports, "take", ()=>take
);
parcelHelpers.export(exports, "tap", ()=>tap
);
parcelHelpers.export(exports, "time", ()=>time
);
parcelHelpers.export(exports, "transform", ()=>transform
);
parcelHelpers.export(exports, "writeToStream", ()=>writeToStream
);
var process = require("process");
async function* _batch(size, iterable) {
    let dataBatch = [];
    for await (const data of iterable){
        dataBatch.push(data);
        if (dataBatch.length === size) {
            yield dataBatch;
            dataBatch = [];
        }
    }
    if (dataBatch.length > 0) yield dataBatch;
}
function* _syncBatch(size, iterable) {
    let dataBatch = [];
    for (const data of iterable){
        dataBatch.push(data);
        if (dataBatch.length === size) {
            yield dataBatch;
            dataBatch = [];
        }
    }
    if (dataBatch.length > 0) yield dataBatch;
}
function batch(size, iterable) {
    if (iterable === undefined) return (curriedIterable)=>batch(size, curriedIterable)
    ;
    if (iterable[Symbol.asyncIterator]) return _batch(size, iterable);
    return _syncBatch(size, iterable);
}
function getIterator(iterable) {
    if (typeof iterable.next === 'function') return iterable;
    if (typeof iterable[Symbol.iterator] === 'function') return iterable[Symbol.iterator]();
    if (typeof iterable[Symbol.asyncIterator] === 'function') return iterable[Symbol.asyncIterator]();
    throw new TypeError('"values" does not to conform to any of the iterator or iterable protocols');
}
function defer() {
    let reject;
    let resolve;
    const promise = new Promise((resolveFunc, rejectFunc)=>{
        resolve = resolveFunc;
        reject = rejectFunc;
    });
    return {
        promise,
        reject,
        resolve
    };
}
/// <reference lib="esnext.asynciterable" />
function _buffer(size, iterable) {
    const iterator = getIterator(iterable);
    const resultQueue = [];
    const readQueue = [];
    let reading = false;
    let ended = false;
    function fulfillReadQueue() {
        while(readQueue.length > 0 && resultQueue.length > 0){
            const readDeferred = readQueue.shift();
            const { error , value  } = resultQueue.shift();
            if (error) readDeferred.reject(error);
            else readDeferred.resolve({
                done: false,
                value
            });
        }
        while(readQueue.length > 0 && ended){
            const { resolve  } = readQueue.shift();
            resolve({
                done: true,
                value: undefined
            });
        }
    }
    async function fillQueue() {
        if (ended) return;
        if (reading) return;
        if (resultQueue.length >= size) return;
        reading = true;
        try {
            const { done , value  } = await iterator.next();
            if (done) ended = true;
            else resultQueue.push({
                value
            });
        } catch (error) {
            ended = true;
            resultQueue.push({
                error
            });
        }
        fulfillReadQueue();
        reading = false;
        fillQueue();
    }
    async function next() {
        if (resultQueue.length > 0) {
            const { error , value  } = resultQueue.shift();
            if (error) throw error;
            fillQueue();
            return {
                done: false,
                value
            };
        }
        if (ended) return {
            done: true,
            value: undefined
        }; // stupid ts
        const deferred = defer();
        readQueue.push(deferred);
        fillQueue();
        return deferred.promise;
    }
    const asyncIterableIterator = {
        next,
        [Symbol.asyncIterator]: ()=>asyncIterableIterator
    };
    return asyncIterableIterator;
}
function* syncBuffer(size, iterable) {
    const valueQueue = [];
    let e;
    try {
        for (const value of iterable){
            valueQueue.push(value);
            if (valueQueue.length <= size) continue;
            yield valueQueue.shift();
        }
    } catch (error) {
        e = error;
    }
    for (const value of valueQueue)yield value;
    if (e) throw e;
}
function buffer(size, iterable) {
    if (iterable === undefined) return (curriedIterable)=>buffer(size, curriedIterable)
    ;
    if (size === 0) return iterable;
    if (iterable[Symbol.asyncIterator]) return _buffer(size, iterable);
    return syncBuffer(size, iterable);
}
async function _collect(iterable) {
    const values = [];
    for await (const value of iterable)values.push(value);
    return values;
}
function collect(iterable) {
    if (iterable[Symbol.asyncIterator]) return _collect(iterable);
    return Array.from(iterable);
}
async function* _concat(iterables) {
    for await (const iterable of iterables)yield* iterable;
}
function* _syncConcat(iterables) {
    for (const iterable of iterables)yield* iterable;
}
function concat(...iterables) {
    const hasAnyAsync = iterables.find((itr)=>itr[Symbol.asyncIterator] !== undefined
    );
    if (hasAnyAsync) return _concat(iterables);
    else return _syncConcat(iterables);
}
async function _consume(iterable) {
    for await (const val of iterable);
}
function consume(iterable) {
    if (iterable[Symbol.asyncIterator]) return _consume(iterable);
    for (const val of iterable);
}
async function* _filter(filterFunc, iterable) {
    for await (const data of iterable)if (await filterFunc(data)) yield data;
}
function filter(filterFunc, iterable) {
    if (iterable === undefined) return (curriedIterable)=>_filter(filterFunc, curriedIterable)
    ;
    return _filter(filterFunc, iterable);
}
async function* flatten(iterable) {
    for await (const maybeItr of iterable)if (maybeItr && typeof maybeItr !== 'string' && (maybeItr[Symbol.iterator] || maybeItr[Symbol.asyncIterator])) yield* flatten(maybeItr);
    else yield maybeItr;
}
async function* _map(func, iterable) {
    for await (const val of iterable)yield await func(val);
}
function map(func, iterable) {
    if (iterable === undefined) return (curriedIterable)=>_map(func, curriedIterable)
    ;
    return _map(func, iterable);
}
function flatMap(func, iterable) {
    if (iterable === undefined) return (curriedIterable)=>flatMap(func, curriedIterable)
    ;
    return filter((i)=>i !== undefined && i !== null
    , flatten(map(func, iterable)));
}
function _flatTransform(concurrency, func, iterable) {
    const iterator = getIterator(iterable);
    const resultQueue = [];
    const readQueue = [];
    let ended = false;
    let reading = false;
    let inflightCount = 0;
    let lastError = null;
    function fulfillReadQueue() {
        while(readQueue.length > 0 && resultQueue.length > 0){
            const { resolve  } = readQueue.shift();
            const value = resultQueue.shift();
            resolve({
                done: false,
                value
            });
        }
        while(readQueue.length > 0 && inflightCount === 0 && ended){
            const { resolve , reject  } = readQueue.shift();
            if (lastError) {
                reject(lastError);
                lastError = null;
            } else resolve({
                done: true,
                value: undefined
            });
        }
    }
    async function fillQueue() {
        if (ended) {
            fulfillReadQueue();
            return;
        }
        if (reading) return;
        if (inflightCount + resultQueue.length >= concurrency) return;
        reading = true;
        inflightCount++;
        try {
            const { done , value  } = await iterator.next();
            if (done) {
                ended = true;
                inflightCount--;
                fulfillReadQueue();
            } else mapAndQueue(value);
        } catch (error) {
            ended = true;
            inflightCount--;
            lastError = error;
            fulfillReadQueue();
        }
        reading = false;
        fillQueue();
    }
    async function mapAndQueue(itrValue) {
        try {
            const value = await func(itrValue);
            if (value && value[Symbol.asyncIterator]) for await (const asyncVal of value)resultQueue.push(asyncVal);
            else resultQueue.push(value);
        } catch (error) {
            ended = true;
            lastError = error;
        }
        inflightCount--;
        fulfillReadQueue();
        fillQueue();
    }
    async function next() {
        if (resultQueue.length === 0) {
            const deferred = defer();
            readQueue.push(deferred);
            fillQueue();
            return deferred.promise;
        }
        const value = resultQueue.shift();
        fillQueue();
        return {
            done: false,
            value
        };
    }
    const asyncIterableIterator = {
        next,
        [Symbol.asyncIterator]: ()=>asyncIterableIterator
    };
    return asyncIterableIterator;
}
function flatTransform(concurrency, func, iterable) {
    if (func === undefined) return (curriedFunc, curriedIterable)=>curriedIterable ? flatTransform(concurrency, curriedFunc, curriedIterable) : flatTransform(concurrency, curriedFunc)
    ;
    if (iterable === undefined) return (curriedIterable)=>flatTransform(concurrency, func, curriedIterable)
    ;
    return filter((i)=>i !== undefined && i !== null
    , flatten(_flatTransform(concurrency, func, iterable)));
}
async function onceReadable(stream) {
    return new Promise((resolve)=>{
        stream.once('readable', ()=>{
            resolve();
        });
    });
}
async function* _fromStream(stream) {
    while(true){
        const data = stream.read();
        if (data !== null) {
            yield data;
            continue;
        }
        if (stream._readableState.ended) break;
        await onceReadable(stream);
    }
}
function fromStream(stream) {
    if (typeof stream[Symbol.asyncIterator] === 'function') return stream;
    return _fromStream(stream);
}
async function* merge(...iterables) {
    const sources = new Set(iterables.map(getIterator));
    while(sources.size > 0)for (const iterator of sources){
        const nextVal = await iterator.next();
        if (nextVal.done) sources.delete(iterator);
        else yield nextVal.value;
    }
}
function pipeline(firstFn, ...fns) {
    let previousFn = firstFn();
    for (const func of fns)previousFn = func(previousFn);
    return previousFn;
}
async function* _parallelMap(concurrency, func, iterable) {
    let transformError = null;
    const wrapFunc = (value)=>({
            value: func(value)
        })
    ;
    const stopOnError = async function*(source) {
        for await (const value of source){
            if (transformError) return;
            yield value;
        }
    };
    const output = pipeline(()=>iterable
    , buffer(1), stopOnError, map(wrapFunc), buffer(concurrency - 1));
    const itr = getIterator(output);
    while(true){
        const { value , done  } = await itr.next();
        if (done) break;
        try {
            const val = await value.value;
            if (!transformError) yield val;
        } catch (error) {
            transformError = error;
        }
    }
    if (transformError) throw transformError;
}
function parallelMap(concurrency, func, iterable) {
    if (func === undefined) return (curriedFunc, curriedIterable)=>parallelMap(concurrency, curriedFunc, curriedIterable)
    ;
    if (iterable === undefined) return (curriedIterable)=>parallelMap(concurrency, func, curriedIterable)
    ;
    if (concurrency === 1) return map(func, iterable);
    return _parallelMap(concurrency, func, iterable);
}
function parallelFlatMap(concurrency, func, iterable) {
    if (func === undefined) return (curriedFunc, curriedIterable)=>curriedIterable ? parallelFlatMap(concurrency, curriedFunc, curriedIterable) : parallelFlatMap(concurrency, curriedFunc)
    ;
    if (iterable === undefined) return (curriedIterable)=>parallelFlatMap(concurrency, func, curriedIterable)
    ;
    return filter((i)=>i !== undefined && i !== null
    , flatten(parallelMap(concurrency, func, iterable)));
}
/// <reference lib="esnext.asynciterable" />
async function* parallelMerge(...iterables) {
    const inputs = iterables.map(getIterator);
    const concurrentWork = new Set();
    const values = new Map();
    let lastError = null;
    let errCb = null;
    let valueCb = null;
    const notifyError = (err)=>{
        lastError = err;
        if (errCb) errCb(err);
    };
    const notifyDone = (value)=>{
        if (valueCb) valueCb(value);
    };
    const waitForQueue = ()=>new Promise((resolve, reject)=>{
            if (lastError) reject(lastError);
            if (values.size > 0) return resolve();
            valueCb = resolve;
            errCb = reject;
        })
    ;
    const queueNext = (input)=>{
        const nextVal = Promise.resolve(input.next()).then(async ({ done , value  })=>{
            if (!done) values.set(input, value);
            concurrentWork.delete(nextVal);
        });
        concurrentWork.add(nextVal);
        nextVal.then(notifyDone, notifyError);
    };
    for (const input1 of inputs)queueNext(input1);
    while(true){
        // We technically don't have to check `values.size` as the for loop should have emptied it
        // However I haven't yet found specs verifying that behavior, only tests
        // the guard in waitForQueue() checking for values is in place for the same reason
        if (concurrentWork.size === 0 && values.size === 0) return;
        await waitForQueue();
        for (const [input, value] of values){
            values.delete(input);
            yield value;
            queueNext(input);
        }
    }
}
async function _reduce(func, start, iterable) {
    let value = start;
    for await (const nextItem of iterable)value = await func(value, nextItem);
    return value;
}
function reduce(func, start, iterable) {
    if (start === undefined) return (curriedStart, curriedIterable)=>curriedIterable ? _reduce(func, curriedStart, curriedIterable) : reduce(func, curriedStart)
    ;
    if (iterable === undefined) return (curriedIterable)=>reduce(func, start, curriedIterable)
    ;
    return _reduce(func, start, iterable);
}
async function* _take(count, iterable) {
    let taken = 0;
    for await (const val of iterable){
        yield await val;
        taken++;
        if (taken >= count) break;
    }
}
function* _syncTake(count, iterable) {
    let taken = 0;
    for (const val of iterable){
        yield val;
        taken++;
        if (taken >= count) break;
    }
}
function take(count, iterable) {
    if (iterable === undefined) return (curriedIterable)=>take(count, curriedIterable)
    ;
    if (iterable[Symbol.asyncIterator]) return _take(count, iterable);
    return _syncTake(count, iterable);
}
async function* _asyncTap(func, iterable) {
    for await (const val of iterable){
        await func(val);
        yield val;
    }
}
function tap(func, iterable) {
    if (iterable === undefined) return (curriedIterable)=>_asyncTap(func, curriedIterable)
    ;
    return _asyncTap(func, iterable);
}
function addTime(a, b) {
    let seconds = a[0] + b[0];
    let nanoseconds = a[1] + b[1];
    if (nanoseconds >= 1000000000) {
        const remainder = nanoseconds % 1000000000;
        seconds += (nanoseconds - remainder) / 1000000000;
        nanoseconds = remainder;
    }
    return [
        seconds,
        nanoseconds
    ];
}
async function* _asyncTime(config, iterable) {
    const itr = iterable[Symbol.asyncIterator]();
    let total = [
        0,
        0
    ];
    while(true){
        const start = process.hrtime();
        const { value , done  } = await itr.next();
        const delta = process.hrtime(start);
        total = addTime(total, delta);
        if (config.progress) config.progress(delta, total);
        if (done) {
            if (config.total) config.total(total);
            return value;
        }
        yield value;
    }
}
function* _syncTime(config, iterable) {
    const itr = iterable[Symbol.iterator]();
    let total = [
        0,
        0
    ];
    while(true){
        const start = process.hrtime();
        const { value , done  } = itr.next();
        const delta = process.hrtime(start);
        total = addTime(total, delta);
        if (config.progress) config.progress(delta, total);
        if (done) {
            if (config.total) config.total(total);
            return value;
        }
        yield value;
    }
}
function time(config = {
}, iterable) {
    if (iterable === undefined) return (curriedIterable)=>time(config, curriedIterable)
    ;
    if (iterable[Symbol.asyncIterator] !== undefined) return _asyncTime(config, iterable);
    else return _syncTime(config, iterable);
}
function _transform(concurrency, func, iterable) {
    const iterator = getIterator(iterable);
    const resultQueue = [];
    const readQueue = [];
    let ended = false;
    let reading = false;
    let inflightCount = 0;
    let lastError = null;
    function fulfillReadQueue() {
        while(readQueue.length > 0 && resultQueue.length > 0){
            const { resolve  } = readQueue.shift();
            const value = resultQueue.shift();
            resolve({
                done: false,
                value
            });
        }
        while(readQueue.length > 0 && inflightCount === 0 && ended){
            const { resolve , reject  } = readQueue.shift();
            if (lastError) {
                reject(lastError);
                lastError = null;
            } else resolve({
                done: true,
                value: undefined
            });
        }
    }
    async function fillQueue() {
        if (ended) {
            fulfillReadQueue();
            return;
        }
        if (reading) return;
        if (inflightCount + resultQueue.length >= concurrency) return;
        reading = true;
        inflightCount++;
        try {
            const { done , value  } = await iterator.next();
            if (done) {
                ended = true;
                inflightCount--;
                fulfillReadQueue();
            } else mapAndQueue(value);
        } catch (error) {
            ended = true;
            inflightCount--;
            lastError = error;
            fulfillReadQueue();
        }
        reading = false;
        fillQueue();
    }
    async function mapAndQueue(itrValue) {
        try {
            const value = await func(itrValue);
            resultQueue.push(value);
        } catch (error) {
            ended = true;
            lastError = error;
        }
        inflightCount--;
        fulfillReadQueue();
        fillQueue();
    }
    async function next() {
        if (resultQueue.length === 0) {
            const deferred = defer();
            readQueue.push(deferred);
            fillQueue();
            return deferred.promise;
        }
        const value = resultQueue.shift();
        fillQueue();
        return {
            done: false,
            value
        };
    }
    const asyncIterableIterator = {
        next,
        [Symbol.asyncIterator]: ()=>asyncIterableIterator
    };
    return asyncIterableIterator;
}
function transform(concurrency, func, iterable) {
    if (func === undefined) return (curriedFunc, curriedIterable)=>curriedIterable ? transform(concurrency, curriedFunc, curriedIterable) : transform(concurrency, curriedFunc)
    ;
    if (iterable === undefined) return (curriedIterable)=>transform(concurrency, func, curriedIterable)
    ;
    return _transform(concurrency, func, iterable);
}
async function _writeToStream(stream, iterable) {
    let lastError = null;
    let errCb = null;
    let drainCb = null;
    const notifyError = (err)=>{
        lastError = err;
        if (errCb) errCb(err);
    };
    const notifyDrain = ()=>{
        if (drainCb) drainCb();
    };
    const cleanup = ()=>{
        stream.removeListener('error', notifyError);
        stream.removeListener('drain', notifyDrain);
    };
    stream.once('error', notifyError);
    const waitForDrain = ()=>new Promise((resolve, reject)=>{
            if (lastError) return reject(lastError);
            stream.once('drain', notifyDrain);
            drainCb = resolve;
            errCb = reject;
        })
    ;
    for await (const value of iterable){
        if (stream.write(value) === false) await waitForDrain();
        if (lastError) break;
    }
    cleanup();
    if (lastError) throw lastError;
}
function writeToStream(stream, iterable) {
    if (iterable === undefined) return (curriedIterable)=>_writeToStream(stream, curriedIterable)
    ;
    return _writeToStream(stream, iterable);
}

},{"process":"lDnB8","@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"lWd7O":[function(require,module,exports) {
'use strict';
const { pipe  } = require('it-pipe');
const lp = require('it-length-prefixed');
const Message = require('../message');
const handlers = require('./handlers');
const utils = require('../utils');
/**
 * @typedef {import('peer-id')} PeerId
 * @typedef {import('libp2p-interfaces/src/stream-muxer/types').MuxedStream} MuxedStream
 */ /**
 * @param {import('../index')} dht
 */ module.exports = (dht)=>{
    const log = utils.logger(dht.peerId, 'rpc');
    const getMessageHandler = handlers(dht);
    /**
   * Process incoming DHT messages.
   *
   * @param {PeerId} peerId
   * @param {Message} msg
   */ async function handleMessage(peerId, msg) {
        // get handler & execute it
        const handler = getMessageHandler(msg.type);
        try {
            await dht._add(peerId);
        } catch (err) {
            log.error('Failed to update the kbucket store', err);
        }
        if (!handler) {
            log.error(`no handler found for message type: ${msg.type}`);
            return;
        }
        return handler(peerId, msg);
    }
    /**
   * Handle incoming streams on the dht protocol
   *
   * @param {object} props
   * @param {MuxedStream} props.stream
   * @param {import('libp2p-interfaces/src/connection').Connection} props.connection
   */ async function onIncomingStream({ stream , connection  }) {
        const peerId = connection.remotePeer;
        try {
            await dht._add(peerId);
        } catch (err) {
            log.error(err);
        }
        const idB58Str = peerId.toB58String();
        log('from: %s', idB58Str);
        await pipe(stream.source, lp.decode(), /**
       * @param {AsyncIterable<Uint8Array>} source
       */ (source)=>(async function*() {
                for await (const msg of source){
                    // handle the message
                    const desMessage = Message.deserialize(msg.slice());
                    const res = await handleMessage(peerId, desMessage);
                    // Not all handlers will return a response
                    if (res) yield res.serialize();
                }
            })()
        , lp.encode(), stream.sink);
    }
    return onIncomingStream;
};

},{"it-pipe":"4jukm","it-length-prefixed":"2cvC1","../message":"5TcLe","./handlers":"7ZC1l","../utils":"16BUU"}],"5TcLe":[function(require,module,exports) {
'use strict';
const PeerId = require('peer-id');
const { Multiaddr  } = require('multiaddr');
const { Record  } = require('libp2p-record');
const Proto = require('./dht');
const MESSAGE_TYPE = Proto.Message.MessageType;
const CONNECTION_TYPE = Proto.Message.ConnectionType;
/**
 * @typedef {0|1|2|3|4} ConnectionType
 *
 * @typedef {object} PBPeer
 * @property {Uint8Array} id
 * @property {Uint8Array[]} addrs
 * @property {ConnectionType} connection
 *
 * @typedef {import('../index').PeerData} PeerData
 */ /**
 * Represents a single DHT control message.
 */ class Message {
    /**
   * @param {import('./dht').Message.MessageType} type
   * @param {Uint8Array} key
   * @param {number} level
   */ constructor(type, key, level){
        if (key && !(key instanceof Uint8Array)) throw new Error('Key must be a Uint8Array');
        this.type = type;
        this.key = key;
        this._clusterLevelRaw = level;
        /** @type {PeerData[]} */ this.closerPeers = [];
        /** @type {PeerData[]} */ this.providerPeers = [];
        /** @type {import('libp2p-record').Record | undefined} */ this.record = undefined;
    }
    /**
   * @type {number}
   */ get clusterLevel() {
        const level = this._clusterLevelRaw - 1;
        if (level < 0) return 0;
        return level;
    }
    set clusterLevel(level1) {
        this._clusterLevelRaw = level1;
    }
    /**
   * Encode into protobuf
   */ serialize() {
        const obj = {
            key: this.key,
            type: this.type,
            clusterLevelRaw: this._clusterLevelRaw,
            closerPeers: this.closerPeers.map(toPbPeer),
            providerPeers: this.providerPeers.map(toPbPeer),
            /** @type {Uint8Array | undefined} */ record: undefined
        };
        if (this.record) {
            if (this.record instanceof Uint8Array) obj.record = this.record;
            else obj.record = this.record.serialize();
        }
        return Proto.Message.encode(obj).finish();
    }
    /**
   * Decode from protobuf
   *
   * @param {Uint8Array} raw
   */ static deserialize(raw) {
        const dec = Proto.Message.decode(raw);
        const msg = new Message(dec.type || 0, dec.key || Uint8Array.from([]), dec.clusterLevelRaw || 0);
        msg.closerPeers = dec.closerPeers.map(fromPbPeer);
        msg.providerPeers = dec.providerPeers.map(fromPbPeer);
        if (dec.record && dec.record.length) msg.record = Record.deserialize(dec.record);
        return msg;
    }
}
Message.TYPES = MESSAGE_TYPE;
Message.CONNECTION_TYPES = CONNECTION_TYPE;
/**
 * @param {PeerData} peer
 */ function toPbPeer(peer) {
    /** @type {PBPeer} */ const output = {
        id: peer.id.id,
        addrs: (peer.multiaddrs || []).map((m)=>m.bytes
        ),
        connection: CONNECTION_TYPE.CONNECTED
    };
    return output;
}
/**
 * @param {import('./dht').Message.IPeer} peer
 */ function fromPbPeer(peer) {
    return {
        // @ts-ignore id is optional on protobuf, but it will exist?
        id: new PeerId(peer.id),
        multiaddrs: (peer.addrs || []).map((a)=>new Multiaddr(a)
        )
    };
}
module.exports = Message;

},{"peer-id":"4VGWt","multiaddr":"kOPrF","libp2p-record":"4hkIr","./dht":"bFKFj"}],"bFKFj":[function(require,module,exports) {
/*eslint-disable*/ "use strict";
var $protobuf = require("protobufjs/minimal");
// Common aliases
var $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util;
// Exported root namespace
var $root = $protobuf.roots["libp2p-dht-message"] || ($protobuf.roots["libp2p-dht-message"] = {
});
$root.Record = (function() {
    /**
     * Properties of a Record.
     * @exports IRecord
     * @interface IRecord
     * @property {Uint8Array|null} [key] Record key
     * @property {Uint8Array|null} [value] Record value
     * @property {Uint8Array|null} [author] Record author
     * @property {Uint8Array|null} [signature] Record signature
     * @property {string|null} [timeReceived] Record timeReceived
     */ /**
     * Constructs a new Record.
     * @exports Record
     * @classdesc Represents a Record.
     * @implements IRecord
     * @constructor
     * @param {IRecord=} [p] Properties to set
     */ function Record(p) {
        if (p) {
            for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
        }
    }
    /**
     * Record key.
     * @member {Uint8Array|null|undefined} key
     * @memberof Record
     * @instance
     */ Record.prototype.key = null;
    /**
     * Record value.
     * @member {Uint8Array|null|undefined} value
     * @memberof Record
     * @instance
     */ Record.prototype.value = null;
    /**
     * Record author.
     * @member {Uint8Array|null|undefined} author
     * @memberof Record
     * @instance
     */ Record.prototype.author = null;
    /**
     * Record signature.
     * @member {Uint8Array|null|undefined} signature
     * @memberof Record
     * @instance
     */ Record.prototype.signature = null;
    /**
     * Record timeReceived.
     * @member {string|null|undefined} timeReceived
     * @memberof Record
     * @instance
     */ Record.prototype.timeReceived = null;
    // OneOf field names bound to virtual getters and setters
    var $oneOfFields;
    /**
     * Record _key.
     * @member {"key"|undefined} _key
     * @memberof Record
     * @instance
     */ Object.defineProperty(Record.prototype, "_key", {
        get: $util.oneOfGetter($oneOfFields = [
            "key"
        ]),
        set: $util.oneOfSetter($oneOfFields)
    });
    /**
     * Record _value.
     * @member {"value"|undefined} _value
     * @memberof Record
     * @instance
     */ Object.defineProperty(Record.prototype, "_value", {
        get: $util.oneOfGetter($oneOfFields = [
            "value"
        ]),
        set: $util.oneOfSetter($oneOfFields)
    });
    /**
     * Record _author.
     * @member {"author"|undefined} _author
     * @memberof Record
     * @instance
     */ Object.defineProperty(Record.prototype, "_author", {
        get: $util.oneOfGetter($oneOfFields = [
            "author"
        ]),
        set: $util.oneOfSetter($oneOfFields)
    });
    /**
     * Record _signature.
     * @member {"signature"|undefined} _signature
     * @memberof Record
     * @instance
     */ Object.defineProperty(Record.prototype, "_signature", {
        get: $util.oneOfGetter($oneOfFields = [
            "signature"
        ]),
        set: $util.oneOfSetter($oneOfFields)
    });
    /**
     * Record _timeReceived.
     * @member {"timeReceived"|undefined} _timeReceived
     * @memberof Record
     * @instance
     */ Object.defineProperty(Record.prototype, "_timeReceived", {
        get: $util.oneOfGetter($oneOfFields = [
            "timeReceived"
        ]),
        set: $util.oneOfSetter($oneOfFields)
    });
    /**
     * Encodes the specified Record message. Does not implicitly {@link Record.verify|verify} messages.
     * @function encode
     * @memberof Record
     * @static
     * @param {IRecord} m Record message or plain object to encode
     * @param {$protobuf.Writer} [w] Writer to encode to
     * @returns {$protobuf.Writer} Writer
     */ Record.encode = function encode(m, w) {
        if (!w) w = $Writer.create();
        if (m.key != null && Object.hasOwnProperty.call(m, "key")) w.uint32(10).bytes(m.key);
        if (m.value != null && Object.hasOwnProperty.call(m, "value")) w.uint32(18).bytes(m.value);
        if (m.author != null && Object.hasOwnProperty.call(m, "author")) w.uint32(26).bytes(m.author);
        if (m.signature != null && Object.hasOwnProperty.call(m, "signature")) w.uint32(34).bytes(m.signature);
        if (m.timeReceived != null && Object.hasOwnProperty.call(m, "timeReceived")) w.uint32(42).string(m.timeReceived);
        return w;
    };
    /**
     * Decodes a Record message from the specified reader or buffer.
     * @function decode
     * @memberof Record
     * @static
     * @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
     * @param {number} [l] Message length if known beforehand
     * @returns {Record} Record
     * @throws {Error} If the payload is not a reader or valid buffer
     * @throws {$protobuf.util.ProtocolError} If required fields are missing
     */ Record.decode = function decode(r, l) {
        if (!(r instanceof $Reader)) r = $Reader.create(r);
        var c = l === undefined ? r.len : r.pos + l, m = new $root.Record();
        while(r.pos < c){
            var t = r.uint32();
            switch(t >>> 3){
                case 1:
                    m.key = r.bytes();
                    break;
                case 2:
                    m.value = r.bytes();
                    break;
                case 3:
                    m.author = r.bytes();
                    break;
                case 4:
                    m.signature = r.bytes();
                    break;
                case 5:
                    m.timeReceived = r.string();
                    break;
                default:
                    r.skipType(t & 7);
                    break;
            }
        }
        return m;
    };
    /**
     * Creates a Record message from a plain object. Also converts values to their respective internal types.
     * @function fromObject
     * @memberof Record
     * @static
     * @param {Object.<string,*>} d Plain object
     * @returns {Record} Record
     */ Record.fromObject = function fromObject(d) {
        if (d instanceof $root.Record) return d;
        var m = new $root.Record();
        if (d.key != null) {
            if (typeof d.key === "string") $util.base64.decode(d.key, m.key = $util.newBuffer($util.base64.length(d.key)), 0);
            else if (d.key.length) m.key = d.key;
        }
        if (d.value != null) {
            if (typeof d.value === "string") $util.base64.decode(d.value, m.value = $util.newBuffer($util.base64.length(d.value)), 0);
            else if (d.value.length) m.value = d.value;
        }
        if (d.author != null) {
            if (typeof d.author === "string") $util.base64.decode(d.author, m.author = $util.newBuffer($util.base64.length(d.author)), 0);
            else if (d.author.length) m.author = d.author;
        }
        if (d.signature != null) {
            if (typeof d.signature === "string") $util.base64.decode(d.signature, m.signature = $util.newBuffer($util.base64.length(d.signature)), 0);
            else if (d.signature.length) m.signature = d.signature;
        }
        if (d.timeReceived != null) m.timeReceived = String(d.timeReceived);
        return m;
    };
    /**
     * Creates a plain object from a Record message. Also converts values to other types if specified.
     * @function toObject
     * @memberof Record
     * @static
     * @param {Record} m Record
     * @param {$protobuf.IConversionOptions} [o] Conversion options
     * @returns {Object.<string,*>} Plain object
     */ Record.toObject = function toObject(m, o) {
        if (!o) o = {
        };
        var d = {
        };
        if (m.key != null && m.hasOwnProperty("key")) {
            d.key = o.bytes === String ? $util.base64.encode(m.key, 0, m.key.length) : o.bytes === Array ? Array.prototype.slice.call(m.key) : m.key;
            if (o.oneofs) d._key = "key";
        }
        if (m.value != null && m.hasOwnProperty("value")) {
            d.value = o.bytes === String ? $util.base64.encode(m.value, 0, m.value.length) : o.bytes === Array ? Array.prototype.slice.call(m.value) : m.value;
            if (o.oneofs) d._value = "value";
        }
        if (m.author != null && m.hasOwnProperty("author")) {
            d.author = o.bytes === String ? $util.base64.encode(m.author, 0, m.author.length) : o.bytes === Array ? Array.prototype.slice.call(m.author) : m.author;
            if (o.oneofs) d._author = "author";
        }
        if (m.signature != null && m.hasOwnProperty("signature")) {
            d.signature = o.bytes === String ? $util.base64.encode(m.signature, 0, m.signature.length) : o.bytes === Array ? Array.prototype.slice.call(m.signature) : m.signature;
            if (o.oneofs) d._signature = "signature";
        }
        if (m.timeReceived != null && m.hasOwnProperty("timeReceived")) {
            d.timeReceived = m.timeReceived;
            if (o.oneofs) d._timeReceived = "timeReceived";
        }
        return d;
    };
    /**
     * Converts this Record to JSON.
     * @function toJSON
     * @memberof Record
     * @instance
     * @returns {Object.<string,*>} JSON object
     */ Record.prototype.toJSON = function toJSON() {
        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
    };
    return Record;
})();
$root.Message = (function() {
    /**
     * Properties of a Message.
     * @exports IMessage
     * @interface IMessage
     * @property {Message.MessageType|null} [type] Message type
     * @property {number|null} [clusterLevelRaw] Message clusterLevelRaw
     * @property {Uint8Array|null} [key] Message key
     * @property {Uint8Array|null} [record] Message record
     * @property {Array.<Message.IPeer>|null} [closerPeers] Message closerPeers
     * @property {Array.<Message.IPeer>|null} [providerPeers] Message providerPeers
     */ /**
     * Constructs a new Message.
     * @exports Message
     * @classdesc Represents a Message.
     * @implements IMessage
     * @constructor
     * @param {IMessage=} [p] Properties to set
     */ function Message(p) {
        this.closerPeers = [];
        this.providerPeers = [];
        if (p) {
            for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
        }
    }
    /**
     * Message type.
     * @member {Message.MessageType|null|undefined} type
     * @memberof Message
     * @instance
     */ Message.prototype.type = null;
    /**
     * Message clusterLevelRaw.
     * @member {number|null|undefined} clusterLevelRaw
     * @memberof Message
     * @instance
     */ Message.prototype.clusterLevelRaw = null;
    /**
     * Message key.
     * @member {Uint8Array|null|undefined} key
     * @memberof Message
     * @instance
     */ Message.prototype.key = null;
    /**
     * Message record.
     * @member {Uint8Array|null|undefined} record
     * @memberof Message
     * @instance
     */ Message.prototype.record = null;
    /**
     * Message closerPeers.
     * @member {Array.<Message.IPeer>} closerPeers
     * @memberof Message
     * @instance
     */ Message.prototype.closerPeers = $util.emptyArray;
    /**
     * Message providerPeers.
     * @member {Array.<Message.IPeer>} providerPeers
     * @memberof Message
     * @instance
     */ Message.prototype.providerPeers = $util.emptyArray;
    // OneOf field names bound to virtual getters and setters
    var $oneOfFields1;
    /**
     * Message _type.
     * @member {"type"|undefined} _type
     * @memberof Message
     * @instance
     */ Object.defineProperty(Message.prototype, "_type", {
        get: $util.oneOfGetter($oneOfFields1 = [
            "type"
        ]),
        set: $util.oneOfSetter($oneOfFields1)
    });
    /**
     * Message _clusterLevelRaw.
     * @member {"clusterLevelRaw"|undefined} _clusterLevelRaw
     * @memberof Message
     * @instance
     */ Object.defineProperty(Message.prototype, "_clusterLevelRaw", {
        get: $util.oneOfGetter($oneOfFields1 = [
            "clusterLevelRaw"
        ]),
        set: $util.oneOfSetter($oneOfFields1)
    });
    /**
     * Message _key.
     * @member {"key"|undefined} _key
     * @memberof Message
     * @instance
     */ Object.defineProperty(Message.prototype, "_key", {
        get: $util.oneOfGetter($oneOfFields1 = [
            "key"
        ]),
        set: $util.oneOfSetter($oneOfFields1)
    });
    /**
     * Message _record.
     * @member {"record"|undefined} _record
     * @memberof Message
     * @instance
     */ Object.defineProperty(Message.prototype, "_record", {
        get: $util.oneOfGetter($oneOfFields1 = [
            "record"
        ]),
        set: $util.oneOfSetter($oneOfFields1)
    });
    /**
     * Encodes the specified Message message. Does not implicitly {@link Message.verify|verify} messages.
     * @function encode
     * @memberof Message
     * @static
     * @param {IMessage} m Message message or plain object to encode
     * @param {$protobuf.Writer} [w] Writer to encode to
     * @returns {$protobuf.Writer} Writer
     */ Message.encode = function encode(m, w) {
        if (!w) w = $Writer.create();
        if (m.type != null && Object.hasOwnProperty.call(m, "type")) w.uint32(8).int32(m.type);
        if (m.key != null && Object.hasOwnProperty.call(m, "key")) w.uint32(18).bytes(m.key);
        if (m.record != null && Object.hasOwnProperty.call(m, "record")) w.uint32(26).bytes(m.record);
        if (m.closerPeers != null && m.closerPeers.length) for(var i = 0; i < m.closerPeers.length; ++i)$root.Message.Peer.encode(m.closerPeers[i], w.uint32(66).fork()).ldelim();
        if (m.providerPeers != null && m.providerPeers.length) for(var i = 0; i < m.providerPeers.length; ++i)$root.Message.Peer.encode(m.providerPeers[i], w.uint32(74).fork()).ldelim();
        if (m.clusterLevelRaw != null && Object.hasOwnProperty.call(m, "clusterLevelRaw")) w.uint32(80).int32(m.clusterLevelRaw);
        return w;
    };
    /**
     * Decodes a Message message from the specified reader or buffer.
     * @function decode
     * @memberof Message
     * @static
     * @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
     * @param {number} [l] Message length if known beforehand
     * @returns {Message} Message
     * @throws {Error} If the payload is not a reader or valid buffer
     * @throws {$protobuf.util.ProtocolError} If required fields are missing
     */ Message.decode = function decode(r, l) {
        if (!(r instanceof $Reader)) r = $Reader.create(r);
        var c = l === undefined ? r.len : r.pos + l, m = new $root.Message();
        while(r.pos < c){
            var t = r.uint32();
            switch(t >>> 3){
                case 1:
                    m.type = r.int32();
                    break;
                case 10:
                    m.clusterLevelRaw = r.int32();
                    break;
                case 2:
                    m.key = r.bytes();
                    break;
                case 3:
                    m.record = r.bytes();
                    break;
                case 8:
                    if (!(m.closerPeers && m.closerPeers.length)) m.closerPeers = [];
                    m.closerPeers.push($root.Message.Peer.decode(r, r.uint32()));
                    break;
                case 9:
                    if (!(m.providerPeers && m.providerPeers.length)) m.providerPeers = [];
                    m.providerPeers.push($root.Message.Peer.decode(r, r.uint32()));
                    break;
                default:
                    r.skipType(t & 7);
                    break;
            }
        }
        return m;
    };
    /**
     * Creates a Message message from a plain object. Also converts values to their respective internal types.
     * @function fromObject
     * @memberof Message
     * @static
     * @param {Object.<string,*>} d Plain object
     * @returns {Message} Message
     */ Message.fromObject = function fromObject(d) {
        if (d instanceof $root.Message) return d;
        var m = new $root.Message();
        switch(d.type){
            case "PUT_VALUE":
            case 0:
                m.type = 0;
                break;
            case "GET_VALUE":
            case 1:
                m.type = 1;
                break;
            case "ADD_PROVIDER":
            case 2:
                m.type = 2;
                break;
            case "GET_PROVIDERS":
            case 3:
                m.type = 3;
                break;
            case "FIND_NODE":
            case 4:
                m.type = 4;
                break;
            case "PING":
            case 5:
                m.type = 5;
                break;
        }
        if (d.clusterLevelRaw != null) m.clusterLevelRaw = d.clusterLevelRaw | 0;
        if (d.key != null) {
            if (typeof d.key === "string") $util.base64.decode(d.key, m.key = $util.newBuffer($util.base64.length(d.key)), 0);
            else if (d.key.length) m.key = d.key;
        }
        if (d.record != null) {
            if (typeof d.record === "string") $util.base64.decode(d.record, m.record = $util.newBuffer($util.base64.length(d.record)), 0);
            else if (d.record.length) m.record = d.record;
        }
        if (d.closerPeers) {
            if (!Array.isArray(d.closerPeers)) throw TypeError(".Message.closerPeers: array expected");
            m.closerPeers = [];
            for(var i = 0; i < d.closerPeers.length; ++i){
                if (typeof d.closerPeers[i] !== "object") throw TypeError(".Message.closerPeers: object expected");
                m.closerPeers[i] = $root.Message.Peer.fromObject(d.closerPeers[i]);
            }
        }
        if (d.providerPeers) {
            if (!Array.isArray(d.providerPeers)) throw TypeError(".Message.providerPeers: array expected");
            m.providerPeers = [];
            for(var i = 0; i < d.providerPeers.length; ++i){
                if (typeof d.providerPeers[i] !== "object") throw TypeError(".Message.providerPeers: object expected");
                m.providerPeers[i] = $root.Message.Peer.fromObject(d.providerPeers[i]);
            }
        }
        return m;
    };
    /**
     * Creates a plain object from a Message message. Also converts values to other types if specified.
     * @function toObject
     * @memberof Message
     * @static
     * @param {Message} m Message
     * @param {$protobuf.IConversionOptions} [o] Conversion options
     * @returns {Object.<string,*>} Plain object
     */ Message.toObject = function toObject(m, o) {
        if (!o) o = {
        };
        var d = {
        };
        if (o.arrays || o.defaults) {
            d.closerPeers = [];
            d.providerPeers = [];
        }
        if (m.type != null && m.hasOwnProperty("type")) {
            d.type = o.enums === String ? $root.Message.MessageType[m.type] : m.type;
            if (o.oneofs) d._type = "type";
        }
        if (m.key != null && m.hasOwnProperty("key")) {
            d.key = o.bytes === String ? $util.base64.encode(m.key, 0, m.key.length) : o.bytes === Array ? Array.prototype.slice.call(m.key) : m.key;
            if (o.oneofs) d._key = "key";
        }
        if (m.record != null && m.hasOwnProperty("record")) {
            d.record = o.bytes === String ? $util.base64.encode(m.record, 0, m.record.length) : o.bytes === Array ? Array.prototype.slice.call(m.record) : m.record;
            if (o.oneofs) d._record = "record";
        }
        if (m.closerPeers && m.closerPeers.length) {
            d.closerPeers = [];
            for(var j = 0; j < m.closerPeers.length; ++j)d.closerPeers[j] = $root.Message.Peer.toObject(m.closerPeers[j], o);
        }
        if (m.providerPeers && m.providerPeers.length) {
            d.providerPeers = [];
            for(var j = 0; j < m.providerPeers.length; ++j)d.providerPeers[j] = $root.Message.Peer.toObject(m.providerPeers[j], o);
        }
        if (m.clusterLevelRaw != null && m.hasOwnProperty("clusterLevelRaw")) {
            d.clusterLevelRaw = m.clusterLevelRaw;
            if (o.oneofs) d._clusterLevelRaw = "clusterLevelRaw";
        }
        return d;
    };
    /**
     * Converts this Message to JSON.
     * @function toJSON
     * @memberof Message
     * @instance
     * @returns {Object.<string,*>} JSON object
     */ Message.prototype.toJSON = function toJSON() {
        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
    };
    /**
     * MessageType enum.
     * @name Message.MessageType
     * @enum {number}
     * @property {number} PUT_VALUE=0 PUT_VALUE value
     * @property {number} GET_VALUE=1 GET_VALUE value
     * @property {number} ADD_PROVIDER=2 ADD_PROVIDER value
     * @property {number} GET_PROVIDERS=3 GET_PROVIDERS value
     * @property {number} FIND_NODE=4 FIND_NODE value
     * @property {number} PING=5 PING value
     */ Message.MessageType = (function() {
        var valuesById = {
        }, values = Object.create(valuesById);
        values[valuesById[0] = "PUT_VALUE"] = 0;
        values[valuesById[1] = "GET_VALUE"] = 1;
        values[valuesById[2] = "ADD_PROVIDER"] = 2;
        values[valuesById[3] = "GET_PROVIDERS"] = 3;
        values[valuesById[4] = "FIND_NODE"] = 4;
        values[valuesById[5] = "PING"] = 5;
        return values;
    })();
    /**
     * ConnectionType enum.
     * @name Message.ConnectionType
     * @enum {number}
     * @property {number} NOT_CONNECTED=0 NOT_CONNECTED value
     * @property {number} CONNECTED=1 CONNECTED value
     * @property {number} CAN_CONNECT=2 CAN_CONNECT value
     * @property {number} CANNOT_CONNECT=3 CANNOT_CONNECT value
     */ Message.ConnectionType = (function() {
        var valuesById = {
        }, values = Object.create(valuesById);
        values[valuesById[0] = "NOT_CONNECTED"] = 0;
        values[valuesById[1] = "CONNECTED"] = 1;
        values[valuesById[2] = "CAN_CONNECT"] = 2;
        values[valuesById[3] = "CANNOT_CONNECT"] = 3;
        return values;
    })();
    Message.Peer = (function() {
        /**
         * Properties of a Peer.
         * @memberof Message
         * @interface IPeer
         * @property {Uint8Array|null} [id] Peer id
         * @property {Array.<Uint8Array>|null} [addrs] Peer addrs
         * @property {Message.ConnectionType|null} [connection] Peer connection
         */ /**
         * Constructs a new Peer.
         * @memberof Message
         * @classdesc Represents a Peer.
         * @implements IPeer
         * @constructor
         * @param {Message.IPeer=} [p] Properties to set
         */ function Peer(p) {
            this.addrs = [];
            if (p) {
                for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
            }
        }
        /**
         * Peer id.
         * @member {Uint8Array|null|undefined} id
         * @memberof Message.Peer
         * @instance
         */ Peer.prototype.id = null;
        /**
         * Peer addrs.
         * @member {Array.<Uint8Array>} addrs
         * @memberof Message.Peer
         * @instance
         */ Peer.prototype.addrs = $util.emptyArray;
        /**
         * Peer connection.
         * @member {Message.ConnectionType|null|undefined} connection
         * @memberof Message.Peer
         * @instance
         */ Peer.prototype.connection = null;
        // OneOf field names bound to virtual getters and setters
        var $oneOfFields;
        /**
         * Peer _id.
         * @member {"id"|undefined} _id
         * @memberof Message.Peer
         * @instance
         */ Object.defineProperty(Peer.prototype, "_id", {
            get: $util.oneOfGetter($oneOfFields = [
                "id"
            ]),
            set: $util.oneOfSetter($oneOfFields)
        });
        /**
         * Peer _connection.
         * @member {"connection"|undefined} _connection
         * @memberof Message.Peer
         * @instance
         */ Object.defineProperty(Peer.prototype, "_connection", {
            get: $util.oneOfGetter($oneOfFields = [
                "connection"
            ]),
            set: $util.oneOfSetter($oneOfFields)
        });
        /**
         * Encodes the specified Peer message. Does not implicitly {@link Message.Peer.verify|verify} messages.
         * @function encode
         * @memberof Message.Peer
         * @static
         * @param {Message.IPeer} m Peer message or plain object to encode
         * @param {$protobuf.Writer} [w] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */ Peer.encode = function encode(m, w) {
            if (!w) w = $Writer.create();
            if (m.id != null && Object.hasOwnProperty.call(m, "id")) w.uint32(10).bytes(m.id);
            if (m.addrs != null && m.addrs.length) for(var i = 0; i < m.addrs.length; ++i)w.uint32(18).bytes(m.addrs[i]);
            if (m.connection != null && Object.hasOwnProperty.call(m, "connection")) w.uint32(24).int32(m.connection);
            return w;
        };
        /**
         * Decodes a Peer message from the specified reader or buffer.
         * @function decode
         * @memberof Message.Peer
         * @static
         * @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
         * @param {number} [l] Message length if known beforehand
         * @returns {Message.Peer} Peer
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */ Peer.decode = function decode(r, l) {
            if (!(r instanceof $Reader)) r = $Reader.create(r);
            var c = l === undefined ? r.len : r.pos + l, m = new $root.Message.Peer();
            while(r.pos < c){
                var t = r.uint32();
                switch(t >>> 3){
                    case 1:
                        m.id = r.bytes();
                        break;
                    case 2:
                        if (!(m.addrs && m.addrs.length)) m.addrs = [];
                        m.addrs.push(r.bytes());
                        break;
                    case 3:
                        m.connection = r.int32();
                        break;
                    default:
                        r.skipType(t & 7);
                        break;
                }
            }
            return m;
        };
        /**
         * Creates a Peer message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof Message.Peer
         * @static
         * @param {Object.<string,*>} d Plain object
         * @returns {Message.Peer} Peer
         */ Peer.fromObject = function fromObject(d) {
            if (d instanceof $root.Message.Peer) return d;
            var m = new $root.Message.Peer();
            if (d.id != null) {
                if (typeof d.id === "string") $util.base64.decode(d.id, m.id = $util.newBuffer($util.base64.length(d.id)), 0);
                else if (d.id.length) m.id = d.id;
            }
            if (d.addrs) {
                if (!Array.isArray(d.addrs)) throw TypeError(".Message.Peer.addrs: array expected");
                m.addrs = [];
                for(var i = 0; i < d.addrs.length; ++i){
                    if (typeof d.addrs[i] === "string") $util.base64.decode(d.addrs[i], m.addrs[i] = $util.newBuffer($util.base64.length(d.addrs[i])), 0);
                    else if (d.addrs[i].length) m.addrs[i] = d.addrs[i];
                }
            }
            switch(d.connection){
                case "NOT_CONNECTED":
                case 0:
                    m.connection = 0;
                    break;
                case "CONNECTED":
                case 1:
                    m.connection = 1;
                    break;
                case "CAN_CONNECT":
                case 2:
                    m.connection = 2;
                    break;
                case "CANNOT_CONNECT":
                case 3:
                    m.connection = 3;
                    break;
            }
            return m;
        };
        /**
         * Creates a plain object from a Peer message. Also converts values to other types if specified.
         * @function toObject
         * @memberof Message.Peer
         * @static
         * @param {Message.Peer} m Peer
         * @param {$protobuf.IConversionOptions} [o] Conversion options
         * @returns {Object.<string,*>} Plain object
         */ Peer.toObject = function toObject(m, o) {
            if (!o) o = {
            };
            var d = {
            };
            if (o.arrays || o.defaults) d.addrs = [];
            if (m.id != null && m.hasOwnProperty("id")) {
                d.id = o.bytes === String ? $util.base64.encode(m.id, 0, m.id.length) : o.bytes === Array ? Array.prototype.slice.call(m.id) : m.id;
                if (o.oneofs) d._id = "id";
            }
            if (m.addrs && m.addrs.length) {
                d.addrs = [];
                for(var j = 0; j < m.addrs.length; ++j)d.addrs[j] = o.bytes === String ? $util.base64.encode(m.addrs[j], 0, m.addrs[j].length) : o.bytes === Array ? Array.prototype.slice.call(m.addrs[j]) : m.addrs[j];
            }
            if (m.connection != null && m.hasOwnProperty("connection")) {
                d.connection = o.enums === String ? $root.Message.ConnectionType[m.connection] : m.connection;
                if (o.oneofs) d._connection = "connection";
            }
            return d;
        };
        /**
         * Converts this Peer to JSON.
         * @function toJSON
         * @memberof Message.Peer
         * @instance
         * @returns {Object.<string,*>} JSON object
         */ Peer.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };
        return Peer;
    })();
    return Message;
})();
module.exports = $root;

},{"protobufjs/minimal":"9Jmso"}],"7ZC1l":[function(require,module,exports) {
'use strict';
const T = require('../../message').TYPES;
/**
 *
 * @param {import('../../index')} dht
 */ module.exports = (dht)=>{
    const handlers = {
        [T.GET_VALUE]: require('./get-value')(dht),
        [T.PUT_VALUE]: require('./put-value')(dht),
        [T.FIND_NODE]: require('./find-node')(dht),
        [T.ADD_PROVIDER]: require('./add-provider')(dht),
        [T.GET_PROVIDERS]: require('./get-providers')(dht),
        [T.PING]: require('./ping')(dht)
    };
    /**
   * Get the message handler matching the passed in type.
   *
   * @param {number} type
   */ function getMessageHandler(type) {
        // @ts-ignore ts does not aknowledge number as an index type
        return handlers[type];
    }
    return getMessageHandler;
};

},{"../../message":"5TcLe","./get-value":"da1At","./put-value":"4kjLW","./find-node":"gfYOr","./add-provider":"78rxj","./get-providers":"69bsO","./ping":"etGgx"}],"da1At":[function(require,module,exports) {
'use strict';
const { Record  } = require('libp2p-record');
const errcode = require('err-code');
const Message = require('../../message');
const utils = require('../../utils');
/**
 * @typedef {import('peer-id')} PeerId
 */ /**
 * @param {import('../../index')} dht
 */ module.exports = (dht)=>{
    const log = utils.logger(dht.peerId, 'rpc:get-value');
    /**
   * Process `GetValue` DHT messages.
   *
   * @param {PeerId} peerId
   * @param {Message} msg
   * @returns {Promise<Message>}
   */ async function getValue(peerId, msg) {
        const key = msg.key;
        log('key: %b', key);
        if (!key || key.length === 0) throw errcode(new Error('Invalid key'), 'ERR_INVALID_KEY');
        const response = new Message(Message.TYPES.GET_VALUE, key, msg.clusterLevel);
        if (utils.isPublicKeyKey(key)) {
            log('is public key');
            const idFromKey = utils.fromPublicKeyKey(key);
            let id;
            if (dht._isSelf(idFromKey)) id = dht.peerId;
            else {
                const peerData = dht.peerStore.get(idFromKey);
                id = peerData && peerData.id;
            }
            if (id && id.pubKey) {
                log('returning found public key');
                response.record = new Record(key, id.pubKey.bytes);
                return response;
            }
        }
        const [record, closer] = await Promise.all([
            dht._checkLocalDatastore(key),
            dht._betterPeersToQuery(msg, peerId)
        ]);
        if (record) {
            log('got record');
            response.record = record;
        }
        if (closer.length > 0) {
            log('got closer %s', closer.length);
            response.closerPeers = closer;
        }
        return response;
    }
    return getValue;
};

},{"libp2p-record":"4hkIr","err-code":"eQvyh","../../message":"5TcLe","../../utils":"16BUU"}],"4kjLW":[function(require,module,exports) {
'use strict';
const utils = require('../../utils');
const errcode = require('err-code');
/**
 * @typedef {import('peer-id')} PeerId
 * @typedef {import('../../message')} Message
 */ /**
 * @param {import('../../index')} dht
 */ module.exports = (dht)=>{
    const log = utils.logger(dht.peerId, 'rpc:put-value');
    /**
   * Process `PutValue` DHT messages.
   *
   * @param {PeerId} peerId
   * @param {Message} msg
   */ async function putValue(peerId, msg) {
        const key = msg.key;
        log('key: %b', key);
        const record = msg.record;
        if (!record) {
            const errMsg = `Empty record from: ${peerId.toB58String()}`;
            log.error(errMsg);
            throw errcode(new Error(errMsg), 'ERR_EMPTY_RECORD');
        }
        await dht._verifyRecordLocally(record);
        record.timeReceived = new Date();
        const recordKey = utils.bufferToKey(record.key);
        await dht.datastore.put(recordKey, record.serialize());
        dht.onPut(record, peerId);
        return msg;
    }
    return putValue;
};

},{"../../utils":"16BUU","err-code":"eQvyh"}],"gfYOr":[function(require,module,exports) {
'use strict';
const { equals: uint8ArrayEquals  } = require('uint8arrays/equals');
const Message = require('../../message');
const utils = require('../../utils');
/**
 * @typedef {import('peer-id')} PeerId
 */ /**
 * @param {import('../../index')} dht
 */ module.exports = (dht)=>{
    const log = utils.logger(dht.peerId, 'rpc:find-node');
    /**
   * Process `FindNode` DHT messages.
   *
   * @param {PeerId} peerId
   * @param {Message} msg
   */ async function findNode(peerId, msg) {
        log('start');
        let closer;
        if (uint8ArrayEquals(msg.key, dht.peerId.id)) closer = [
            {
                id: dht.peerId,
                multiaddrs: dht.libp2p.multiaddrs
            }
        ];
        else closer = await dht._betterPeersToQuery(msg, peerId);
        const response = new Message(msg.type, new Uint8Array(0), msg.clusterLevel);
        if (closer.length > 0) response.closerPeers = closer;
        else log('handle FindNode %s: could not find anything', peerId.toB58String());
        return response;
    }
    return findNode;
};

},{"uint8arrays/equals":"fjLeN","../../message":"5TcLe","../../utils":"16BUU"}],"78rxj":[function(require,module,exports) {
'use strict';
const { CID  } = require('multiformats/cid');
const errcode = require('err-code');
const utils = require('../../utils');
/**
 * @typedef {import('peer-id')} PeerId
 * @typedef {import('../../message')} Message
 */ /**
 * @param {import('../../index')} dht
 */ module.exports = (dht)=>{
    const log = utils.logger(dht.peerId, 'rpc:add-provider');
    /**
   * Process `AddProvider` DHT messages.
   *
   * @param {PeerId} peerId
   * @param {Message} msg
   */ async function addProvider(peerId, msg) {
        log('start');
        if (!msg.key || msg.key.length === 0) throw errcode(new Error('Missing key'), 'ERR_MISSING_KEY');
        /** @type {CID} */ let cid;
        try {
            cid = CID.decode(msg.key);
        } catch (err) {
            const errMsg = `Invalid CID: ${err.message}`;
            throw errcode(new Error(errMsg), 'ERR_INVALID_CID');
        }
        msg.providerPeers.forEach((pi)=>{
            // Ignore providers not from the originator
            if (!pi.id.isEqual(peerId)) {
                log('invalid provider peer %s from %s', pi.id.toB58String(), peerId.toB58String());
                return;
            }
            if (pi.multiaddrs.length < 1) {
                log('no valid addresses for provider %s. Ignore', peerId.toB58String());
                return;
            }
            log('received provider %s for %s (addrs %s)', peerId.toB58String(), cid.toString(), pi.multiaddrs.map((m)=>m.toString()
            ));
            if (!dht._isSelf(pi.id)) {
                // Add known address to peer store
                dht.peerStore.addressBook.add(pi.id, pi.multiaddrs);
                return dht.providers.addProvider(cid, pi.id);
            }
        });
        // Previous versions of the JS DHT sent erroneous providers in the
        // `providerPeers` field. In order to accommodate older clients that have
        // this bug, we fall back to assuming the originator is the provider if
        // we can't find any valid providers in the payload.
        // https://github.com/libp2p/js-libp2p-kad-dht/pull/127
        // https://github.com/libp2p/js-libp2p-kad-dht/issues/128
        return dht.providers.addProvider(cid, peerId);
    }
    return addProvider;
};

},{"multiformats/cid":"fJJnW","err-code":"eQvyh","../../utils":"16BUU"}],"69bsO":[function(require,module,exports) {
'use strict';
const { CID  } = require('multiformats/cid');
const errcode = require('err-code');
const Message = require('../../message');
const utils = require('../../utils');
/**
 * @typedef {import('peer-id')} PeerId
 */ /**
 * @param {import('../../index')} dht
 */ module.exports = (dht)=>{
    const log = utils.logger(dht.peerId, 'rpc:get-providers');
    /**
   * Process `GetProviders` DHT messages.
   *
   * @param {PeerId} peerId
   * @param {Message} msg
   */ async function getProviders(peerId1, msg) {
        let cid;
        try {
            cid = CID.decode(msg.key);
        } catch (err) {
            throw errcode(new Error(`Invalid CID: ${err.message}`), 'ERR_INVALID_CID');
        }
        log('%s', cid.toString());
        const dsKey = utils.bufferToKey(cid.bytes);
        const [has, peers, closer] = await Promise.all([
            dht.datastore.has(dsKey),
            dht.providers.getProviders(cid),
            dht._betterPeersToQuery(msg, peerId1)
        ]);
        const providerPeers = peers.map((peerId)=>({
                id: peerId,
                multiaddrs: []
            })
        );
        const closerPeers = closer.map((c)=>({
                id: c.id,
                multiaddrs: []
            })
        );
        if (has) providerPeers.push({
            id: dht.peerId,
            multiaddrs: []
        });
        const response = new Message(msg.type, msg.key, msg.clusterLevel);
        if (providerPeers.length > 0) response.providerPeers = providerPeers;
        if (closerPeers.length > 0) response.closerPeers = closerPeers;
        log('got %s providers %s closerPeers', providerPeers.length, closerPeers.length);
        return response;
    }
    return getProviders;
};

},{"multiformats/cid":"fJJnW","err-code":"eQvyh","../../message":"5TcLe","../../utils":"16BUU"}],"etGgx":[function(require,module,exports) {
'use strict';
const utils = require('../../utils');
/**
 * @typedef {import('peer-id')} PeerId
 * @typedef {import('../../message')} Message
 */ /**
 * @param {import('../../index')} dht
 */ module.exports = (dht)=>{
    const log = utils.logger(dht.peerId, 'rpc:ping');
    /**
   * Process `Ping` DHT messages.
   *
   * @param {PeerId} peerId
   * @param {Message} msg
   */ function ping(peerId, msg) {
        log('from %s', peerId.toB58String());
        return msg;
    }
    return ping;
};

},{"../../utils":"16BUU"}],"1Ifs8":[function(require,module,exports) {
'use strict';
const errcode = require('err-code');
const pTimeout = require('p-timeout');
const { equals: uint8ArrayEquals  } = require('uint8arrays/equals');
const { toString: uint8ArrayToString  } = require('uint8arrays/to-string');
const libp2pRecord = require('libp2p-record');
const c = require('../constants');
const Query = require('../query');
const utils = require('../utils');
const Record = libp2pRecord.Record;
/**
 * @typedef {import('peer-id')} PeerId
 * @typedef {import('../query').DHTQueryResult} DHTQueryResult
 */ /**
 * @param {import('../')} dht
 */ module.exports = (dht)=>{
    /**
   * @param {Uint8Array} key
   * @param {Uint8Array} rec
   */ const putLocal = async (key, rec)=>{
        return dht.datastore.put(utils.bufferToKey(key), rec);
    };
    /**
   * Attempt to retrieve the value for the given key from
   * the local datastore.
   *
   * @param {Uint8Array} key
   */ const getLocal = async (key)=>{
        dht._log(`getLocal ${uint8ArrayToString(key, 'base32')}`);
        const raw = await dht.datastore.get(utils.bufferToKey(key));
        dht._log(`found ${uint8ArrayToString(key, 'base32')} in local datastore`);
        const rec = Record.deserialize(raw);
        await dht._verifyRecordLocally(rec);
        return rec;
    };
    /**
   * Send the best record found to any peers that have an out of date record.
   *
   * @param {Uint8Array} key
   * @param {import('../query').DHTQueryValue[]} vals - values retrieved from the DHT
   * @param {Uint8Array} best - the best record that was found
   */ const sendCorrectionRecord = async (key, vals, best)=>{
        const fixupRec = await utils.createPutRecord(key, best);
        return Promise.all(vals.map(async (v)=>{
            // no need to do anything
            if (uint8ArrayEquals(v.val, best)) return;
            // correct ourself
            if (dht._isSelf(v.from)) {
                try {
                    await dht._putLocal(key, fixupRec);
                } catch (err) {
                    dht._log.error('Failed error correcting self', err);
                }
                return;
            }
            // send correction
            try {
                await dht._putValueToPeer(key, fixupRec, v.from);
            } catch (err) {
                dht._log.error('Failed error correcting entry', err);
            }
        }));
    };
    return {
        /**
     * Store the given key/value pair locally, in the datastore.
     *
     * @param {Uint8Array} key
     * @param {Uint8Array} rec - encoded record
     */ async _putLocal (key, rec) {
            return putLocal(key, rec);
        },
        /**
     * Store the given key/value  pair in the DHT.
     *
     * @param {Uint8Array} key
     * @param {Uint8Array} value
     * @param {object} [options] - put options
     * @param {number} [options.minPeers] - minimum number of peers required to successfully put (default: closestPeers.length)
     */ async put (key, value, options = {
        }) {
            dht._log('PutValue %b', key);
            // create record in the dht format
            const record = await utils.createPutRecord(key, value);
            // store the record locally
            await putLocal(key, record);
            // put record to the closest peers
            let counterAll = 0;
            let counterSuccess = 0;
            await utils.mapParallel(dht.getClosestPeers(key, {
                shallow: true
            }), async (peer)=>{
                try {
                    counterAll += 1;
                    await dht._putValueToPeer(key, record, peer);
                    counterSuccess += 1;
                } catch (err) {
                    dht._log.error('Failed to put to peer (%b): %s', peer.id, err);
                }
            });
            // verify if we were able to put to enough peers
            const minPeers = options.minPeers || counterAll // Ensure we have a default `minPeers`
            ;
            if (minPeers > counterSuccess) {
                const error = errcode(new Error(`Failed to put value to enough peers: ${counterSuccess}/${minPeers}`), 'ERR_NOT_ENOUGH_PUT_PEERS');
                dht._log.error(error);
                throw error;
            }
        },
        /**
     * Get the value to the given key.
     * Times out after 1 minute by default.
     *
     * @param {Uint8Array} key
     * @param {object} [options] - get options
     * @param {number} [options.timeout] - optional timeout (default: 60000)
     */ async get (key, options = {
        }) {
            options.timeout = options.timeout || c.minute;
            dht._log('_get %b', key);
            const vals = await dht.getMany(key, c.GET_MANY_RECORD_COUNT, options);
            const recs = vals.map((v)=>v.val
            );
            let i = 0;
            try {
                i = libp2pRecord.selection.bestRecord(dht.selectors, key, recs);
            } catch (err) {
                // Assume the first record if no selector available
                if (err.code !== 'ERR_NO_SELECTOR_FUNCTION_FOR_RECORD_KEY') throw err;
            }
            const best = recs[i];
            dht._log('GetValue %b %s', key, best);
            if (!best) throw errcode(new Error('best value was not found'), 'ERR_NOT_FOUND');
            await sendCorrectionRecord(key, vals, best);
            return best;
        },
        /**
     * Get the `n` values to the given key without sorting.
     *
     * @param {Uint8Array} key
     * @param {number} nvals
     * @param {object} [options] - get options
     * @param {number} [options.timeout] - optional timeout (default: 60000)
     */ async getMany (key, nvals, options = {
        }) {
            options.timeout = options.timeout || c.minute;
            dht._log('getMany %b (%s)', key, nvals);
            const vals = [];
            let localRec;
            try {
                localRec = await getLocal(key);
            } catch (err1) {
                if (nvals === 0) throw err1;
            }
            if (localRec) vals.push({
                val: localRec.value,
                from: dht.peerId
            });
            if (vals.length >= nvals) return vals;
            const id = await utils.convertBuffer(key);
            const rtp = dht.routingTable.closestPeers(id, dht.kBucketSize);
            dht._log('peers in rt: %d', rtp.length);
            if (rtp.length === 0) {
                const errMsg = 'Failed to lookup key! No peers from routing table!';
                dht._log.error(errMsg);
                if (vals.length === 0) throw errcode(new Error(errMsg), 'ERR_NO_PEERS_IN_ROUTING_TABLE');
                return vals;
            }
            const valsLength = vals.length;
            /**
       * @param {number} pathIndex
       * @param {number} numPaths
       */ function createQuery(pathIndex, numPaths) {
                // This function body runs once per disjoint path
                const pathSize = utils.pathSize(nvals - valsLength, numPaths);
                let queryResults = 0;
                /**
         * Here we return the query function to use on this particular disjoint path
         *
         * @param {PeerId} peer
         */ async function disjointPathQuery(peer) {
                    let rec, peers, lookupErr;
                    try {
                        const results = await dht._getValueOrPeers(peer, key);
                        rec = results.record;
                        peers = results.peers;
                    } catch (err) {
                        // If we have an invalid record we just want to continue and fetch a new one.
                        if (err.code !== 'ERR_INVALID_RECORD') throw err;
                        lookupErr = err;
                    }
                    /** @type {import('../query').QueryResult} */ const res = {
                        closerPeers: peers
                    };
                    if (rec && rec.value) {
                        vals.push({
                            val: rec.value,
                            from: peer
                        });
                        queryResults++;
                    } else if (lookupErr) {
                        vals.push({
                            err: lookupErr,
                            from: peer
                        });
                        queryResults++;
                    }
                    // enough is enough
                    if (queryResults >= pathSize) res.pathComplete = true;
                    return res;
                }
                return disjointPathQuery;
            }
            // we have peers, lets send the actual query to them
            const query = new Query(dht, key, createQuery);
            try {
                await pTimeout(query.run(rtp), options.timeout);
            } catch (err) {
                if (vals.length === 0) throw err;
            } finally{
                query.stop();
            }
            return vals;
        }
    };
};

},{"err-code":"eQvyh","p-timeout":"5asWS","uint8arrays/equals":"fjLeN","uint8arrays/to-string":"g3mCQ","libp2p-record":"4hkIr","../constants":"b8cEs","../query":"hByXb","../utils":"16BUU"}],"hByXb":[function(require,module,exports) {
'use strict';
const { base58btc  } = require('multiformats/bases/base58');
const utils = require('../utils');
const Run = require('./run');
/**
 * @typedef {import('peer-id')} PeerId
 * @typedef {{from: PeerId, val: Uint8Array}} DHTQueryValue
 * @typedef {{from: PeerId, err: Error}} DHTQueryError
 * @typedef {DHTQueryValue | DHTQueryError} DHTQueryResult
 * @typedef {import('../').PeerData} PeerData
 *
 * @typedef {{ pathComplete?: boolean, queryComplete?: boolean, closerPeers?: PeerData[], peer?: PeerData, success?: boolean }} QueryResult
 */ /**
 * User-supplied function to set up an individual disjoint path. Per-path
 * query state should be held in this function's closure.
 *
 * Accepts the numeric index from zero to numPaths - 1 and returns a function
 * to call on each peer in the query.
 *
 * @typedef {(pathIndex: number, numPaths: number) => QueryFunc } MakeQueryFunc
 */ /**
 * Query function
 *
 * @typedef {(peer: PeerId) => Promise<QueryResult> } QueryFunc
 */ /**
 * Divide peers up into disjoint paths (subqueries). Any peer can only be used once over all paths.
 * Within each path, query peers from closest to farthest away.
 */ class Query {
    /**
   * Create a new query. The makePath function is called once per disjoint path, so that per-path
   * variables can be created in that scope. makePath then returns the actual query function (queryFunc) to
   * use when on that path.
   *
   * @param {import('../index')} dht - DHT instance
   * @param {Uint8Array} key
   * @param {MakeQueryFunc} makePath - Called to set up each disjoint path. Must return the query function.
   */ constructor(dht, key, makePath){
        this.dht = dht;
        this.key = key;
        this.makePath = makePath;
        this._log = utils.logger(this.dht.peerId, 'query:' + base58btc.baseEncode(key));
        this.running = false;
        this._onStart = this._onStart.bind(this);
        this._onComplete = this._onComplete.bind(this);
    }
    /**
   * Run this query, start with the given list of peers first.
   *
   * @param {PeerId[]} peers
   */ async run(peers) {
        if (!this.dht._queryManager.running) {
            this._log.error('Attempt to run query after shutdown');
            return {
                finalSet: new Set(),
                paths: []
            };
        }
        if (peers.length === 0) {
            this._log.error('Running query with no peers');
            return {
                finalSet: new Set(),
                paths: []
            };
        }
        this._run = new Run(this);
        this._log(`query running with K=${this.dht.kBucketSize}, A=${this.dht.concurrency}, D=${Math.min(this.dht.disjointPaths, peers.length)}`);
        this._run.once('start', this._onStart);
        this._run.once('complete', this._onComplete);
        return this._run.execute(peers);
    }
    /**
   * Called when the run starts.
   */ _onStart() {
        this.running = true;
        this._startTime = Date.now();
        this._log('query:start');
        // Register this query so we can stop it if the DHT stops
        this.dht._queryManager.queryStarted(this);
    }
    /**
   * Called when the run completes (even if there's an error).
   */ _onComplete() {
        // Ensure worker queues for all paths are stopped at the end of the query
        this.stop();
    }
    /**
   * Stop the query.
   */ stop() {
        this._log(`query:done in ${Date.now() - (this._startTime || 0)}ms`);
        if (this._run) this._log(`${this._run.errors.length} of ${this._run.peersSeen.size} peers errored (${this._run.errors.length / this._run.peersSeen.size * 100}% fail rate)`);
        if (!this.running) return;
        this.running = false;
        if (this._run) {
            this._run.removeListener('start', this._onStart);
            this._run.removeListener('complete', this._onComplete);
            this._run.stop();
        }
        this.dht._queryManager.queryCompleted(this);
    }
}
module.exports = Query;

},{"multiformats/bases/base58":"6Rnqi","../utils":"16BUU","./run":"etGYk"}],"etGYk":[function(require,module,exports) {
'use strict';
const PeerDistanceList = require('../peer-list/peer-distance-list');
const EventEmitter = require('events');
const Path = require('./path');
const WorkerQueue = require('./worker-queue');
const utils = require('../utils');
/**
 * @typedef {import('peer-id')} PeerId
 */ /**
 * Manages a single run of the query.
 */ class Run extends EventEmitter {
    /**
   * Creates a Run.
   *
   * @param {import('./index')} query
   */ constructor(query){
        super();
        this.query = query;
        this.running = false;
        /** @type {WorkerQueue[]} */ this.workers = [];
        // The peers that have been queried (including error responses)
        this.peersSeen = new Set();
        // The errors received when querying peers
        /** @type {Error[]} */ this.errors = [];
        // The closest K peers that have been queried successfully
        // (this member is initialized when the worker queues start)
        /** @type {PeerDistanceList | null} */ this.peersQueried = null;
    }
    /**
   * Stop all the workers
   */ stop() {
        if (!this.running) return;
        this.running = false;
        for (const worker of this.workers)worker.stop();
    }
    /**
   * Execute the run with the given initial set of peers.
   *
   * @param {PeerId[]} peers
   */ async execute(peers) {
        /** @type {import('./path')[]} */ const paths = [] // array of states per disjoint path
        ;
        // Create disjoint paths
        const numPaths = Math.min(this.query.dht.disjointPaths, peers.length);
        for(let i = 0; i < numPaths; i++)paths.push(new Path(this, this.query.makePath(i, numPaths)));
        // Assign peers to paths round-robin style
        peers.forEach((peer, i)=>{
            paths[i % numPaths].addInitialPeer(peer);
        });
        // Execute the query along each disjoint path
        await this.executePaths(paths);
        const res = {
            // The closest K peers we were able to query successfully
            finalSet: new Set(this.peersQueried && this.peersQueried.peers),
            /** @type {import('./index').QueryResult[]} */ paths: []
        };
        // Collect the results from each completed path
        for (const path of paths)if (path.res && (path.res.pathComplete || path.res.queryComplete)) {
            path.res.success = true;
            res.paths.push(path.res);
        }
        return res;
    }
    /**
   * Execute all paths through the DHT.
   *
   * @param {Array<Path>} paths
   * @returns {Promise<void>}
   */ async executePaths(paths) {
        this.running = true;
        this.emit('start');
        try {
            await Promise.all(paths.map((path)=>path.execute()
            ));
        } finally{
            // Ensure all workers are stopped
            this.stop();
            // Completed the Run
            this.emit('complete');
        }
        // If all queries errored out, something is seriously wrong, so callback
        // with an error
        if (this.errors.length === this.peersSeen.size) throw this.errors[0];
    }
    /**
   * Initialize the list of queried peers, then start a worker queue for the
   * given path.
   *
   * @param {Path} path
   * @returns {Promise<void>}
   */ async workerQueue(path) {
        await this.init();
        await this.startWorker(path);
    }
    /**
   * Create and start a worker queue for a particular path.
   *
   * @param {Path} path
   * @returns {Promise<void>}
   */ async startWorker(path1) {
        const worker = new WorkerQueue(this.query.dht, this, path1, this.query._log);
        this.workers.push(worker);
        await worker.execute();
    }
    /**
   * Initialize the list of closest peers we've queried - this is shared by all
   * paths in the run.
   *
   * @returns {Promise<void>}
   */ async init() {
        if (this.peersQueried) return;
        // We only want to initialize the PeerDistanceList once for the run
        if (this.peersQueriedPromise) {
            await this.peersQueriedPromise;
            return;
        }
        // This promise is temporarily stored so that others may await its completion
        this.peersQueriedPromise = (async ()=>{
            const dhtKey = await utils.convertBuffer(this.query.key);
            this.peersQueried = new PeerDistanceList(dhtKey, this.query.dht.kBucketSize);
        })();
        // After PeerDistanceList is initialized, clean up
        await this.peersQueriedPromise;
        delete this.peersQueriedPromise;
    }
    /**
   * If we've queried K peers, and the remaining peers in the given `worker`'s queue
   * are all further from the key than the peers we've already queried, then we should
   * stop querying on that `worker`.
   *
   * @param {WorkerQueue} worker
   * @returns {Promise<boolean>}
   */ async continueQuerying(worker) {
        // If we haven't queried K peers yet, keep going
        if (this.peersQueried && this.peersQueried.length < this.peersQueried.capacity) return true;
        // Get all the peers that are currently being queried.
        // Note that this function gets called right after a peer has been popped
        // off the head of the closest peers queue so it will include that peer.
        const running = Array.from(worker.queuedPeerIds);
        // Check if any of the peers that are currently being queried are closer
        // to the key than the peers we've already queried
        const someCloser = this.peersQueried && await this.peersQueried.anyCloser(running);
        // Some are closer, the worker should keep going
        if (someCloser) return true;
        // None are closer, the worker can stop
        return false;
    }
}
module.exports = Run;

},{"../peer-list/peer-distance-list":"g5j4G","events":"bHM3D","./path":"42wap","./worker-queue":"5kzIB","../utils":"16BUU"}],"g5j4G":[function(require,module,exports) {
'use strict';
const utils = require('../utils');
const pMap = require('p-map');
const { equals: uint8ArrayEquals  } = require('uint8arrays/equals');
const { compare: uint8ArrayCompare  } = require('uint8arrays/compare');
const { xor: uint8ArrayXor  } = require('uint8arrays/xor');
/**
 * @typedef {import('peer-id')} PeerId
 * @typedef {import('../').PeerData} PeerData
 */ /**
 * Maintains a list of peerIds sorted by distance from a DHT key.
 */ class PeerDistanceList {
    /**
   * Creates a new PeerDistanceList.
   *
   * @param {Uint8Array} originDhtKey - the DHT key from which distance is calculated
   * @param {number} capacity - the maximum size of the list
   */ constructor(originDhtKey, capacity){
        this.originDhtKey = originDhtKey;
        this.capacity = capacity;
        /** @type {{ peerId: PeerId, distance: Uint8Array }[]} */ this.peerDistances = [];
    }
    /**
   * The length of the list
   */ get length() {
        return this.peerDistances.length;
    }
    /**
   * The peerIds in the list, in order of distance from the origin key
   */ get peers() {
        return this.peerDistances.map((pd)=>pd.peerId
        );
    }
    /**
   * Add a peerId to the list.
   *
   * @param {PeerId} peerId
   */ async add(peerId1) {
        if (this.peerDistances.find((pd)=>uint8ArrayEquals(pd.peerId.id, peerId1.id)
        )) return;
        const dhtKey = await utils.convertPeerId(peerId1);
        const el = {
            peerId: peerId1,
            distance: uint8ArrayXor(this.originDhtKey, dhtKey)
        };
        this.peerDistances.push(el);
        this.peerDistances.sort((a, b)=>uint8ArrayCompare(a.distance, b.distance)
        );
        this.peerDistances = this.peerDistances.slice(0, this.capacity);
    }
    /**
   * Indicates whether any of the peerIds passed as a parameter are closer
   * to the origin key than the furthest peerId in the PeerDistanceList.
   *
   * @param {PeerId[]} peerIds
   */ async anyCloser(peerIds) {
        if (!peerIds.length) return false;
        if (!this.length) return true;
        const dhtKeys = await pMap(peerIds, (peerId)=>utils.convertPeerId(peerId)
        );
        const furthestDistance = this.peerDistances[this.peerDistances.length - 1].distance;
        for (const dhtKey of dhtKeys){
            const keyDistance = uint8ArrayXor(this.originDhtKey, dhtKey);
            if (uint8ArrayCompare(keyDistance, furthestDistance) < 0) return true;
        }
        return false;
    }
}
module.exports = PeerDistanceList;

},{"../utils":"16BUU","p-map":"75sAO","uint8arrays/equals":"fjLeN","uint8arrays/compare":"m8amP","uint8arrays/xor":"lpkFK"}],"42wap":[function(require,module,exports) {
'use strict';
const PeerQueue = require('../peer-list/peer-queue');
const utils = require('../utils');
// TODO: Temporary until parallel dial in Switch have a proper
// timeout. Requires async/await refactor of transports and
// dial abort logic. This gives us 30s to complete the `queryFunc`.
// This should help reduce the high end call times of queries
const QUERY_FUNC_TIMEOUT = 30000;
/**
 * @typedef {import('peer-id')} PeerId
 */ /**
 * Manages a single Path through the DHT.
 */ class Path {
    /**
   * Creates a Path.
   *
   * @param {import('./run')} run
   * @param {import('./index').QueryFunc} queryFunc
   */ constructor(run, queryFunc){
        this.run = run;
        this.queryFunc = utils.withTimeout(queryFunc, QUERY_FUNC_TIMEOUT);
        if (!this.queryFunc) throw new Error('Path requires a `queryFn` to be specified');
        if (typeof this.queryFunc !== 'function') throw new Error('Path expected `queryFn` to be a function. Got ' + typeof this.queryFunc);
        /** @type {PeerId[]} */ this.initialPeers = [];
        /** @type {PeerQueue | null} */ this.peersToQuery = null;
        /** @type {import('./index').QueryResult | null} */ this.res = null;
    }
    /**
   * Add a peer to the set of peers that are used to intialize the path.
   *
   * @param {PeerId} peer
   */ addInitialPeer(peer1) {
        this.initialPeers.push(peer1);
    }
    /**
   * Execute the path
   */ async execute() {
        // Create a queue of peers ordered by distance from the key
        const queue = await PeerQueue.fromKey(this.run.query.key);
        // Add initial peers to the queue
        this.peersToQuery = queue;
        await Promise.all(this.initialPeers.map((peer)=>this.addPeerToQuery(peer)
        ));
        await this.run.workerQueue(this);
    }
    /**
   * Add a peer to the peers to be queried.
   *
   * @param {PeerId} peer
   */ async addPeerToQuery(peer) {
        // Don't add self
        if (this.run.query.dht._isSelf(peer)) return;
        // The paths must be disjoint, meaning that no two paths in the Query may
        // traverse the same peer
        if (this.run.peersSeen.has(peer.toB58String())) return;
        if (this.peersToQuery) await this.peersToQuery.enqueue(peer);
    }
}
module.exports = Path;

},{"../peer-list/peer-queue":"b6oN3","../utils":"16BUU"}],"b6oN3":[function(require,module,exports) {
'use strict';
// @ts-ignore
const Heap = require('heap');
const { xor: uint8ArrayXor  } = require('uint8arrays/xor');
const debug = require('debug');
const utils = require('../utils');
const log = debug('libp2p:dht:peer-queue');
/**
 * @typedef {import('peer-id')} PeerId
 */ /**
 * PeerQueue is a heap that sorts its entries (PeerIds) by their
 * xor distance to the inital provided key.
 */ class PeerQueue {
    /**
   * Create from a given peer id.
   *
   * @param {PeerId} id
   * @returns {Promise<PeerQueue>}
   */ static async fromPeerId(id) {
        const key = await utils.convertPeerId(id);
        return new PeerQueue(key);
    }
    /**
   * Create from a given Uint8Array.
   *
   * @param {Uint8Array} keyBuffer
   * @returns {Promise<PeerQueue>}
   */ static async fromKey(keyBuffer) {
        const key = await utils.convertBuffer(keyBuffer);
        return new PeerQueue(key);
    }
    /**
   * Create a new PeerQueue.
   *
   * @param {Uint8Array} from - The sha2-256 encoded peer id
   */ constructor(from){
        log('create: %b', from);
        this.from = from;
        this.heap = new Heap(utils.xorCompare);
    }
    /**
   * Add a new PeerId to the queue.
   *
   * @param {PeerId} id
   */ async enqueue(id1) {
        log('enqueue %s', id1.toB58String());
        const key = await utils.convertPeerId(id1);
        const el = {
            id: id1,
            distance: uint8ArrayXor(this.from, key)
        };
        this.heap.push(el);
    }
    /**
   * Returns the closest peer to the `from` peer.
   *
   * @returns {PeerId}
   */ dequeue() {
        const el = this.heap.pop();
        log('dequeue %s', el.id.toB58String());
        return el.id;
    }
    get length() {
        return this.heap.size();
    }
}
module.exports = PeerQueue;

},{"heap":"bJI8x","uint8arrays/xor":"lpkFK","debug":"lWlU4","../utils":"16BUU"}],"bJI8x":[function(require,module,exports) {
module.exports = require('./lib/heap');

},{"./lib/heap":"89RSo"}],"89RSo":[function(require,module,exports) {
// Generated by CoffeeScript 1.8.0
(function() {
    var Heap1, defaultCmp, floor, heapify, heappop, heappush, heappushpop, heapreplace, insort, min, nlargest, nsmallest, updateItem, _siftdown, _siftup;
    floor = Math.floor, min = Math.min;
    /*
  Default comparison function to be used
   */ defaultCmp = function(x, y) {
        if (x < y) return -1;
        if (x > y) return 1;
        return 0;
    };
    /*
  Insert item x in list a, and keep it sorted assuming a is sorted.
  
  If x is already in a, insert it to the right of the rightmost x.
  
  Optional args lo (default 0) and hi (default a.length) bound the slice
  of a to be searched.
   */ insort = function(a, x, lo, hi, cmp) {
        var mid;
        if (lo == null) lo = 0;
        if (cmp == null) cmp = defaultCmp;
        if (lo < 0) throw new Error('lo must be non-negative');
        if (hi == null) hi = a.length;
        while(lo < hi){
            mid = floor((lo + hi) / 2);
            if (cmp(x, a[mid]) < 0) hi = mid;
            else lo = mid + 1;
        }
        return [].splice.apply(a, [
            lo,
            lo - lo
        ].concat(x)), x;
    };
    /*
  Push item onto heap, maintaining the heap invariant.
   */ heappush = function(array, item, cmp) {
        if (cmp == null) cmp = defaultCmp;
        array.push(item);
        return _siftdown(array, 0, array.length - 1, cmp);
    };
    /*
  Pop the smallest item off the heap, maintaining the heap invariant.
   */ heappop = function(array, cmp) {
        var lastelt, returnitem;
        if (cmp == null) cmp = defaultCmp;
        lastelt = array.pop();
        if (array.length) {
            returnitem = array[0];
            array[0] = lastelt;
            _siftup(array, 0, cmp);
        } else returnitem = lastelt;
        return returnitem;
    };
    /*
  Pop and return the current smallest value, and add the new item.
  
  This is more efficient than heappop() followed by heappush(), and can be
  more appropriate when using a fixed size heap. Note that the value
  returned may be larger than item! That constrains reasonable use of
  this routine unless written as part of a conditional replacement:
      if item > array[0]
        item = heapreplace(array, item)
   */ heapreplace = function(array, item, cmp) {
        var returnitem;
        if (cmp == null) cmp = defaultCmp;
        returnitem = array[0];
        array[0] = item;
        _siftup(array, 0, cmp);
        return returnitem;
    };
    /*
  Fast version of a heappush followed by a heappop.
   */ heappushpop = function(array, item, cmp) {
        var _ref;
        if (cmp == null) cmp = defaultCmp;
        if (array.length && cmp(array[0], item) < 0) {
            _ref = [
                array[0],
                item
            ], item = _ref[0], array[0] = _ref[1];
            _siftup(array, 0, cmp);
        }
        return item;
    };
    /*
  Transform list into a heap, in-place, in O(array.length) time.
   */ heapify = function(array, cmp) {
        var i, _i, _j1, _len, _ref2, _ref1, _results, _results1;
        if (cmp == null) cmp = defaultCmp;
        _ref1 = (function() {
            _results1 = [];
            for(var _j = 0, _ref = floor(array.length / 2); 0 <= _ref ? _j < _ref : _j > _ref; 0 <= _ref ? _j++ : _j--)_results1.push(_j);
            return _results1;
        }).apply(this).reverse();
        _results = [];
        for(_i = 0, _len = _ref1.length; _i < _len; _i++){
            i = _ref1[_i];
            _results.push(_siftup(array, i, cmp));
        }
        return _results;
    };
    /*
  Update the position of the given item in the heap.
  This function should be called every time the item is being modified.
   */ updateItem = function(array, item, cmp) {
        var pos;
        if (cmp == null) cmp = defaultCmp;
        pos = array.indexOf(item);
        if (pos === -1) return;
        _siftdown(array, 0, pos, cmp);
        return _siftup(array, pos, cmp);
    };
    /*
  Find the n largest elements in a dataset.
   */ nlargest = function(array, n, cmp) {
        var elem, result, _i, _len, _ref;
        if (cmp == null) cmp = defaultCmp;
        result = array.slice(0, n);
        if (!result.length) return result;
        heapify(result, cmp);
        _ref = array.slice(n);
        for(_i = 0, _len = _ref.length; _i < _len; _i++){
            elem = _ref[_i];
            heappushpop(result, elem, cmp);
        }
        return result.sort(cmp).reverse();
    };
    /*
  Find the n smallest elements in a dataset.
   */ nsmallest = function(array, n, cmp) {
        var elem, i, los, result, _i, _j, _len, _ref, _ref1, _results;
        if (cmp == null) cmp = defaultCmp;
        if (n * 10 <= array.length) {
            result = array.slice(0, n).sort(cmp);
            if (!result.length) return result;
            los = result[result.length - 1];
            _ref = array.slice(n);
            for(_i = 0, _len = _ref.length; _i < _len; _i++){
                elem = _ref[_i];
                if (cmp(elem, los) < 0) {
                    insort(result, elem, 0, null, cmp);
                    result.pop();
                    los = result[result.length - 1];
                }
            }
            return result;
        }
        heapify(array, cmp);
        _results = [];
        for(i = _j = 0, _ref1 = min(n, array.length); 0 <= _ref1 ? _j < _ref1 : _j > _ref1; i = 0 <= _ref1 ? ++_j : --_j)_results.push(heappop(array, cmp));
        return _results;
    };
    _siftdown = function(array, startpos, pos, cmp) {
        var newitem, parent, parentpos;
        if (cmp == null) cmp = defaultCmp;
        newitem = array[pos];
        while(pos > startpos){
            parentpos = pos - 1 >> 1;
            parent = array[parentpos];
            if (cmp(newitem, parent) < 0) {
                array[pos] = parent;
                pos = parentpos;
                continue;
            }
            break;
        }
        return array[pos] = newitem;
    };
    _siftup = function(array, pos, cmp) {
        var childpos, endpos, newitem, rightpos, startpos;
        if (cmp == null) cmp = defaultCmp;
        endpos = array.length;
        startpos = pos;
        newitem = array[pos];
        childpos = 2 * pos + 1;
        while(childpos < endpos){
            rightpos = childpos + 1;
            if (rightpos < endpos && !(cmp(array[childpos], array[rightpos]) < 0)) childpos = rightpos;
            array[pos] = array[childpos];
            pos = childpos;
            childpos = 2 * pos + 1;
        }
        array[pos] = newitem;
        return _siftdown(array, startpos, pos, cmp);
    };
    Heap1 = (function() {
        Heap.push = heappush;
        Heap.pop = heappop;
        Heap.replace = heapreplace;
        Heap.pushpop = heappushpop;
        Heap.heapify = heapify;
        Heap.updateItem = updateItem;
        Heap.nlargest = nlargest;
        Heap.nsmallest = nsmallest;
        function Heap(cmp) {
            this.cmp = cmp != null ? cmp : defaultCmp;
            this.nodes = [];
        }
        Heap.prototype.push = function(x) {
            return heappush(this.nodes, x, this.cmp);
        };
        Heap.prototype.pop = function() {
            return heappop(this.nodes, this.cmp);
        };
        Heap.prototype.peek = function() {
            return this.nodes[0];
        };
        Heap.prototype.contains = function(x) {
            return this.nodes.indexOf(x) !== -1;
        };
        Heap.prototype.replace = function(x) {
            return heapreplace(this.nodes, x, this.cmp);
        };
        Heap.prototype.pushpop = function(x) {
            return heappushpop(this.nodes, x, this.cmp);
        };
        Heap.prototype.heapify = function() {
            return heapify(this.nodes, this.cmp);
        };
        Heap.prototype.updateItem = function(x) {
            return updateItem(this.nodes, x, this.cmp);
        };
        Heap.prototype.clear = function() {
            return this.nodes = [];
        };
        Heap.prototype.empty = function() {
            return this.nodes.length === 0;
        };
        Heap.prototype.size = function() {
            return this.nodes.length;
        };
        Heap.prototype.clone = function() {
            var heap;
            heap = new Heap();
            heap.nodes = this.nodes.slice(0);
            return heap;
        };
        Heap.prototype.toArray = function() {
            return this.nodes.slice(0);
        };
        Heap.prototype.insert = Heap.prototype.push;
        Heap.prototype.top = Heap.prototype.peek;
        Heap.prototype.front = Heap.prototype.peek;
        Heap.prototype.has = Heap.prototype.contains;
        Heap.prototype.copy = Heap.prototype.clone;
        return Heap;
    })();
    (function(root, factory) {
        if (typeof define === 'function' && define.amd) return define([], factory);
        else if (typeof exports === 'object') return module.exports = factory();
        else return root.Heap = factory();
    })(this, function() {
        return Heap1;
    });
}).call(this);

},{}],"5kzIB":[function(require,module,exports) {
'use strict';
const { default: Queue  } = require('p-queue');
/**
 * @typedef {import('peer-id')} PeerId
 */ class WorkerQueue {
    /**
   * Creates a new WorkerQueue.
   *
   * @param {import('../index')} dht
   * @param {import('./run')} run
   * @param {import('./path')} path
   * @param {Function & {error: Function}} log
   */ constructor(dht, run, path, log){
        this.dht = dht;
        this.run = run;
        this.path = path;
        this.log = log;
        this.concurrency = this.dht.concurrency;
        this.queue = this.setupQueue();
        // a container for resolve/reject functions that will be populated
        // when execute() is called
        /** @type {{ resolve: (result?: any) => void, reject: (err: Error) => void} | null} */ this.execution = null;
        /** @type {Set<PeerId>} */ this.queuedPeerIds = new Set();
    }
    /**
   * Create the underlying async queue.
   *
   * @returns {Queue}
   */ setupQueue() {
        const q = new Queue({
            concurrency: this.concurrency
        });
        // When all peers in the queue have been processed, stop the worker
        q.on('idle', ()=>{
            if (this.path.peersToQuery && !this.path.peersToQuery.length) {
                this.log('queue:drain');
                this.stop();
            }
        });
        // When a space opens up in the queue, add some more peers
        q.on('next', ()=>{
            if (!this.running) return;
            if (q.pending < this.concurrency) this.fill();
        });
        return q;
    }
    /**
   * Stop the worker, optionally providing an error to pass to the worker's
   * callback.
   *
   * @param {Error} [err]
   */ stop(err1) {
        if (!this.running) return;
        this.running = false;
        this.queue.clear();
        this.log('worker:stop, %d workers still running', this.run.workers.filter((w)=>w.running
        ).length);
        if (this.execution) {
            if (err1) this.execution.reject(err1);
            else this.execution.resolve();
        }
    }
    /**
   * Use the queue from async to keep `concurrency` amount items running
   * per path.
   *
   * @returns {Promise<void>}
   */ async execute() {
        this.running = true;
        // store the promise resolution functions to be resolved at end of queue
        this.execution = null;
        const execPromise = new Promise((resolve, reject)=>{
            this.execution = {
                resolve,
                reject
            };
        });
        // start queue
        this.fill();
        // await completion
        await execPromise;
    }
    /**
   * Add peers to the worker queue until there are enough to satisfy the
   * worker queue concurrency.
   * Note that we don't want to take any more than those required to satisfy
   * concurrency from the peers-to-query queue, because we always want to
   * query the closest peers to the key first, and new peers are continuously
   * being added to the peers-to-query queue.
   */ fill() {
        if (!this.path.peersToQuery) return;
        // Note:
        // - queue.pending: number of items that are currently running
        // - queue.size: the number of items that are waiting to be run
        while(this.queue.pending + this.queue.size < this.concurrency && this.path.peersToQuery.length > 0){
            const peer = this.path.peersToQuery.dequeue();
            // store the peer id so we can potentially abort early
            this.queuedPeerIds.add(peer);
            this.queue.add(()=>{
                return this.processNext(peer).catch((err)=>{
                    this.log.error('queue', err);
                    this.stop(err);
                }).finally(()=>{
                    this.queuedPeerIds.delete(peer);
                });
            });
        }
    }
    /**
   * Process the next peer in the queue
   *
   * @param {PeerId} peer
   */ async processNext(peer) {
        if (!this.running) return;
        // The paths must be disjoint, meaning that no two paths in the Query may
        // traverse the same peer
        if (this.run.peersSeen.has(peer.toB58String())) return;
        // Check if we've queried enough peers already
        let continueQuerying, continueQueryingError;
        try {
            continueQuerying = await this.run.continueQuerying(this);
        } catch (err) {
            continueQueryingError = err;
        }
        // Abort and ignore any error if we're no longer running
        if (!this.running) return;
        if (continueQueryingError) throw continueQueryingError;
        // No peer we're querying is closer, stop the queue
        // This will cause queries that may potentially result in
        // closer nodes to be ended, but it reduces overall query time
        if (!continueQuerying) {
            this.stop();
            return;
        }
        // Check if another path has queried this peer in the mean time
        if (this.run.peersSeen.has(peer.toB58String())) return;
        this.run.peersSeen.add(peer.toB58String());
        // Execute the query on the next peer
        this.log('queue:work');
        let state, execError;
        try {
            state = await this.execQuery(peer);
        } catch (err2) {
            execError = err2;
        }
        // Abort and ignore any error if we're no longer running
        if (!this.running) return;
        this.log('queue:work:done', execError, state);
        if (execError) throw execError;
        // If query is complete, stop all workers.
        // Note: run.stop() calls stop() on all the workers, which kills the
        // queue and resolves execution
        if (state && state.queryComplete) {
            this.log('query:complete');
            this.run.stop();
            return;
        }
        // If path is complete, just stop this worker.
        // Note: this.stop() kills the queue and resolves execution
        if (state && state.pathComplete) this.stop();
    }
    /**
   * Execute a query on the next peer.
   *
   * @param {PeerId} peer
   */ async execQuery(peer1) {
        let res, queryError;
        try {
            res = await this.path.queryFunc(peer1);
        } catch (err) {
            queryError = err;
        }
        // Abort and ignore any error if we're no longer running
        if (!this.running) return;
        if (queryError) {
            this.run.errors.push(queryError);
            return;
        }
        // Add the peer to the closest peers we have successfully queried
        this.run.peersQueried && await this.run.peersQueried.add(peer1);
        if (!res) return;
        // If the query indicates that this path or the whole query is complete
        // set the path result and bail out
        if (res.pathComplete || res.queryComplete) {
            this.path.res = res;
            return {
                pathComplete: res.pathComplete,
                queryComplete: res.queryComplete
            };
        }
        // If there are closer peers to query, add them to the queue
        if (res.closerPeers && res.closerPeers.length > 0) {
            /**
       * @param {import('../').PeerData} closer
       */ const queryCloser = async (closer)=>{
                // don't add ourselves
                if (this.dht._isSelf(closer.id)) return;
                this.dht._peerDiscovered(closer.id, closer.multiaddrs);
                await this.path.addPeerToQuery(closer.id);
            };
            await Promise.all(res.closerPeers.map(queryCloser));
        }
    }
}
module.exports = WorkerQueue;

},{"p-queue":"ccCVf"}],"lbaJI":[function(require,module,exports) {
'use strict';
const errcode = require('err-code');
const pTimeout = require('p-timeout');
const c = require('../constants');
const LimitedPeerList = require('../peer-list/limited-peer-list');
const Message = require('../message');
const Query = require('../query');
const utils = require('../utils');
/**
 * @typedef {import('multiformats/cid').CID} CID
 * @typedef {import('peer-id')} PeerId
 * @typedef {import('multiaddr').Multiaddr} Multiaddr
 */ /**
 * @param {import('../')} dht
 */ module.exports = (dht)=>{
    /**
   * Check for providers from a single node.
   *
   * @param {PeerId} peer
   * @param {CID} key
   *
   * @private
   */ const findProvidersSingle = async (peer, key)=>{
        const msg = new Message(Message.TYPES.GET_PROVIDERS, key.bytes, 0);
        return dht.network.sendRequest(peer, msg);
    };
    return {
        /**
     * Announce to the network that we can provide the value for a given key
     *
     * @param {CID} key
     */ async provide (key) {
            dht._log(`provide: ${key}`);
            /** @type {Error[]} */ const errors = [];
            // Add peer as provider
            await dht.providers.addProvider(key, dht.peerId);
            const multiaddrs = dht.libp2p ? dht.libp2p.multiaddrs : [];
            const msg = new Message(Message.TYPES.ADD_PROVIDER, key.bytes, 0);
            msg.providerPeers = [
                {
                    id: dht.peerId,
                    multiaddrs
                }
            ];
            /**
       * @param {PeerId} peer
       */ async function mapPeer(peer) {
                dht._log(`putProvider ${key} to ${peer.toB58String()}`);
                try {
                    await dht.network.sendMessage(peer, msg);
                } catch (err) {
                    errors.push(err);
                }
            }
            // Notify closest peers
            await utils.mapParallel(dht.getClosestPeers(key.bytes), mapPeer);
            if (errors.length) // TODO:
            // This should be infrequent. This means a peer we previously connected
            // to failed to exchange the provide message. If getClosestPeers was an
            // iterator, we could continue to pull until we announce to kBucketSize peers.
            throw errcode(new Error(`Failed to provide to ${errors.length} of ${dht.kBucketSize} peers`), 'ERR_SOME_PROVIDES_FAILED', {
                errors
            });
        },
        /**
     * Search the dht for up to `K` providers of the given CID.
     *
     * @param {CID} key
     * @param {Object} [options] - findProviders options
     * @param {number} [options.timeout=60000] - how long the query should maximally run, in milliseconds
     * @param {number} [options.maxNumProviders=5] - maximum number of providers to find
     * @returns {AsyncIterable<{ id: PeerId, multiaddrs: Multiaddr[] }>}
     */ async *findProviders (key, options = {
            timeout: 60000,
            maxNumProviders: 5
        }) {
            const providerTimeout = options.timeout || c.minute;
            const n = options.maxNumProviders || c.K;
            dht._log(`findProviders ${key}`);
            const out = new LimitedPeerList(n);
            const provs1 = await dht.providers.getProviders(key);
            provs1.forEach((id)=>{
                /** @type {{ id: PeerId, addresses: { multiaddr: Multiaddr }[] }} */ const peerData = dht.peerStore.get(id);
                if (peerData) out.push({
                    id: peerData.id,
                    multiaddrs: peerData.addresses.map((address)=>address.multiaddr
                    )
                });
                else out.push({
                    id,
                    multiaddrs: []
                });
            });
            // All done
            if (out.length >= n) {
                // yield values
                for (const pData of out.toArray())yield pData;
                return;
            }
            // need more, query the network
            /** @type {LimitedPeerList[]} */ const paths = [];
            /**
       *
       * @param {number} pathIndex
       * @param {number} numPaths
       */ function makePath(pathIndex, numPaths) {
                // This function body runs once per disjoint path
                const pathSize = utils.pathSize(n - out.length, numPaths);
                const pathProviders = new LimitedPeerList(pathSize);
                paths.push(pathProviders);
                /**
         * The query function to use on this particular disjoint path
         *
         * @param {PeerId} peer
         */ async function queryDisjointPath(peer) {
                    const msg = await findProvidersSingle(peer, key);
                    const provs = msg.providerPeers;
                    dht._log(`Found ${provs.length} provider entries for ${key}`);
                    provs.forEach((prov)=>{
                        pathProviders.push({
                            ...prov
                        });
                    });
                    // hooray we have all that we want
                    if (pathProviders.length >= pathSize) return {
                        pathComplete: true
                    };
                    // it looks like we want some more
                    return {
                        closerPeers: msg.closerPeers
                    };
                }
                return queryDisjointPath;
            }
            const query = new Query(dht, key.bytes, makePath);
            const peers = dht.routingTable.closestPeers(key.bytes, dht.kBucketSize);
            try {
                await pTimeout(query.run(peers), providerTimeout);
            } catch (err) {
                if (err.name !== pTimeout.TimeoutError.name) throw err;
            } finally{
                query.stop();
            }
            // combine peers from each path
            paths.forEach((path)=>{
                path.toArray().forEach((peer)=>{
                    out.push(peer);
                });
            });
            for (const pData of out.toArray())yield pData;
        }
    };
};

},{"err-code":"eQvyh","p-timeout":"5asWS","../constants":"b8cEs","../peer-list/limited-peer-list":"iqJKe","../message":"5TcLe","../query":"hByXb","../utils":"16BUU"}],"iqJKe":[function(require,module,exports) {
'use strict';
const PeerList = require('.');
/**
 * @typedef {import('../').PeerData} PeerData
 */ /**
 * Like PeerList but with a length restriction.
 */ class LimitedPeerList extends PeerList {
    /**
   * Create a new limited peer list.
   *
   * @param {number} limit
   */ constructor(limit){
        super();
        this.limit = limit;
    }
    /**
   * Add a PeerData if it fits in the list
   *
   * @param {PeerData} peerData
   */ push(peerData) {
        if (this.length < this.limit) return super.push(peerData);
        return false;
    }
}
module.exports = LimitedPeerList;

},{".":"lRjM0"}],"lRjM0":[function(require,module,exports) {
'use strict';
/**
 * @typedef {import('peer-id')} PeerId
 * @typedef {import('../').PeerData} PeerData
 */ /**
 * A list of unique peers.
 */ class PeerList {
    constructor(){
        /** @type {PeerData[]} */ this.list = [];
    }
    /**
   * Add a new peer. Returns `true` if it was a new one
   *
   * @param {PeerData} peerData
   */ push(peerData) {
        if (!this.has(peerData.id)) {
            this.list.push(peerData);
            return true;
        }
        return false;
    }
    /**
   * Check if this PeerData is already in here.
   *
   * @param {PeerId} peerId
   */ has(peerId) {
        const match = this.list.find((i)=>i.id.equals(peerId)
        );
        return Boolean(match);
    }
    /**
   * Get the list as an array.
   */ toArray() {
        return this.list.slice();
    }
    /**
   * Remove the last element
   */ pop() {
        return this.list.pop();
    }
    /**
   * The length of the list
   */ get length() {
        return this.list.length;
    }
}
module.exports = PeerList;

},{}],"liYRf":[function(require,module,exports) {
'use strict';
const errcode = require('err-code');
const pTimeout = require('p-timeout');
const PeerId = require('peer-id');
const crypto = require('libp2p-crypto');
const { toString: uint8ArrayToString  } = require('uint8arrays/to-string');
const c = require('../constants');
const Message = require('../message');
const Query = require('../query');
const utils = require('../utils');
/**
 * @typedef {import('multiaddr').Multiaddr} Multiaddr
 */ /**
 * @param {import('../index')} dht
 */ module.exports = (dht)=>{
    /**
   * Look if we are connected to a peer with the given id.
   * Returns its id and addresses, if found, otherwise `undefined`.
   *
   * @param {PeerId} peer
   */ const findPeerLocal = async (peer)=>{
        dht._log(`findPeerLocal ${peer.toB58String()}`);
        const p = await dht.routingTable.find(peer);
        /** @type {{ id: PeerId, addresses: { multiaddr: Multiaddr }[] }} */ const peerData = p && dht.peerStore.get(p);
        if (peerData) return {
            id: peerData.id,
            multiaddrs: peerData.addresses.map((address)=>address.multiaddr
            )
        };
    };
    /**
   * Get a value via rpc call for the given parameters.
   *
   * @param {PeerId} peer
   * @param {Uint8Array} key
   * @returns {Promise<Message>}
   * @private
   */ const getValueSingle = async (peer, key)=>{
        const msg = new Message(Message.TYPES.GET_VALUE, key, 0);
        return dht.network.sendRequest(peer, msg);
    };
    /**
   * Find close peers for a given peer
   *
   * @param {Uint8Array} key
   * @param {PeerId} peer
   * @returns {Promise<Array<{ id: PeerId, multiaddrs: Multiaddr[] }>>}
   * @private
   */ const closerPeersSingle = async (key, peer)=>{
        dht._log(`closerPeersSingle ${uint8ArrayToString(key, 'base32')} from ${peer.toB58String()}`);
        const msg = await dht.peerRouting._findPeerSingle(peer, new PeerId(key));
        return msg.closerPeers.filter((peerData)=>!dht._isSelf(peerData.id)
        ).map((peerData)=>{
            dht.peerStore.addressBook.add(peerData.id, peerData.multiaddrs);
            return peerData;
        });
    };
    /**
   * Get the public key directly from a node.
   *
   * @param {PeerId} peer
   */ const getPublicKeyFromNode = async (peer)=>{
        const pkKey = utils.keyForPublicKey(peer);
        const msg = await getValueSingle(peer, pkKey);
        if (!msg.record || !msg.record.value) throw errcode(new Error(`Node not responding with its public key: ${peer.toB58String()}`), 'ERR_INVALID_RECORD');
        const recPeer = await PeerId.createFromPubKey(msg.record.value);
        // compare hashes of the pub key
        if (!recPeer.equals(peer)) throw errcode(new Error('public key does not match id'), 'ERR_PUBLIC_KEY_DOES_NOT_MATCH_ID');
        return recPeer.pubKey;
    };
    return {
        /**
   * Ask peer `peer` if they know where the peer with id `target` is.
   *
   * @param {PeerId} peer
   * @param {PeerId} target
   * @returns {Promise<Message>}
   * @private
   */ async _findPeerSingle (peer, target) {
            dht._log('findPeerSingle %s', peer.toB58String());
            const msg = new Message(Message.TYPES.FIND_NODE, target.id, 0);
            return dht.network.sendRequest(peer, msg);
        },
        /**
     * Search for a peer with the given ID.
     *
     * @param {PeerId} id
     * @param {Object} [options] - findPeer options
     * @param {number} [options.timeout=60000] - how long the query should maximally run, in milliseconds
     * @returns {Promise<{ id: PeerId, multiaddrs: Multiaddr[] }>}
     */ async findPeer (id, options = {
            timeout: 60000
        }) {
            options.timeout = options.timeout || c.minute;
            dht._log('findPeer %s', id.toB58String());
            // Try to find locally
            const pi = await findPeerLocal(id);
            // already got it
            if (pi != null) {
                dht._log('found local');
                return pi;
            }
            const key = await utils.convertPeerId(id);
            const peers = dht.routingTable.closestPeers(key, dht.kBucketSize);
            if (peers.length === 0) throw errcode(new Error('Peer lookup failed'), 'ERR_LOOKUP_FAILED');
            // sanity check
            const match1 = peers.find((p)=>p.isEqual(id)
            );
            if (match1) {
                /** @type {{ id: PeerId, addresses: { multiaddr: Multiaddr }[] }} */ const peer = dht.peerStore.get(id);
                if (peer) {
                    dht._log('found in peerStore');
                    return {
                        id: peer.id,
                        multiaddrs: peer.addresses.map((address)=>address.multiaddr
                        )
                    };
                }
            }
            // query the network
            const query = new Query(dht, id.id, ()=>{
                /**
         * There is no distinction between the disjoint paths, so there are no per-path
         * variables in dht scope. Just return the actual query function.
         *
         * @param {PeerId} peer
         */ const queryFn = async (peer)=>{
                    const msg = await this._findPeerSingle(peer, id);
                    const match = msg.closerPeers.find((p)=>p.id.isEqual(id)
                    );
                    // found it
                    if (match) return {
                        peer: match,
                        queryComplete: true
                    };
                    return {
                        closerPeers: msg.closerPeers
                    };
                };
                return queryFn;
            });
            let result1;
            try {
                result1 = await pTimeout(query.run(peers), options.timeout);
            } finally{
                query.stop();
            }
            let success = false;
            result1.paths.forEach((result)=>{
                if (result.success && result.peer) {
                    success = true;
                    dht.peerStore.addressBook.add(result.peer.id, result.peer.multiaddrs);
                }
            });
            dht._log('findPeer %s: %s', id.toB58String(), success);
            if (!success) throw errcode(new Error('No peer found'), 'ERR_NOT_FOUND');
            /** @type {{ id: PeerId, addresses: { multiaddr: Multiaddr }[] }} */ const peerData = dht.peerStore.get(id);
            if (!peerData) throw errcode(new Error('No peer found in peer store'), 'ERR_NOT_FOUND');
            return {
                id: peerData.id,
                multiaddrs: peerData.addresses.map((address)=>address.multiaddr
                )
            };
        },
        /**
     * Kademlia 'node lookup' operation.
     *
     * @param {Uint8Array} key
     * @param {Object} [options]
     * @param {boolean} [options.shallow=false] - shallow query
     * @returns {AsyncIterable<PeerId>}
     */ async *getClosestPeers (key, options = {
            shallow: false
        }) {
            dht._log('getClosestPeers to %b', key);
            const id = await utils.convertBuffer(key);
            const tablePeers = dht.routingTable.closestPeers(id, dht.kBucketSize);
            const q = new Query(dht, key, ()=>{
                // There is no distinction between the disjoint paths,
                // so there are no per-path variables in dht scope.
                // Just return the actual query function.
                return async (peer)=>{
                    const closer = await closerPeersSingle(key, peer);
                    return {
                        closerPeers: closer,
                        pathComplete: options.shallow ? true : undefined
                    };
                };
            });
            const res = await q.run(tablePeers);
            if (!res || !res.finalSet) return [];
            const sorted = await utils.sortClosestPeers(Array.from(res.finalSet), id);
            for (const pId of sorted.slice(0, dht.kBucketSize))yield pId;
        },
        /**
     * Get the public key for the given peer id.
     *
     * @param {PeerId} peer
     */ async getPublicKey (peer) {
            dht._log('getPublicKey %s', peer.toB58String());
            // local check
            /** @type {{ id: PeerId, addresses: { multiaddr: Multiaddr }[] }} */ const peerData = dht.peerStore.get(peer);
            if (peerData && peerData.id.pubKey) {
                dht._log('getPublicKey: found local copy');
                return peerData.id.pubKey;
            }
            // try the node directly
            let pk;
            try {
                pk = await getPublicKeyFromNode(peer);
            } catch (err) {
                // try dht directly
                const pkKey = utils.keyForPublicKey(peer);
                const value = await dht.get(pkKey);
                pk = crypto.keys.unmarshalPublicKey(value);
            }
            const peerId = new PeerId(peer.id, undefined, pk);
            const addrs = (peerData && peerData.addresses || []).map((address)=>address.multiaddr
            );
            dht.peerStore.addressBook.add(peerId, addrs);
            dht.peerStore.keyBook.set(peerId, pk);
            return pk;
        }
    };
};

},{"err-code":"eQvyh","p-timeout":"5asWS","peer-id":"4VGWt","libp2p-crypto":"hsRcr","uint8arrays/to-string":"g3mCQ","../constants":"b8cEs","../message":"5TcLe","../query":"hByXb","../utils":"16BUU"}],"lKxfg":[function(require,module,exports) {
'use strict';
const cache = require('hashlru');
// @ts-ignore
const varint = require('varint');
const PeerId = require('peer-id');
const { Key  } = require('interface-datastore/key');
const { default: Queue  } = require('p-queue');
const c = require('./constants');
const utils = require('./utils');
/**
 * @typedef {import('multiformats/cid').CID} CID
 * @typedef {import('interface-datastore').Datastore} Datastore
 */ /**
 * This class manages known providers.
 * A provider is a peer that we know to have the content for a given CID.
 *
 * Every `cleanupInterval` providers are checked if they
 * are still valid, i.e. younger than the `provideValidity`.
 * If they are not, they are deleted.
 *
 * To ensure the list survives restarts of the daemon,
 * providers are stored in the datastore, but to ensure
 * access is fast there is an LRU cache in front of that.
 */ class Providers {
    /**
   * @param {Datastore} datastore
   * @param {PeerId} [self]
   * @param {number} [cacheSize=256]
   */ constructor(datastore, self, cacheSize){
        this.datastore = datastore;
        this._log = utils.logger(self, 'providers');
        /**
     * How often invalid records are cleaned. (in seconds)
     *
     * @type {number}
     */ this.cleanupInterval = c.PROVIDERS_CLEANUP_INTERVAL;
        /**
     * How long is a provider valid for. (in seconds)
     *
     * @type {number}
     */ this.provideValidity = c.PROVIDERS_VALIDITY;
        /**
     * LRU cache size
     *
     * @type {number}
     */ this.lruCacheSize = cacheSize || c.PROVIDERS_LRU_CACHE_SIZE;
        // @ts-ignore hashlru types are wrong
        this.providers = cache(this.lruCacheSize);
        this.syncQueue = new Queue({
            concurrency: 1
        });
    }
    /**
   * Start the provider cleanup service
   */ start() {
        if (this._started) return;
        this._started = true;
        this._cleaner = setInterval(()=>this._cleanup()
        , this.cleanupInterval);
    }
    /**
   * Release any resources.
   */ stop() {
        this._started = false;
        if (this._cleaner) {
            clearInterval(this._cleaner);
            this._cleaner = null;
        }
    }
    /**
   * Check all providers if they are still valid, and if not delete them.
   *
   * @returns {Promise<void>}
   * @private
   */ _cleanup() {
        return this.syncQueue.add(async ()=>{
            this._log('start cleanup');
            const start = Date.now();
            let count = 0;
            let deleteCount = 0;
            const deleted = new Map();
            const batch = this.datastore.batch();
            // Get all provider entries from the datastore
            const query = this.datastore.query({
                prefix: c.PROVIDERS_KEY_PREFIX
            });
            for await (const entry of query)try {
                // Add a delete to the batch for each expired entry
                const { cid , peerId  } = parseProviderKey(entry.key);
                const time = readTime(entry.value);
                const now = Date.now();
                const delta = now - time;
                const expired = delta > this.provideValidity;
                this._log('comparing: %d - %d = %d > %d %s', now, time, delta, this.provideValidity, expired ? '(expired)' : '');
                if (expired) {
                    deleteCount++;
                    batch.delete(entry.key);
                    const peers = deleted.get(cid) || new Set();
                    peers.add(peerId);
                    deleted.set(cid, peers);
                }
                count++;
            } catch (err) {
                this._log.error(err.message);
            }
            this._log('deleting %d / %d entries', deleteCount, count);
            // Commit the deletes to the datastore
            if (deleted.size) await batch.commit();
            // Clear expired entries from the cache
            for (const [cid, peers] of deleted){
                const key = makeProviderKey(cid);
                const provs = this.providers.get(key);
                if (provs) {
                    for (const peerId of peers)provs.delete(peerId);
                    if (provs.size === 0) this.providers.remove(key);
                    else this.providers.set(key, provs);
                }
            }
            this._log('Cleanup successful (%dms)', Date.now() - start);
        });
    }
    /**
   * Get the currently known provider peer ids for a given CID.
   *
   * @param {CID} cid
   * @returns {Promise<Map<string, Date>>}
   *
   * @private
   */ async _getProvidersMap(cid3) {
        const cacheKey = makeProviderKey(cid3);
        let provs = this.providers.get(cacheKey);
        if (!provs) {
            provs = await loadProviders(this.datastore, cid3);
            this.providers.set(cacheKey, provs);
        }
        return provs;
    }
    /**
   * Add a new provider for the given CID.
   *
   * @param {CID} cid
   * @param {PeerId} provider
   * @returns {Promise<void>}
   */ async addProvider(cid1, provider) {
        return this.syncQueue.add(async ()=>{
            this._log('addProvider %s', cid1.toString());
            const provs = await this._getProvidersMap(cid1);
            this._log('loaded %s provs', provs.size);
            const now = new Date();
            provs.set(utils.encodeBase32(provider.id), now);
            const dsKey = makeProviderKey(cid1);
            this.providers.set(dsKey, provs);
            return writeProviderEntry(this.datastore, cid1, provider, now);
        });
    }
    /**
   * Get a list of providers for the given CID.
   *
   * @param {CID} cid
   * @returns {Promise<Array<PeerId>>}
   */ async getProviders(cid2) {
        return this.syncQueue.add(async ()=>{
            this._log('getProviders %s', cid2.toString());
            const provs = await this._getProvidersMap(cid2);
            return [
                ...provs.keys()
            ].map((base32PeerId)=>{
                return new PeerId(utils.decodeBase32(base32PeerId));
            });
        });
    }
}
/**
 * Encode the given key its matching datastore key.
 *
 * @param {CID|string} cid - cid or base32 encoded string
 * @returns {string}
 *
 * @private
 */ function makeProviderKey(cid) {
    cid = typeof cid === 'string' ? cid : utils.encodeBase32(cid.bytes);
    return c.PROVIDERS_KEY_PREFIX + cid;
}
/**
 * Write a provider into the given store.
 *
 * @param {Datastore} store
 * @param {CID} cid
 * @param {PeerId} peer
 * @param {Date} time
 */ async function writeProviderEntry(store, cid, peer, time) {
    const dsKey = [
        makeProviderKey(cid),
        '/',
        utils.encodeBase32(peer.id)
    ].join('');
    const key = new Key(dsKey);
    const buffer = Uint8Array.from(varint.encode(time.getTime()));
    return store.put(key, buffer);
}
/**
 * Parse the CID and provider peer id from the key
 *
 * @param {import('interface-datastore/key').Key} key
 */ function parseProviderKey(key) {
    const parts = key.toString().split('/');
    if (parts.length !== 4) throw new Error('incorrectly formatted provider entry key in datastore: ' + key);
    return {
        cid: parts[2],
        peerId: parts[3]
    };
}
/**
 * Load providers for the given CID from the store.
 *
 * @param {Datastore} store
 * @param {CID} cid
 * @returns {Promise<Map<PeerId, Date>>}
 *
 * @private
 */ async function loadProviders(store, cid) {
    const providers = new Map();
    const query = store.query({
        prefix: makeProviderKey(cid)
    });
    for await (const entry of query){
        const { peerId  } = parseProviderKey(entry.key);
        providers.set(peerId, readTime(entry.value));
    }
    return providers;
}
/**
 * @param {Uint8Array} buf
 */ function readTime(buf) {
    return varint.decode(buf);
}
module.exports = Providers;

},{"hashlru":"fzwAb","varint":"l84uL","peer-id":"4VGWt","interface-datastore/key":"ccQWS","p-queue":"ccCVf","./constants":"b8cEs","./utils":"16BUU"}],"jkIo4":[function(require,module,exports) {
'use strict';
/**
 * @typedef {import('./query')} Query
 */ /**
 * Keeps track of all running queries.
 */ class QueryManager {
    /**
   * Creates a new QueryManager.
   */ constructor(){
        this.queries = new Set();
        this.running = false;
    }
    /**
   * Called when a query is started.
   *
   * @param {Query} query
   */ queryStarted(query) {
        this.queries.add(query);
    }
    /**
   * Called when a query completes.
   *
   * @param {Query} query
   */ queryCompleted(query1) {
        this.queries.delete(query1);
    }
    /**
   * Starts the query manager.
   */ start() {
        this.running = true;
    }
    /**
   * Stops all queries.
   */ stop() {
        this.running = false;
        for (const query of this.queries)query.stop();
        this.queries.clear();
    }
}
module.exports = QueryManager;

},{}],"1OT9O":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var ipns = require('ipns');
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n["default"] = e;
    return Object.freeze(n);
}
var ipns__namespace = /*#__PURE__*/ _interopNamespace(ipns);
const validator = {
    func: (key, record)=>ipns__namespace.validator.validate(record, key)
};
function selector(_k, records) {
    return ipns__namespace.validator.select(records[0], records[1]);
}
exports.selector = selector;
exports.validator = validator;

},{"ipns":"jnLxg"}],"lAx0u":[function(require,module,exports) {
'use strict';
const PeerId = require('peer-id');
const { Multiaddr  } = require('multiaddr');
const mafmt = require('mafmt');
const { EventEmitter  } = require('events');
const debug = require('debug');
const log = Object.assign(debug('libp2p:bootstrap'), {
    error: debug('libp2p:bootstrap:error')
});
/**
 * Emits 'peer' events on a regular interval for each peer in the provided list.
 */ class Bootstrap extends EventEmitter {
    /**
   * Constructs a new Bootstrap.
   *
   * @param {Object} options
   * @param {Array<string>} options.list - the list of peer addresses in multi-address format
   * @param {number} [options.interval = 10000] - the interval between emitting addresses in milliseconds
   *
   */ constructor(options = {
        list: []
    }){
        if (!options.list || !options.list.length) throw new Error('Bootstrap requires a list of peer addresses');
        super();
        this._list = options.list;
        this._interval = options.interval || 10000;
        this._timer = null;
    }
    /**
   * Start emitting events.
   */ start() {
        if (this._timer) return;
        this._timer = setInterval(()=>this._discoverBootstrapPeers()
        , this._interval);
        log('Starting bootstrap node discovery');
        this._discoverBootstrapPeers();
    }
    /**
   * Emit each address in the list as a PeerInfo.
   */ _discoverBootstrapPeers() {
        if (!this._timer) return;
        this._list.forEach((candidate)=>{
            if (!mafmt.P2P.matches(candidate)) return log.error('Invalid multiaddr');
            const ma = new Multiaddr(candidate);
            const peerIdStr = ma.getPeerId();
            if (!peerIdStr) {
                log.error('Invalid bootstrap multiaddr without peer id');
                return;
            }
            const peerId = PeerId.createFromB58String(peerIdStr);
            try {
                this.emit('peer', {
                    id: peerId,
                    multiaddrs: [
                        ma
                    ]
                });
            } catch (err) {
                log.error('Invalid bootstrap peer id', err);
            }
        });
    }
    /**
   * Stop emitting events.
   */ stop() {
        if (this._timer) clearInterval(this._timer);
        this._timer = null;
    }
}
exports = module.exports = Bootstrap;
exports.tag = 'bootstrap';

},{"peer-id":"4VGWt","multiaddr":"kOPrF","mafmt":"hdtcj","events":"bHM3D","debug":"lWlU4"}],"1VuOh":[function(require,module,exports) {
'use strict';
const debug = require('debug');
const log = Object.assign(debug('libp2p'), {
    error: debug('libp2p:err')
});
const { EventEmitter  } = require('events');
const errCode = require('err-code');
const PeerId = require('peer-id');
const { Multiaddr  } = require('multiaddr');
const PeerRouting = require('./peer-routing');
const ContentRouting = require('./content-routing');
const getPeer = require('./get-peer');
const { validate: validateConfig  } = require('./config');
const { codes , messages  } = require('./errors');
const AddressManager = require('./address-manager');
const ConnectionManager = require('./connection-manager');
const Circuit = require('./circuit/transport');
const Relay = require('./circuit');
const Dialer = require('./dialer');
const Keychain = require('./keychain');
const Metrics = require('./metrics');
const TransportManager = require('./transport-manager');
const Upgrader = require('./upgrader');
const PeerStore = require('./peer-store');
const PubsubAdapter = require('./pubsub-adapter');
const PersistentPeerStore = require('./peer-store/persistent');
const Registrar = require('./registrar');
const ping = require('./ping');
const IdentifyService = require('./identify');
const NatManager = require('./nat-manager');
const { updateSelfPeerRecord  } = require('./record/utils');
/**
 * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection
 * @typedef {import('libp2p-interfaces/src/stream-muxer/types').MuxedStream} MuxedStream
 * @typedef {import('libp2p-interfaces/src/transport/types').TransportFactory<any, any>} TransportFactory
 * @typedef {import('libp2p-interfaces/src/stream-muxer/types').MuxerFactory} MuxerFactory
 * @typedef {import('libp2p-interfaces/src/content-routing/types').ContentRouting} ContentRoutingModule
 * @typedef {import('libp2p-interfaces/src/peer-discovery/types').PeerDiscoveryFactory} PeerDiscoveryFactory
 * @typedef {import('libp2p-interfaces/src/peer-routing/types').PeerRouting} PeerRoutingModule
 * @typedef {import('libp2p-interfaces/src/crypto/types').Crypto} Crypto
 * @typedef {import('libp2p-interfaces/src/pubsub')} Pubsub
 * @typedef {import('libp2p-interfaces/src/pubsub').PubsubOptions} PubsubOptions
 * @typedef {import('interface-datastore').Datastore} Datastore
 * @typedef {import('./pnet')} Protector
 */ /**
 * @typedef {Object} HandlerProps
 * @property {Connection} connection
 * @property {MuxedStream} stream
 * @property {string} protocol
 *
 * @typedef {Object} RandomWalkOptions
 * @property {boolean} [enabled = false]
 * @property {number} [queriesPerPeriod = 1]
 * @property {number} [interval = 300e3]
 * @property {number} [timeout = 10e3]
 *
 * @typedef {Object} DhtOptions
 * @property {boolean} [enabled = false]
 * @property {number} [kBucketSize = 20]
 * @property {RandomWalkOptions} [randomWalk]
 * @property {boolean} [clientMode]
 * @property {import('libp2p-interfaces/src/types').DhtSelectors} [selectors]
 * @property {import('libp2p-interfaces/src/types').DhtValidators} [validators]
 *
 * @typedef {Object} KeychainOptions
 * @property {Datastore} [datastore]
 *
 * @typedef {Object} PeerStoreOptions
 * @property {boolean} persistence
 *
 * @typedef {Object} PubsubLocalOptions
 * @property {boolean} enabled
 *
 * @typedef {Object} MetricsOptions
 * @property {boolean} enabled
 *
 * @typedef {Object} RelayOptions
 * @property {boolean} [enabled = true]
 * @property {import('./circuit').RelayAdvertiseOptions} [advertise]
 * @property {import('./circuit').HopOptions} [hop]
 * @property {import('./circuit').AutoRelayOptions} [autoRelay]
 *
 * @typedef {Object} Libp2pConfig
 * @property {DhtOptions} [dht] dht module options
 * @property {import('./nat-manager').NatManagerOptions} [nat]
 * @property {Record<string, Object|boolean>} [peerDiscovery]
 * @property {PubsubLocalOptions & PubsubOptions} [pubsub] pubsub module options
 * @property {RelayOptions} [relay]
 * @property {Record<string, Object>} [transport] transport options indexed by transport key
 *
 * @typedef {Object} Libp2pModules
 * @property {TransportFactory[]} transport
 * @property {MuxerFactory[]} streamMuxer
 * @property {Crypto[]} connEncryption
 * @property {PeerDiscoveryFactory[]} [peerDiscovery]
 * @property {PeerRoutingModule[]} [peerRouting]
 * @property {ContentRoutingModule[]} [contentRouting]
 * @property {Object} [dht]
 * @property {{new(...args: any[]): Pubsub}} [pubsub]
 * @property {Protector} [connProtector]
 *
 * @typedef {Object} Libp2pOptions
 * @property {Libp2pModules} modules libp2p modules to use
 * @property {import('./address-manager').AddressManagerOptions} [addresses]
 * @property {import('./connection-manager').ConnectionManagerOptions} [connectionManager]
 * @property {Datastore} [datastore]
 * @property {import('./dialer').DialerOptions} [dialer]
 * @property {import('./identify/index').HostProperties} [host] libp2p host
 * @property {KeychainOptions & import('./keychain/index').KeychainOptions} [keychain]
 * @property {MetricsOptions & import('./metrics').MetricsOptions} [metrics]
 * @property {import('./peer-routing').PeerRoutingOptions} [peerRouting]
 * @property {PeerStoreOptions & import('./peer-store/persistent').PersistentPeerStoreOptions} [peerStore]
 * @property {import('./transport-manager').TransportManagerOptions} [transportManager]
 * @property {Libp2pConfig} [config]
 *
 * @typedef {Object} constructorOptions
 * @property {PeerId} peerId
 *
 * @typedef {Object} CreateOptions
 * @property {PeerId} [peerId]
 *
 * @extends {EventEmitter}
 * @fires Libp2p#error Emitted when an error occurs
 * @fires Libp2p#peer:discovery Emitted when a peer is discovered
 */ class Libp2p extends EventEmitter {
    /**
   * Like `new Libp2p(options)` except it will create a `PeerId`
   * instance if one is not provided in options.
   *
   * @param {Libp2pOptions & CreateOptions} options - Libp2p configuration options
   * @returns {Promise<Libp2p>}
   */ static async create(options) {
        if (options.peerId) // @ts-ignore 'Libp2pOptions & CreateOptions' is not assignable to 'Libp2pOptions & constructorOptions'
        return new Libp2p(options);
        const peerId = await PeerId.create();
        options.peerId = peerId;
        // @ts-ignore 'Libp2pOptions & CreateOptions' is not assignable to 'Libp2pOptions & constructorOptions'
        return new Libp2p(options);
    }
    /**
   * Libp2p node.
   *
   * @class
   * @param {Libp2pOptions & constructorOptions} _options
   */ constructor(_options){
        super();
        // validateConfig will ensure the config is correct,
        // and add default values where appropriate
        this._options = validateConfig(_options);
        /** @type {PeerId} */ this.peerId = this._options.peerId;
        this.datastore = this._options.datastore;
        this.peerStore = this.datastore && this._options.peerStore.persistence ? new PersistentPeerStore({
            peerId: this.peerId,
            datastore: this.datastore,
            ...this._options.peerStore
        }) : new PeerStore({
            peerId: this.peerId
        });
        // Addresses {listen, announce, noAnnounce}
        this.addresses = this._options.addresses;
        this.addressManager = new AddressManager(this.peerId, this._options.addresses);
        // when addresses change, update our peer record
        this.addressManager.on('change:addresses', ()=>{
            updateSelfPeerRecord(this).catch((err)=>{
                log.error('Error updating self peer record', err);
            });
        });
        this._modules = this._options.modules;
        this._config = this._options.config;
        this._transport = [] // Transport instances/references
        ;
        this._discovery = new Map() // Discovery service instances/references
        ;
        // Create the Connection Manager
        this.connectionManager = new ConnectionManager(this, {
            autoDial: this._config.peerDiscovery.autoDial,
            ...this._options.connectionManager
        });
        // Create Metrics
        if (this._options.metrics.enabled) this.metrics = new Metrics({
            ...this._options.metrics,
            connectionManager: this.connectionManager
        });
        // Create keychain
        if (this._options.keychain && this._options.keychain.datastore) {
            log('creating keychain');
            const keychainOpts = Keychain.generateOptions();
            this.keychain = new Keychain(this._options.keychain.datastore, {
                ...keychainOpts,
                ...this._options.keychain
            });
            log('keychain constructed');
        }
        // Setup the Upgrader
        this.upgrader = new Upgrader({
            localPeer: this.peerId,
            metrics: this.metrics,
            onConnection: (connection)=>this.connectionManager.onConnect(connection)
            ,
            onConnectionEnd: (connection)=>this.connectionManager.onDisconnect(connection)
        });
        // Setup the transport manager
        this.transportManager = new TransportManager({
            libp2p: this,
            upgrader: this.upgrader,
            faultTolerance: this._options.transportManager.faultTolerance
        });
        // Create the Nat Manager
        this.natManager = new NatManager({
            peerId: this.peerId,
            addressManager: this.addressManager,
            transportManager: this.transportManager,
            // @ts-ignore Nat typedef is not understood as Object
            ...this._options.config.nat
        });
        // Create the Registrar
        this.registrar = new Registrar({
            peerStore: this.peerStore,
            connectionManager: this.connectionManager
        });
        this.handle = this.handle.bind(this);
        this.registrar.handle = this.handle;
        // Attach crypto channels
        if (!this._modules.connEncryption || !this._modules.connEncryption.length) throw errCode(new Error(messages.CONN_ENCRYPTION_REQUIRED), codes.CONN_ENCRYPTION_REQUIRED);
        const cryptos = this._modules.connEncryption;
        cryptos.forEach((crypto)=>{
            this.upgrader.cryptos.set(crypto.protocol, crypto);
        });
        this.dialer = new Dialer({
            transportManager: this.transportManager,
            peerStore: this.peerStore,
            ...this._options.dialer
        });
        this._modules.transport.forEach((Transport)=>{
            const key = Transport.prototype[Symbol.toStringTag];
            const transportOptions = this._config.transport[key];
            this.transportManager.add(key, Transport, transportOptions);
        });
        if (this._config.relay.enabled) {
            // @ts-ignore Circuit prototype
            this.transportManager.add(Circuit.prototype[Symbol.toStringTag], Circuit);
            this.relay = new Relay(this);
        }
        // Attach stream multiplexers
        if (this._modules.streamMuxer) {
            const muxers = this._modules.streamMuxer;
            muxers.forEach((muxer)=>{
                this.upgrader.muxers.set(muxer.multicodec, muxer);
            });
            // Add the identify service since we can multiplex
            this.identifyService = new IdentifyService({
                libp2p: this
            });
            this.handle(Object.values(IdentifyService.getProtocolStr(this)), this.identifyService.handleMessage);
        }
        // Attach private network protector
        if (this._modules.connProtector) this.upgrader.protector = this._modules.connProtector;
        else if (globalThis.process !== undefined && globalThis.process.env && globalThis.process.env.LIBP2P_FORCE_PNET) throw new Error('Private network is enforced, but no protector was provided');
        // dht provided components (peerRouting, contentRouting, dht)
        if (this._modules.dht) {
            const DHT = this._modules.dht;
            // @ts-ignore Object is not constructable
            this._dht = new DHT({
                libp2p: this,
                dialer: this.dialer,
                peerId: this.peerId,
                peerStore: this.peerStore,
                registrar: this.registrar,
                datastore: this.datastore,
                ...this._config.dht
            });
        }
        // Create pubsub if provided
        if (this._modules.pubsub) {
            const Pubsub = this._modules.pubsub;
            // using pubsub adapter with *DEPRECATED* handlers functionality
            /** @type {Pubsub} */ this.pubsub = PubsubAdapter(Pubsub, this, this._config.pubsub);
        }
        // Attach remaining APIs
        // peer and content routing will automatically get modules from _modules and _dht
        this.peerRouting = new PeerRouting(this);
        this.contentRouting = new ContentRouting(this);
        // Mount default protocols
        ping.mount(this);
        this._onDiscoveryPeer = this._onDiscoveryPeer.bind(this);
    }
    /**
   * Overrides EventEmitter.emit to conditionally emit errors
   * if there is a handler. If not, errors will be logged.
   *
   * @param {string} eventName
   * @param  {...any} args
   * @returns {boolean}
   */ emit(eventName, ...args) {
        // TODO: do we still need this?
        // @ts-ignore _events does not exist in libp2p
        if (eventName === 'error' && !this._events.error) {
            log.error(args);
            return false;
        } else return super.emit(eventName, ...args);
    }
    /**
   * Starts the libp2p node and all its subsystems
   *
   * @returns {Promise<void>}
   */ async start() {
        log('libp2p is starting');
        try {
            await this._onStarting();
            await this._onDidStart();
            log('libp2p has started');
        } catch (err) {
            this.emit('error', err);
            log.error('An error occurred starting libp2p', err);
            await this.stop();
            throw err;
        }
    }
    /**
   * Stop the libp2p node by closing its listeners and open connections
   *
   * @async
   * @returns {Promise<void>}
   */ async stop() {
        log('libp2p is stopping');
        try {
            this._isStarted = false;
            this.relay && this.relay.stop();
            this.peerRouting.stop();
            for (const service of this._discovery.values())service.removeListener('peer', this._onDiscoveryPeer);
            await Promise.all(Array.from(this._discovery.values(), (s)=>s.stop()
            ));
            this._discovery = new Map();
            await this.peerStore.stop();
            await this.connectionManager.stop();
            await Promise.all([
                this.pubsub && this.pubsub.stop(),
                this._dht && this._dht.stop(),
                this.metrics && this.metrics.stop()
            ]);
            await this.natManager.stop();
            await this.transportManager.close();
            ping.unmount(this);
            this.dialer.destroy();
        } catch (err) {
            if (err) {
                log.error(err);
                this.emit('error', err);
            }
        }
        log('libp2p has stopped');
    }
    /**
   * Load keychain keys from the datastore.
   * Imports the private key as 'self', if needed.
   *
   * @async
   * @returns {Promise<void>}
   */ async loadKeychain() {
        if (!this.keychain) return;
        try {
            await this.keychain.findKeyByName('self');
        } catch (err) {
            await this.keychain.importPeer('self', this.peerId);
        }
    }
    isStarted() {
        return this._isStarted;
    }
    /**
   * Gets a Map of the current connections. The keys are the stringified
   * `PeerId` of the peer. The value is an array of Connections to that peer.
   *
   * @returns {Map<string, Connection[]>}
   */ get connections() {
        return this.connectionManager.connections;
    }
    /**
   * Dials to the provided peer. If successful, the known metadata of the
   * peer will be added to the nodes `peerStore`
   *
   * @param {PeerId|Multiaddr|string} peer - The peer to dial
   * @param {object} [options]
   * @param {AbortSignal} [options.signal]
   * @returns {Promise<Connection>}
   */ dial(peer, options1) {
        return this._dial(peer, options1);
    }
    /**
   * Dials to the provided peer and tries to handshake with the given protocols in order.
   * If successful, the known metadata of the peer will be added to the nodes `peerStore`,
   * and the `MuxedStream` will be returned together with the successful negotiated protocol.
   *
   * @async
   * @param {PeerId|Multiaddr|string} peer - The peer to dial
   * @param {string[]|string} protocols
   * @param {object} [options]
   * @param {AbortSignal} [options.signal]
   */ async dialProtocol(peer1, protocols, options2) {
        if (!protocols || !protocols.length) throw errCode(new Error('no protocols were provided to open a stream'), codes.ERR_INVALID_PROTOCOLS_FOR_STREAM);
        const connection = await this._dial(peer1, options2);
        return connection.newStream(protocols);
    }
    /**
   * @async
   * @param {PeerId|Multiaddr|string} peer - The peer to dial
   * @param {object} [options]
   * @returns {Promise<Connection>}
   */ async _dial(peer2, options3) {
        const { id , multiaddrs  } = getPeer(peer2);
        if (id.equals(this.peerId)) throw errCode(new Error('Cannot dial self'), codes.ERR_DIALED_SELF);
        let connection = this.connectionManager.get(id);
        if (!connection) connection = await this.dialer.connectToPeer(peer2, options3);
        else if (multiaddrs) this.peerStore.addressBook.add(id, multiaddrs);
        return connection;
    }
    /**
   * Get a deduplicated list of peer advertising multiaddrs by concatenating
   * the listen addresses used by transports with any configured
   * announce addresses as well as observed addresses reported by peers.
   *
   * If Announce addrs are specified, configured listen addresses will be
   * ignored though observed addresses will still be included.
   *
   * @returns {Multiaddr[]}
   */ get multiaddrs() {
        let addrs = this.addressManager.getAnnounceAddrs().map((ma)=>ma.toString()
        );
        if (!addrs.length) // no configured announce addrs, add configured listen addresses
        addrs = this.transportManager.getAddrs().map((ma)=>ma.toString()
        );
        addrs = addrs.concat(this.addressManager.getObservedAddrs().map((ma)=>ma.toString()
        ));
        const announceFilter = this._options.addresses.announceFilter;
        // dedupe multiaddrs
        const addrSet = new Set(addrs);
        // Create advertising list
        return announceFilter(Array.from(addrSet).map((str)=>new Multiaddr(str)
        ));
    }
    /**
   * Disconnects all connections to the given `peer`
   *
   * @param {PeerId|Multiaddr|string} peer - the peer to close connections to
   * @returns {Promise<void>}
   */ async hangUp(peer3) {
        const { id  } = getPeer(peer3);
        const connections = this.connectionManager.connections.get(id.toB58String());
        if (!connections) return;
        await Promise.all(connections.map((connection)=>{
            return connection.close();
        }));
    }
    /**
   * Pings the given peer in order to obtain the operation latency.
   *
   * @param {PeerId|Multiaddr|string} peer - The peer to ping
   * @returns {Promise<number>}
   */ ping(peer4) {
        const { id , multiaddrs  } = getPeer(peer4);
        // If received multiaddr, ping it
        if (multiaddrs) return ping(this, multiaddrs[0]);
        return ping(this, id);
    }
    /**
   * Registers the `handler` for each protocol
   *
   * @param {string[]|string} protocols
   * @param {(props: HandlerProps) => void} handler
   */ handle(protocols1, handler) {
        protocols1 = Array.isArray(protocols1) ? protocols1 : [
            protocols1
        ];
        protocols1.forEach((protocol)=>{
            this.upgrader.protocols.set(protocol, handler);
        });
        // Add new protocols to self protocols in the Protobook
        this.peerStore.protoBook.add(this.peerId, protocols1);
    }
    /**
   * Removes the handler for each protocol. The protocol
   * will no longer be supported on streams.
   *
   * @param {string[]|string} protocols
   */ unhandle(protocols2) {
        protocols2 = Array.isArray(protocols2) ? protocols2 : [
            protocols2
        ];
        protocols2.forEach((protocol)=>{
            this.upgrader.protocols.delete(protocol);
        });
        // Remove protocols from self protocols in the Protobook
        this.peerStore.protoBook.remove(this.peerId, protocols2);
    }
    async _onStarting() {
        // Listen on the provided transports for the provided addresses
        const addrs = this.addressManager.getListenAddrs();
        await this.transportManager.listen(addrs);
        // Manage your NATs
        this.natManager.start();
        // Start PeerStore
        await this.peerStore.start();
        if (this._config.pubsub.enabled) this.pubsub && this.pubsub.start();
        // DHT subsystem
        if (this._config.dht.enabled) {
            this._dht && this._dht.start();
            // TODO: this should be modified once random-walk is used as
            // the other discovery modules
            this._dht.on('peer', this._onDiscoveryPeer);
        }
        // Start metrics if present
        this.metrics && this.metrics.start();
    }
    /**
   * Called when libp2p has started and before it returns
   *
   * @private
   */ async _onDidStart() {
        this._isStarted = true;
        this.peerStore.on('peer', (peerId)=>{
            this.emit('peer:discovery', peerId);
            this._maybeConnect(peerId);
        });
        // Once we start, emit any peers we may have already discovered
        // TODO: this should be removed, as we already discovered these peers in the past
        for (const peer of this.peerStore.peers.values())this.emit('peer:discovery', peer.id);
        this.connectionManager.start();
        // Peer discovery
        await this._setupPeerDiscovery();
        // Relay
        this.relay && this.relay.start();
        this.peerRouting.start();
    }
    /**
   * Called whenever peer discovery services emit `peer` events.
   * Known peers may be emitted.
   *
   * @private
   * @param {{ id: PeerId, multiaddrs: Multiaddr[], protocols: string[] }} peer
   */ _onDiscoveryPeer(peer5) {
        if (peer5.id.toB58String() === this.peerId.toB58String()) {
            log.error(new Error(codes.ERR_DISCOVERED_SELF));
            return;
        }
        peer5.multiaddrs && this.peerStore.addressBook.add(peer5.id, peer5.multiaddrs);
        peer5.protocols && this.peerStore.protoBook.set(peer5.id, peer5.protocols);
    }
    /**
   * Will dial to the given `peerId` if the current number of
   * connected peers is less than the configured `ConnectionManager`
   * minConnections.
   *
   * @private
   * @param {PeerId} peerId
   */ async _maybeConnect(peerId) {
        // If auto dialing is on and we have no connection to the peer, check if we should dial
        if (this._config.peerDiscovery.autoDial === true && !this.connectionManager.get(peerId)) {
            const minConnections = this._options.connectionManager.minConnections || 0;
            if (minConnections > this.connectionManager.size) {
                log('connecting to discovered peer %s', peerId.toB58String());
                try {
                    await this.dialer.connectToPeer(peerId);
                } catch (err) {
                    log.error(`could not connect to discovered peer ${peerId.toB58String()} with ${err}`);
                }
            }
        }
    }
    /**
   * Initializes and starts peer discovery services
   *
   * @async
   * @private
   */ async _setupPeerDiscovery() {
        /**
     * @param {PeerDiscoveryFactory} DiscoveryService
     */ const setupService = (DiscoveryService)=>{
            let config = {
                enabled: true // on by default
            };
            if (DiscoveryService.tag && this._config.peerDiscovery && this._config.peerDiscovery[DiscoveryService.tag]) // @ts-ignore PeerDiscovery not understood as an Object for spread
            config = {
                ...config,
                ...this._config.peerDiscovery[DiscoveryService.tag]
            };
            if (config.enabled && !this._discovery.has(DiscoveryService.tag)) {
                let discoveryService;
                if (typeof DiscoveryService === 'function') // @ts-ignore DiscoveryService has no constructor type inferred
                discoveryService = new DiscoveryService(Object.assign({
                }, config, {
                    peerId: this.peerId,
                    libp2p: this
                }));
                else discoveryService = DiscoveryService;
                discoveryService.on('peer', this._onDiscoveryPeer);
                this._discovery.set(DiscoveryService.tag, discoveryService);
            }
        };
        // Discovery modules
        for (const DiscoveryService1 of this._modules.peerDiscovery || [])setupService(DiscoveryService1);
        // Transport modules with discovery
        for (const Transport of this.transportManager.getTransports())// @ts-ignore Transport interface does not include discovery
        if (Transport.discovery) // @ts-ignore Transport interface does not include discovery
        setupService(Transport.discovery);
        await Promise.all(Array.from(this._discovery.values(), (d)=>d.start()
        ));
    }
}
module.exports = Libp2p;

},{"debug":"lWlU4","events":"bHM3D","err-code":"eQvyh","peer-id":"4VGWt","multiaddr":"kOPrF","./peer-routing":"eCYhW","./content-routing":"eOkjp","./get-peer":"8B3xC","./config":"3Ycck","./errors":"dO31S","./address-manager":"kRtIc","./connection-manager":"RxH4d","./circuit/transport":"6Ysb8","./circuit":"1RcZC","./dialer":"dakOv","./keychain":"qJaG4","./metrics":"iSisa","./transport-manager":"fdmmy","./upgrader":"2e64O","./peer-store":"SedIN","./pubsub-adapter":"hpvjv","./peer-store/persistent":"hlkIm","./registrar":"gAB2y","./ping":"4QQ6u","./identify":"aTTi0","./nat-manager":"iQ3J2","./record/utils":"6p0gR"}],"eCYhW":[function(require,module,exports) {
'use strict';
const debug = require('debug');
const log = Object.assign(debug('libp2p:peer-routing'), {
    error: debug('libp2p:peer-routing:err')
});
const errCode = require('err-code');
const { storeAddresses , uniquePeers , requirePeers  } = require('./content-routing/utils');
const merge = require('it-merge');
const { pipe  } = require('it-pipe');
const first = require('it-first');
const drain = require('it-drain');
const filter = require('it-filter');
const { setDelayedInterval , clearDelayedInterval  } = require('set-delayed-interval');
/**
 * @typedef {import('peer-id')} PeerId
 * @typedef {import('multiaddr').Multiaddr} Multiaddr
 * @typedef {import('libp2p-interfaces/src/peer-routing/types').PeerRouting} PeerRoutingModule
 */ /**
 * @typedef {Object} RefreshManagerOptions
 * @property {boolean} [enabled = true] - Whether to enable the Refresh manager
 * @property {number} [bootDelay = 6e5] - Boot delay to start the Refresh Manager (in ms)
 * @property {number} [interval = 10e3] - Interval between each Refresh Manager run (in ms)
 *
 * @typedef {Object} PeerRoutingOptions
 * @property {RefreshManagerOptions} [refreshManager]
 */ class PeerRouting {
    /**
   * @class
   * @param {import('./')} libp2p
   */ constructor(libp2p){
        this._peerId = libp2p.peerId;
        this._peerStore = libp2p.peerStore;
        /** @type {PeerRoutingModule[]} */ this._routers = libp2p._modules.peerRouting || [];
        // If we have the dht, add it to the available peer routers
        if (libp2p._dht && libp2p._config.dht.enabled) this._routers.push(libp2p._dht);
        this._refreshManagerOptions = libp2p._options.peerRouting.refreshManager;
        this._findClosestPeersTask = this._findClosestPeersTask.bind(this);
    }
    /**
   * Start peer routing service.
   */ start() {
        if (!this._routers.length || this._timeoutId || !this._refreshManagerOptions.enabled) return;
        this._timeoutId = setDelayedInterval(this._findClosestPeersTask, this._refreshManagerOptions.interval, this._refreshManagerOptions.bootDelay);
    }
    /**
   * Recurrent task to find closest peers and add their addresses to the Address Book.
   */ async _findClosestPeersTask() {
        try {
            // nb getClosestPeers adds the addresses to the address book
            await drain(this.getClosestPeers(this._peerId.id));
        } catch (err) {
            log.error(err);
        }
    }
    /**
   * Stop peer routing service.
   */ stop() {
        clearDelayedInterval(this._timeoutId);
    }
    /**
   * Iterates over all peer routers in parallel to find the given peer.
   *
   * @param {PeerId} id - The id of the peer to find
   * @param {object} [options]
   * @param {number} [options.timeout] - How long the query should run
   * @returns {Promise<{ id: PeerId, multiaddrs: Multiaddr[] }>}
   */ async findPeer(id, options) {
        if (!this._routers.length) throw errCode(new Error('No peer routers available'), 'NO_ROUTERS_AVAILABLE');
        if (id.toB58String() === this._peerId.toB58String()) throw errCode(new Error('Should not try to find self'), 'ERR_FIND_SELF');
        const output = await pipe(merge(...this._routers.map((router)=>[
                router.findPeer(id, options)
            ]
        )), (source)=>filter(source, Boolean)
        , // @ts-ignore findPeer resolves a Promise
        (source)=>storeAddresses(source, this._peerStore)
        , (source)=>first(source)
        );
        if (output) return output;
        throw errCode(new Error('not found'), 'NOT_FOUND');
    }
    /**
   * Attempt to find the closest peers on the network to the given key.
   *
   * @param {Uint8Array} key - A CID like key
   * @param {Object} [options]
   * @param {number} [options.timeout=30e3] - How long the query can take.
   * @returns {AsyncIterable<{ id: PeerId, multiaddrs: Multiaddr[] }>}
   */ async *getClosestPeers(key, options1 = {
        timeout: 30000
    }) {
        if (!this._routers.length) throw errCode(new Error('No peer routers available'), 'NO_ROUTERS_AVAILABLE');
        yield* pipe(merge(...this._routers.map((router)=>router.getClosestPeers(key, options1)
        )), (source)=>storeAddresses(source, this._peerStore)
        , (source)=>uniquePeers(source)
        , (source)=>requirePeers(source)
        );
    }
}
module.exports = PeerRouting;

},{"debug":"lWlU4","err-code":"eQvyh","./content-routing/utils":"bXhXE","it-merge":"7iKAo","it-pipe":"4jukm","it-first":"imIGO","it-drain":"h63K2","it-filter":"7NtwB","set-delayed-interval":"jrB3f"}],"bXhXE":[function(require,module,exports) {
'use strict';
const errCode = require('err-code');
const filter = require('it-filter');
const map = require('it-map');
const take = require('it-take');
/**
 * @typedef {import('peer-id')} PeerId
 * @typedef {import('multiaddr').Multiaddr} Multiaddr
 */ /**
 * Store the multiaddrs from every peer in the passed peer store
 *
 * @param {AsyncIterable<{ id: PeerId, multiaddrs: Multiaddr[] }>} source
 * @param {import('../peer-store')} peerStore
 */ function storeAddresses(source, peerStore) {
    return map(source, (peer)=>{
        // ensure we have the addresses for a given peer
        peerStore.addressBook.add(peer.id, peer.multiaddrs);
        return peer;
    });
}
/**
 * Filter peers by unique peer id
 *
 * @param {AsyncIterable<{ id: PeerId, multiaddrs: Multiaddr[] }>} source
 */ function uniquePeers(source) {
    /** @type Set<string> */ const seen = new Set();
    return filter(source, (peer)=>{
        // dedupe by peer id
        if (seen.has(peer.id.toString())) return false;
        seen.add(peer.id.toString());
        return true;
    });
}
/**
 * Require at least `min` peers to be yielded from `source`
 *
 * @param {AsyncIterable<{ id: PeerId, multiaddrs: Multiaddr[] }>} source
 * @param {number} min
 */ async function* requirePeers(source, min = 1) {
    let seen = 0;
    for await (const peer of source){
        seen++;
        yield peer;
    }
    if (seen < min) throw errCode(new Error('not found'), 'NOT_FOUND');
}
/**
 * If `max` is passed, only take that number of peers from the source
 * otherwise take all the peers
 *
 * @param {AsyncIterable<{ id: PeerId, multiaddrs: Multiaddr[] }>} source
 * @param {number} [max]
 */ function maybeLimitSource(source, max) {
    if (max) return take(source, max);
    return source;
}
module.exports = {
    storeAddresses,
    uniquePeers,
    requirePeers,
    maybeLimitSource
};

},{"err-code":"eQvyh","it-filter":"7NtwB","it-map":"dOmp3","it-take":"8hPk7"}],"jrB3f":[function(require,module,exports) {
'use strict';
const intervals = new Map();
const _generateId = ()=>`${Date.now()}:${Math.floor(Math.random() * 1000000)}`
;
/**
 * Run a given task each {interval} ms
 *
 * @param {() => Promise} task
 * @param {number} interval
 * @param {string} id
 */ async function _runPeriodically(task, interval, id) {
    while(intervals.get(id)){
        try {
            await task();
        } catch (err) {
            // Throw global context error if handler throws
            setTimeout(()=>{
                throw err;
            }, 1);
            break;
        }
        if (!intervals.get(id)) break;
        await new Promise((resolve)=>{
            const _timeout = setTimeout(resolve, interval);
            intervals.set(id, _timeout);
        });
    }
}
/**
 * Asynchronous setInterval that is properly delayed using promises and can be delayed on boot.
 *
 * @param {() => Promise} task
 * @param {number} interval
 * @param {number} [delay = interval]
 * @returns {string}
 */ function setDelayedInterval(task, interval, delay) {
    delay = delay || interval;
    const id = _generateId();
    const _timeout = setTimeout(()=>{
        _runPeriodically(task, interval, id);
    }, delay);
    intervals.set(id, _timeout);
    return id;
}
/**
 * Clear delayed interval.
 *
 * @param {string} id
 */ function clearDelayedInterval(id) {
    const _timeout = intervals.get(id);
    if (_timeout) {
        clearTimeout(_timeout);
        intervals.delete(id);
    }
}
module.exports = {
    setDelayedInterval,
    clearDelayedInterval
};

},{}],"eOkjp":[function(require,module,exports) {
'use strict';
const errCode = require('err-code');
const { messages , codes  } = require('../errors');
const { storeAddresses , uniquePeers , requirePeers , maybeLimitSource  } = require('./utils');
const merge = require('it-merge');
const { pipe  } = require('it-pipe');
/**
 * @typedef {import('peer-id')} PeerId
 * @typedef {import('multiaddr').Multiaddr} Multiaddr
 * @typedef {import('multiformats/cid').CID} CID
 * @typedef {import('libp2p-interfaces/src/content-routing/types').ContentRouting} ContentRoutingModule
 */ /**
 * @typedef {Object} GetData
 * @property {PeerId} from
 * @property {Uint8Array} val
 */ class ContentRouting {
    /**
   * @class
   * @param {import('..')} libp2p
   */ constructor(libp2p){
        this.libp2p = libp2p;
        /** @type {ContentRoutingModule[]} */ this.routers = libp2p._modules.contentRouting || [];
        this.dht = libp2p._dht;
        // If we have the dht, add it to the available content routers
        if (this.dht && libp2p._config.dht.enabled) this.routers.push(this.dht);
    }
    /**
   * Iterates over all content routers in parallel to find providers of the given key.
   *
   * @param {CID} key - The CID key of the content to find
   * @param {object} [options]
   * @param {number} [options.timeout] - How long the query should run
   * @param {number} [options.maxNumProviders] - maximum number of providers to find
   * @returns {AsyncIterable<{ id: PeerId, multiaddrs: Multiaddr[] }>}
   */ async *findProviders(key, options = {
    }) {
        if (!this.routers.length) throw errCode(new Error('No content this.routers available'), 'NO_ROUTERS_AVAILABLE');
        yield* pipe(merge(...this.routers.map((router)=>router.findProviders(key, options)
        )), (source)=>storeAddresses(source, this.libp2p.peerStore)
        , (source)=>uniquePeers(source)
        , (source)=>maybeLimitSource(source, options.maxNumProviders)
        , (source)=>requirePeers(source)
        );
    }
    /**
   * Iterates over all content routers in parallel to notify it is
   * a provider of the given key.
   *
   * @param {CID} key - The CID key of the content to find
   * @returns {Promise<void>}
   */ async provide(key1) {
        if (!this.routers.length) throw errCode(new Error('No content routers available'), 'NO_ROUTERS_AVAILABLE');
        await Promise.all(this.routers.map((router)=>router.provide(key1)
        ));
    }
    /**
   * Store the given key/value pair in the DHT.
   *
   * @param {Uint8Array} key
   * @param {Uint8Array} value
   * @param {Object} [options] - put options
   * @param {number} [options.minPeers] - minimum number of peers required to successfully put
   * @returns {Promise<void>}
   */ put(key2, value, options1) {
        if (!this.libp2p.isStarted() || !this.dht.isStarted) throw errCode(new Error(messages.NOT_STARTED_YET), codes.DHT_NOT_STARTED);
        return this.dht.put(key2, value, options1);
    }
    /**
   * Get the value to the given key.
   * Times out after 1 minute by default.
   *
   * @param {Uint8Array} key
   * @param {Object} [options] - get options
   * @param {number} [options.timeout] - optional timeout (default: 60000)
   * @returns {Promise<GetData>}
   */ get(key3, options2) {
        if (!this.libp2p.isStarted() || !this.dht.isStarted) throw errCode(new Error(messages.NOT_STARTED_YET), codes.DHT_NOT_STARTED);
        return this.dht.get(key3, options2);
    }
    /**
   * Get the `n` values to the given key without sorting.
   *
   * @param {Uint8Array} key
   * @param {number} nVals
   * @param {Object} [options] - get options
   * @param {number} [options.timeout] - optional timeout (default: 60000)
   * @returns {Promise<GetData[]>}
   */ async getMany(key4, nVals, options3) {
        if (!this.libp2p.isStarted() || !this.dht.isStarted) throw errCode(new Error(messages.NOT_STARTED_YET), codes.DHT_NOT_STARTED);
        return this.dht.getMany(key4, nVals, options3);
    }
}
module.exports = ContentRouting;

},{"err-code":"eQvyh","../errors":"dO31S","./utils":"bXhXE","it-merge":"7iKAo","it-pipe":"4jukm"}],"8B3xC":[function(require,module,exports) {
'use strict';
const PeerId = require('peer-id');
const { Multiaddr  } = require('multiaddr');
const errCode = require('err-code');
const { codes  } = require('./errors');
/**
 * Converts the given `peer` to a `Peer` object.
 * If a multiaddr is received, the addressBook is updated.
 *
 * @param {PeerId|Multiaddr|string} peer
 * @returns {{ id: PeerId, multiaddrs: Multiaddr[]|undefined }}
 */ function getPeer(peer) {
    if (typeof peer === 'string') peer = new Multiaddr(peer);
    let addr;
    if (Multiaddr.isMultiaddr(peer)) {
        addr = peer;
        const idStr = peer.getPeerId();
        if (!idStr) throw errCode(new Error(`${peer} does not have a valid peer type`), codes.ERR_INVALID_MULTIADDR);
        try {
            peer = PeerId.createFromB58String(idStr);
        } catch (err) {
            throw errCode(new Error(`${peer} is not a valid peer type`), codes.ERR_INVALID_MULTIADDR);
        }
    }
    return {
        id: peer,
        multiaddrs: addr ? [
            addr
        ] : undefined
    };
}
module.exports = getPeer;

},{"peer-id":"4VGWt","multiaddr":"kOPrF","err-code":"eQvyh","./errors":"dO31S"}],"3Ycck":[function(require,module,exports) {
'use strict';
const mergeOptions = require('merge-options');
// @ts-ignore no types in multiaddr path
const { dnsaddrResolver  } = require('multiaddr/src/resolvers');
const Constants = require('./constants');
const { AGENT_VERSION  } = require('./identify/consts');
const RelayConstants = require('./circuit/constants');
const { publicAddressesFirst  } = require('libp2p-utils/src/address-sort');
const { FaultTolerance  } = require('./transport-manager');
/**
 * @typedef {import('multiaddr').Multiaddr} Multiaddr
 * @typedef {import('.').Libp2pOptions} Libp2pOptions
 * @typedef {import('.').constructorOptions} constructorOptions
 */ const DefaultConfig = {
    addresses: {
        listen: [],
        announce: [],
        noAnnounce: [],
        announceFilter: (/** @type {Multiaddr[]} */ multiaddrs)=>multiaddrs
    },
    connectionManager: {
        minConnections: 25
    },
    transportManager: {
        faultTolerance: FaultTolerance.FATAL_ALL
    },
    dialer: {
        maxParallelDials: Constants.MAX_PARALLEL_DIALS,
        maxDialsPerPeer: Constants.MAX_PER_PEER_DIALS,
        dialTimeout: Constants.DIAL_TIMEOUT,
        resolvers: {
            dnsaddr: dnsaddrResolver
        },
        addressSorter: publicAddressesFirst
    },
    host: {
        agentVersion: AGENT_VERSION
    },
    metrics: {
        enabled: false
    },
    peerStore: {
        persistence: false,
        threshold: 5
    },
    peerRouting: {
        refreshManager: {
            enabled: true,
            interval: 600000,
            bootDelay: 10000
        }
    },
    config: {
        protocolPrefix: 'ipfs',
        dht: {
            enabled: false,
            kBucketSize: 20,
            randomWalk: {
                enabled: false,
                queriesPerPeriod: 1,
                interval: 300000,
                timeout: 10000
            }
        },
        nat: {
            enabled: true,
            ttl: 7200,
            keepAlive: true,
            gateway: null,
            externalIp: null,
            pmp: {
                enabled: false
            }
        },
        peerDiscovery: {
            autoDial: true
        },
        pubsub: {
            enabled: true
        },
        relay: {
            enabled: true,
            advertise: {
                bootDelay: RelayConstants.ADVERTISE_BOOT_DELAY,
                enabled: false,
                ttl: RelayConstants.ADVERTISE_TTL
            },
            hop: {
                enabled: false,
                active: false
            },
            autoRelay: {
                enabled: false,
                maxListeners: 2
            }
        },
        transport: {
        }
    }
};
/**
 * @param {Libp2pOptions} opts
 * @returns {DefaultConfig & Libp2pOptions & constructorOptions}
 */ module.exports.validate = (opts)=>{
    /** @type {DefaultConfig & Libp2pOptions & constructorOptions} */ const resultingOptions = mergeOptions(DefaultConfig, opts);
    if (resultingOptions.modules.transport.length < 1) throw new Error("'options.modules.transport' must contain at least 1 transport");
    return resultingOptions;
};

},{"merge-options":"8VjFj","multiaddr/src/resolvers":"8Uumy","./constants":"7AgPB","./identify/consts":"5EOHd","./circuit/constants":"iivfC","libp2p-utils/src/address-sort":"glzi6","./transport-manager":"fdmmy"}],"8Uumy":[function(require,module,exports) {
'use strict';
const protocols = require('../protocols-table');
const { code: dnsaddrCode  } = protocols('dnsaddr');
/**
 * @typedef {import('..').Multiaddr} Multiaddr
 */ /**
 * Resolver for dnsaddr addresses.
 *
 * @param {Multiaddr} addr
 * @returns {Promise<string[]>}
 */ async function dnsaddrResolver(addr) {
    const Resolver = require('./dns');
    const resolver = new Resolver();
    const peerId = addr.getPeerId();
    const [, hostname] = addr.stringTuples().find(([proto])=>proto === dnsaddrCode
    ) || [];
    const records = await resolver.resolveTxt(`_dnsaddr.${hostname}`);
    let addresses = records.flat().map((a)=>a.split('=')[1]
    );
    if (peerId) addresses = addresses.filter((entry)=>entry.includes(peerId)
    );
    return addresses;
}
module.exports = {
    dnsaddrResolver
};

},{"../protocols-table":"5rCcx","./dns":"2gMCx"}],"2gMCx":[function(require,module,exports) {
'use strict';
/** @type {import('dns').promises.Resolver} */ // @ts-ignore - has no types
const dns = require('dns-over-http-resolver');
module.exports = dns;

},{"dns-over-http-resolver":"iGBMq"}],"iGBMq":[function(require,module,exports) {
'use strict';
const debug = require('debug');
const log = debug('dns-over-http-resolver');
log.error = debug('dns-over-http-resolver:error');
const Receptacle = require('receptacle');
const utils = require('./utils');
/**
 * DNS over HTTP resolver.
 * Uses a list of servers to resolve DNS records with HTTP requests.
 */ class Resolver {
    /**
   * @class
   * @param {object} [properties]
   * @param {number} [properties.maxCache = 100] - maximum number of cached dns records.
   */ constructor({ maxCache =100  } = {
    }){
        this._cache = new Receptacle({
            max: maxCache
        });
        this._servers = [
            'https://cloudflare-dns.com/dns-query',
            'https://dns.google/resolve'
        ];
    }
    /**
   * Get an array of the IP addresses currently configured for DNS resolution.
   * These addresses are formatted according to RFC 5952. It can include a custom port.
   *
   * @returns {Array<string>}
   */ getServers() {
        return this._servers;
    }
    /**
   * Get a shuffled array of the IP addresses currently configured for DNS resolution.
   * These addresses are formatted according to RFC 5952. It can include a custom port.
   *
   * @returns {Array<string>}
   */ _getShuffledServers() {
        const newServers = [].concat(this._servers);
        for(let i = newServers.length - 1; i > 0; i--){
            const j = Math.floor(Math.random() * i);
            const temp = newServers[i];
            newServers[i] = newServers[j];
            newServers[j] = temp;
        }
        return newServers;
    }
    /**
   * Sets the IP address and port of servers to be used when performing DNS resolution.
   *
   * @param {Array<string>} servers - array of RFC 5952 formatted addresses.
   */ setServers(servers) {
        this._servers = servers;
    }
    /**
   * Uses the DNS protocol to resolve the given host name into the appropriate DNS record.
   *
   * @param {string} hostname - host name to resolve.
   * @param {string} [rrType = 'A'] - resource record type.
   * @returns {Promise<*>}
   */ resolve(hostname, rrType = 'A') {
        switch(rrType){
            case 'A':
                return this.resolve4(hostname);
            case 'AAAA':
                return this.resolve6(hostname);
            case 'TXT':
                return this.resolveTxt(hostname);
            default:
                throw new Error(`${rrType} is not supported`);
        }
    }
    /**
   * Uses the DNS protocol to resolve the given host name into IPv4 addresses.
   *
   * @param {string} hostname - host name to resolve.
   * @returns {Promise<Array<string>>}
   */ async resolve4(hostname1) {
        const recordType = 'A';
        const cached = this._cache.get(utils.getCacheKey(hostname1, recordType));
        if (cached) return cached;
        for (const server of this._getShuffledServers())try {
            const response = await utils.fetch(utils.buildResource({
                serverResolver: server,
                hostname: hostname1,
                recordType
            }));
            const d = await response.json();
            const data = d.Answer.map((a)=>a.data
            );
            const ttl = Math.min(d.Answer.map((a)=>a.TTL
            ));
            this._cache.set(utils.getCacheKey(hostname1, recordType), data, {
                ttl
            });
            return data;
        } catch (err) {
            log.error(`${server} could not resolve ${hostname1} record ${recordType}`);
        }
        throw new Error(`Could not resolve ${hostname1} record ${recordType}`);
    }
    /**
   * Uses the DNS protocol to resolve the given host name into IPv6 addresses.
   *
   * @param {string} hostname - host name to resolve.
   * @returns {Promise<Array<string>>}
   */ async resolve6(hostname2) {
        const recordType = 'AAAA';
        const cached = this._cache.get(utils.getCacheKey(hostname2, recordType));
        if (cached) return cached;
        for (const server of this._getShuffledServers())try {
            const response = await utils.fetch(utils.buildResource({
                serverResolver: server,
                hostname: hostname2,
                recordType
            }));
            const d = await response.json();
            const data = d.Answer.map((a)=>a.data
            );
            const ttl = Math.min(d.Answer.map((a)=>a.TTL
            ));
            this._cache.set(utils.getCacheKey(hostname2, recordType), data, {
                ttl
            });
            return data;
        } catch (err) {
            log.error(`${server} could not resolve ${hostname2} record ${recordType}`);
        }
        throw new Error(`Could not resolve ${hostname2} record ${recordType}`);
    }
    /**
   * Uses the DNS protocol to resolve the given host name into a Text record.
   *
   * @param {string} hostname - host name to resolve.
   * @returns {Promise<Array<Array<string>>>}
   */ async resolveTxt(hostname3) {
        const recordType = 'TXT';
        const cached = this._cache.get(utils.getCacheKey(hostname3, recordType));
        if (cached) return cached;
        for (const server of this._getShuffledServers())try {
            const response = await utils.fetch(utils.buildResource({
                serverResolver: server,
                hostname: hostname3,
                recordType
            }));
            const d = await response.json();
            const data = d.Answer.map((a)=>[
                    a.data.replace(/['"]+/g, '')
                ]
            );
            const ttl = Math.min(d.Answer.map((a)=>a.TTL
            ));
            this._cache.set(utils.getCacheKey(hostname3, recordType), data, {
                ttl
            });
            return data;
        } catch (err) {
            log.error(`${server} could not resolve ${hostname3} record ${recordType}`);
        }
        throw new Error(`Could not resolve ${hostname3} record ${recordType}`);
    }
}
Resolver.Resolver = Resolver;
module.exports = Resolver;

},{"debug":"lWlU4","receptacle":"9I01w","./utils":"dQapU"}],"9I01w":[function(require,module,exports) {
'use strict';
module.exports = Receptacle;
var toMS = require('ms');
var cache = Receptacle.prototype;
var counter = new Date() % 1000000000;
function getUID() {
    return (Math.random() * 1000000000 >>> 0) + counter++;
}
/**
 * Creates a cache with a maximum key size.
 *
 * @constructor
 * @param {Object} options
 * @param {Number} [options.max=Infinity] the maximum number of keys allowed in the cache (lru).
 * @param {Array} [options.items=[]] the default items in the cache.
 */ function Receptacle(options) {
    options = options || {
    };
    this.id = options.id || getUID();
    this.max = options.max || Infinity;
    this.items = options.items || [];
    this._lookup = {
    };
    this.size = this.items.length;
    this.lastModified = new Date(options.lastModified || new Date());
    // Setup initial timers and indexes for the cache.
    for(var item, ttl, i = this.items.length; i--;){
        item = this.items[i];
        ttl = new Date(item.expires) - new Date();
        this._lookup[item.key] = item;
        if (ttl > 0) this.expire(item.key, ttl);
        else if (ttl <= 0) this.delete(item.key);
    }
}
/**
 * Tests if a key is currently in the cache.
 * Does not check if slot is empty.
 *
 * @param {String} key - the key to retrieve from the cache.
 * @return {Boolean}
 */ cache.has = function(key) {
    return key in this._lookup;
};
/**
 * Retrieves a key from the cache and marks it as recently used.
 *
 * @param {String} key - the key to retrieve from the cache.
 * @return {*}
 */ cache.get = function(key) {
    if (!this.has(key)) return null;
    var record = this._lookup[key];
    // Update expiry for "refresh" keys
    if (record.refresh) this.expire(key, record.refresh);
    // Move to front of the line.
    this.items.splice(this.items.indexOf(record), 1);
    this.items.push(record);
    return record.value;
};
/**
 * Retrieves user meta data for a cached item.
 *
 * @param {String} key - the key to retrieve meta data from the cache.
 * @return {*}
 */ cache.meta = function(key) {
    if (!this.has(key)) return null;
    var record = this._lookup[key];
    if (!('meta' in record)) return null;
    return record.meta;
};
/**
 * Puts a key into the cache with an optional expiry time.
 *
 * @param {String} key - the key for the value in the cache.
 * @param {*} value - the value to place at the key.
 * @param {Number} [options.ttl] - a time after which the key will be removed.
 * @return {Receptacle}
 */ cache.set = function(key, value, options) {
    var oldRecord = this._lookup[key];
    var record = this._lookup[key] = {
        key: key,
        value: value
    };
    // Mark cache as modified.
    this.lastModified = new Date();
    if (oldRecord) {
        // Replace an old key.
        clearTimeout(oldRecord.timeout);
        this.items.splice(this.items.indexOf(oldRecord), 1, record);
    } else {
        // Remove least used item if needed.
        if (this.size >= this.max) this.delete(this.items[0].key);
        // Add a new key.
        this.items.push(record);
        this.size++;
    }
    if (options) {
        // Setup key expiry.
        if ('ttl' in options) this.expire(key, options.ttl);
        // Store user options in the record.
        if ('meta' in options) record.meta = options.meta;
        // Mark a auto refresh key.
        if (options.refresh) record.refresh = options.ttl;
    }
    return this;
};
/**
 * Deletes an item from the cache.
 *
 * @param {String} key - the key to remove.
 * @return {Receptacle}
 */ cache.delete = function(key) {
    var record = this._lookup[key];
    if (!record) return false;
    this.lastModified = new Date();
    this.items.splice(this.items.indexOf(record), 1);
    clearTimeout(record.timeout);
    delete this._lookup[key];
    this.size--;
    return this;
};
/**
 * Utility to register a key that will be removed after some time.
 *
 * @param {String} key - the key to remove.
 * @param {Number} [ms] - the timeout before removal.
 * @return {Receptacle}
 */ cache.expire = function(key, ttl) {
    var ms = ttl || 0;
    var record = this._lookup[key];
    if (!record) return this;
    if (typeof ms === 'string') ms = toMS(ttl);
    if (typeof ms !== 'number') throw new TypeError('Expiration time must be a string or number.');
    clearTimeout(record.timeout);
    record.timeout = setTimeout(this.delete.bind(this, record.key), ms);
    record.expires = Number(new Date()) + ms;
    return this;
};
/**
 * Deletes all items from the cache.
 * @return {Receptacle}
 */ cache.clear = function() {
    for(var i = this.items.length; i--;)this.delete(this.items[i].key);
    return this;
};
/**
 * Fixes serialization issues in polyfilled environments.
 * Ensures non-cyclical serialized object.
 */ cache.toJSON = function() {
    var items = new Array(this.items.length);
    var item;
    for(var i = items.length; i--;){
        item = this.items[i];
        items[i] = {
            key: item.key,
            meta: item.meta,
            value: item.value,
            expires: item.expires,
            refresh: item.refresh
        };
    }
    return {
        id: this.id,
        max: isFinite(this.max) ? this.max : undefined,
        lastModified: this.lastModified,
        items: items
    };
};

},{"ms":"f1SVb"}],"f1SVb":[function(require,module,exports) {
/**
 * Helpers.
 */ var s = 1000;
var m = s * 60;
var h = m * 60;
var d = h * 24;
var w = d * 7;
var y = d * 365.25;
/**
 * Parse or format the given `val`.
 *
 * Options:
 *
 *  - `long` verbose formatting [false]
 *
 * @param {String|Number} val
 * @param {Object} [options]
 * @throws {Error} throw an error if val is not a non-empty string or a number
 * @return {String|Number}
 * @api public
 */ module.exports = function(val, options) {
    options = options || {
    };
    var type = typeof val;
    if (type === 'string' && val.length > 0) return parse(val);
    else if (type === 'number' && isFinite(val)) return options.long ? fmtLong(val) : fmtShort(val);
    throw new Error('val is not a non-empty string or a valid number. val=' + JSON.stringify(val));
};
/**
 * Parse the given `str` and return milliseconds.
 *
 * @param {String} str
 * @return {Number}
 * @api private
 */ function parse(str) {
    str = String(str);
    if (str.length > 100) return;
    var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(str);
    if (!match) return;
    var n = parseFloat(match[1]);
    var type = (match[2] || 'ms').toLowerCase();
    switch(type){
        case 'years':
        case 'year':
        case 'yrs':
        case 'yr':
        case 'y':
            return n * y;
        case 'weeks':
        case 'week':
        case 'w':
            return n * w;
        case 'days':
        case 'day':
        case 'd':
            return n * d;
        case 'hours':
        case 'hour':
        case 'hrs':
        case 'hr':
        case 'h':
            return n * h;
        case 'minutes':
        case 'minute':
        case 'mins':
        case 'min':
        case 'm':
            return n * m;
        case 'seconds':
        case 'second':
        case 'secs':
        case 'sec':
        case 's':
            return n * s;
        case 'milliseconds':
        case 'millisecond':
        case 'msecs':
        case 'msec':
        case 'ms':
            return n;
        default:
            return undefined;
    }
}
/**
 * Short format for `ms`.
 *
 * @param {Number} ms
 * @return {String}
 * @api private
 */ function fmtShort(ms) {
    var msAbs = Math.abs(ms);
    if (msAbs >= d) return Math.round(ms / d) + 'd';
    if (msAbs >= h) return Math.round(ms / h) + 'h';
    if (msAbs >= m) return Math.round(ms / m) + 'm';
    if (msAbs >= s) return Math.round(ms / s) + 's';
    return ms + 'ms';
}
/**
 * Long format for `ms`.
 *
 * @param {Number} ms
 * @return {String}
 * @api private
 */ function fmtLong(ms) {
    var msAbs = Math.abs(ms);
    if (msAbs >= d) return plural(ms, msAbs, d, 'day');
    if (msAbs >= h) return plural(ms, msAbs, h, 'hour');
    if (msAbs >= m) return plural(ms, msAbs, m, 'minute');
    if (msAbs >= s) return plural(ms, msAbs, s, 'second');
    return ms + ' ms';
}
/**
 * Pluralization helper.
 */ function plural(ms, msAbs, n, name) {
    var isPlural = msAbs >= n * 1.5;
    return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');
}

},{}],"dQapU":[function(require,module,exports) {
'use strict';
const { default: nativeFetch , Headers  } = require('native-fetch');
/**
 * Build fetch resource for request.
 *
 * @param {object} properties
 * @param {string} properties.serverResolver
 * @param {string} properties.hostname
 * @param {string} properties.recordType
 * @returns {string}
 */ function buildResource({ serverResolver , hostname , recordType  }) {
    return `${serverResolver}?name=${hostname}&type=${recordType}`;
}
/**
 * Use fetch to find the record.
 *
 * @param {object} resource
 * @returns {Promise}
 */ function fetch(resource) {
    return nativeFetch(resource, {
        headers: new Headers({
            accept: 'application/dns-json'
        })
    });
}
/**
 * Creates cache key composed by recordType and hostname.
 *
 * @param {string} hostname
 * @param {string} recordType
 * @returns {string}
 */ function getCacheKey(hostname, recordType) {
    return `${recordType}_${hostname}`;
}
module.exports = {
    buildResource,
    fetch,
    getCacheKey
};

},{"native-fetch":"h5XVM"}],"7AgPB":[function(require,module,exports) {
'use strict';
module.exports = {
    DIAL_TIMEOUT: 30000,
    MAX_PARALLEL_DIALS: 100,
    MAX_PER_PEER_DIALS: 4,
    MAX_ADDRS_TO_DIAL: 25,
    METRICS: {
        computeThrottleMaxQueueSize: 1000,
        computeThrottleTimeout: 2000,
        movingAverageIntervals: [
            60000,
            300000,
            900000 // 15 minutes
        ],
        maxOldPeersRetention: 50
    }
};

},{}],"5EOHd":[function(require,module,exports) {
'use strict';
// @ts-ignore file not listed within the file list of projects
const libp2pVersion = require('../../package.json').version;
module.exports.PROTOCOL_VERSION = 'ipfs/0.1.0' // deprecated
;
module.exports.AGENT_VERSION = `js-libp2p/${libp2pVersion}`;
module.exports.MULTICODEC_IDENTIFY = '/ipfs/id/1.0.0' // deprecated
;
module.exports.MULTICODEC_IDENTIFY_PUSH = '/ipfs/id/push/1.0.0' // deprecated
;
module.exports.IDENTIFY_PROTOCOL_VERSION = '0.1.0';
module.exports.MULTICODEC_IDENTIFY_PROTOCOL_NAME = 'id';
module.exports.MULTICODEC_IDENTIFY_PUSH_PROTOCOL_NAME = 'id/push';
module.exports.MULTICODEC_IDENTIFY_PROTOCOL_VERSION = '1.0.0';
module.exports.MULTICODEC_IDENTIFY_PUSH_PROTOCOL_VERSION = '1.0.0';

},{"../../package.json":"cz6QZ"}],"cz6QZ":[function(require,module,exports) {
module.exports = JSON.parse("{\"name\":\"libp2p\",\"version\":\"0.33.0\",\"description\":\"JavaScript implementation of libp2p, a modular peer to peer network stack\",\"leadMaintainer\":\"Jacob Heun <jacobheun@gmail.com>\",\"main\":\"src/index.js\",\"types\":\"dist/src/index.d.ts\",\"typesVersions\":{\"*\":{\"src/*\":[\"dist/src/*\",\"dist/src/*/index\"]}},\"files\":[\"dist\",\"src\"],\"scripts\":{\"lint\":\"aegir lint\",\"build\":\"aegir build\",\"build:proto\":\"npm run build:proto:circuit && npm run build:proto:identify && npm run build:proto:plaintext && npm run build:proto:address-book && npm run build:proto:proto-book && npm run build:proto:peer-record && npm run build:proto:envelope\",\"build:proto:circuit\":\"pbjs -t static-module -w commonjs -r libp2p-circuit --force-number --no-verify --no-delimited --no-create --no-beautify --no-defaults --lint eslint-disable -o src/circuit/protocol/index.js ./src/circuit/protocol/index.proto\",\"build:proto:identify\":\"pbjs -t static-module -w commonjs -r libp2p-identify --force-number --no-verify --no-delimited --no-create --no-beautify --no-defaults --lint eslint-disable -o src/identify/message.js ./src/identify/message.proto\",\"build:proto:plaintext\":\"pbjs -t static-module -w commonjs -r libp2p-plaintext --force-number --no-verify --no-delimited --no-create --no-beautify --no-defaults --lint eslint-disable -o src/insecure/proto.js ./src/insecure/proto.proto\",\"build:proto:address-book\":\"pbjs -t static-module -w commonjs -r libp2p-address-book --force-number --no-verify --no-delimited --no-create --no-beautify --no-defaults --lint eslint-disable -o src/peer-store/persistent/pb/address-book.js ./src/peer-store/persistent/pb/address-book.proto\",\"build:proto:proto-book\":\"pbjs -t static-module -w commonjs -r libp2p-proto-book --force-number --no-verify --no-delimited --no-create --no-beautify --no-defaults --lint eslint-disable -o src/peer-store/persistent/pb/proto-book.js ./src/peer-store/persistent/pb/proto-book.proto\",\"build:proto:peer-record\":\"pbjs -t static-module -w commonjs -r libp2p-peer-record --force-number --no-verify --no-delimited --no-create --no-beautify --no-defaults --lint eslint-disable -o src/record/peer-record/peer-record.js ./src/record/peer-record/peer-record.proto\",\"build:proto:envelope\":\"pbjs -t static-module -w commonjs -r libp2p-envelope --force-number --no-verify --no-delimited --no-create --no-beautify --no-defaults --lint eslint-disable -o src/record/envelope/envelope.js ./src/record/envelope/envelope.proto\",\"build:proto-types\":\"npm run build:proto-types:circuit && npm run build:proto-types:identify && npm run build:proto-types:plaintext && npm run build:proto-types:address-book && npm run build:proto-types:proto-book && npm run build:proto-types:peer-record && npm run build:proto-types:envelope\",\"build:proto-types:circuit\":\"pbts -o src/circuit/protocol/index.d.ts src/circuit/protocol/index.js\",\"build:proto-types:identify\":\"pbts -o src/identify/message.d.ts src/identify/message.js\",\"build:proto-types:plaintext\":\"pbts -o src/insecure/proto.d.ts src/insecure/proto.js\",\"build:proto-types:address-book\":\"pbts -o src/peer-store/persistent/pb/address-book.d.ts src/peer-store/persistent/pb/address-book.js\",\"build:proto-types:proto-book\":\"pbts -o src/peer-store/persistent/pb/proto-book.d.ts src/peer-store/persistent/pb/proto-book.js\",\"build:proto-types:peer-record\":\"pbts -o src/record/peer-record/peer-record.d.ts src/record/peer-record/peer-record.js\",\"build:proto-types:envelope\":\"pbts -o src/record/envelope/envelope.d.ts src/record/envelope/envelope.js\",\"test\":\"aegir test\",\"test:ts\":\"aegir build --no-bundle && npm run test --prefix test/ts-use\",\"test:node\":\"aegir test -t node -f \\\"./test/**/*.{node,spec}.js\\\"\",\"test:browser\":\"aegir test -t browser\",\"test:examples\":\"cd examples && npm run test:all\",\"prepare\":\"aegir build --no-bundle\",\"release\":\"aegir release -t node -t browser\",\"release-minor\":\"aegir release --type minor -t node -t browser\",\"release-major\":\"aegir release --type major -t node -t browser\",\"coverage\":\"nyc --reporter=text --reporter=lcov npm run test:node\"},\"repository\":{\"type\":\"git\",\"url\":\"https://github.com/libp2p/js-libp2p.git\"},\"keywords\":[\"libp2p\",\"network\",\"p2p\",\"peer\",\"peer-to-peer\",\"IPFS\"],\"bugs\":{\"url\":\"https://github.com/libp2p/js-libp2p/issues\"},\"homepage\":\"https://libp2p.io\",\"license\":\"MIT\",\"engines\":{\"node\":\">=14.0.0\"},\"browser\":{\"@motrix/nat-api\":false},\"eslintConfig\":{\"extends\":\"ipfs\",\"ignorePatterns\":[\"!.aegir.js\",\"test/ts-use\"]},\"dependencies\":{\"abortable-iterator\":\"^3.0.0\",\"@motrix/nat-api\":\"^0.3.1\",\"@vascosantos/moving-average\":\"^1.1.0\",\"abort-controller\":\"^3.0.0\",\"aggregate-error\":\"^3.1.0\",\"any-signal\":\"^2.1.1\",\"bignumber.js\":\"^9.0.1\",\"class-is\":\"^1.1.0\",\"debug\":\"^4.3.1\",\"err-code\":\"^3.0.0\",\"es6-promisify\":\"^7.0.0\",\"events\":\"^3.3.0\",\"hashlru\":\"^2.3.0\",\"interface-datastore\":\"^6.0.2\",\"it-all\":\"^1.0.4\",\"it-buffer\":\"^0.1.2\",\"it-drain\":\"^1.0.3\",\"it-filter\":\"^1.0.1\",\"it-first\":\"^1.0.4\",\"it-handshake\":\"^2.0.0\",\"it-length-prefixed\":\"^5.0.2\",\"it-map\":\"^1.0.4\",\"it-merge\":\"^1.0.0\",\"it-pipe\":\"^1.1.0\",\"it-take\":\"^1.0.0\",\"libp2p-crypto\":\"^0.19.4\",\"libp2p-interfaces\":\"^1.0.0\",\"libp2p-utils\":\"^0.4.0\",\"mafmt\":\"^10.0.0\",\"merge-options\":\"^3.0.4\",\"multiaddr\":\"^10.0.0\",\"multiformats\":\"^9.0.0\",\"multistream-select\":\"^2.0.0\",\"mutable-proxy\":\"^1.0.0\",\"node-forge\":\"^0.10.0\",\"p-any\":\"^3.0.0\",\"p-fifo\":\"^1.0.0\",\"p-retry\":\"^4.4.0\",\"p-settle\":\"^4.1.1\",\"peer-id\":\"^0.15.0\",\"private-ip\":\"^2.1.0\",\"protobufjs\":\"^6.10.2\",\"retimer\":\"^3.0.0\",\"sanitize-filename\":\"^1.6.3\",\"set-delayed-interval\":\"^1.0.0\",\"streaming-iterables\":\"^6.0.0\",\"timeout-abort-controller\":\"^1.1.1\",\"uint8arrays\":\"^3.0.0\",\"varint\":\"^6.0.0\",\"wherearewe\":\"^1.0.0\",\"xsalsa20\":\"^1.1.0\"},\"devDependencies\":{\"@chainsafe/libp2p-noise\":\"^4.0.0\",\"@nodeutils/defaults-deep\":\"^1.1.0\",\"@types/es6-promisify\":\"^6.0.0\",\"@types/node\":\"^16.0.1\",\"@types/node-forge\":\"^0.10.1\",\"@types/varint\":\"^6.0.0\",\"aegir\":\"^33.1.1\",\"buffer\":\"^6.0.3\",\"datastore-core\":\"^6.0.7\",\"delay\":\"^5.0.0\",\"interop-libp2p\":\"^0.4.0\",\"into-stream\":\"^7.0.0\",\"ipfs-http-client\":\"^52.0.2\",\"it-concat\":\"^2.0.0\",\"it-pair\":\"^1.0.0\",\"it-pushable\":\"^1.4.0\",\"libp2p\":\".\",\"libp2p-bootstrap\":\"^0.13.0\",\"libp2p-delegated-content-routing\":\"^0.11.0\",\"libp2p-delegated-peer-routing\":\"^0.10.0\",\"libp2p-floodsub\":\"^0.27.0\",\"libp2p-gossipsub\":\"^0.11.0\",\"libp2p-interfaces-compliance-tests\":\"^1.0.0\",\"libp2p-kad-dht\":\"^0.24.2\",\"libp2p-mdns\":\"^0.17.0\",\"libp2p-mplex\":\"^0.10.1\",\"libp2p-tcp\":\"^0.17.0\",\"libp2p-webrtc-star\":\"^0.23.0\",\"libp2p-websockets\":\"^0.16.0\",\"nock\":\"^13.0.3\",\"p-defer\":\"^3.0.0\",\"p-times\":\"^3.0.0\",\"p-wait-for\":\"^3.2.0\",\"rimraf\":\"^3.0.2\",\"sinon\":\"^11.1.1\",\"util\":\"^0.12.3\"},\"contributors\":[\"Vasco Santos <vasco.santos@moxy.studio>\",\"David Dias <daviddias.p@gmail.com>\",\"Jacob Heun <jacobheun@gmail.com>\",\"Alex Potsides <alex@achingbrain.net>\",\"Alan Shaw <alan@tableflip.io>\",\"Cayman <caymannava@gmail.com>\",\"Pedro Teixeira <i@pgte.me>\",\"Friedel Ziegelmayer <dignifiedquire@gmail.com>\",\"Maciej Krüger <mkg20001@gmail.com>\",\"Hugo Dias <mail@hugodias.me>\",\"Chris Dostert <chrisdostert@users.noreply.github.com>\",\"dirkmc <dirkmdev@gmail.com>\",\"Volker Mische <volker.mische@gmail.com>\",\"zeim839 <50573884+zeim839@users.noreply.github.com>\",\"Richard Littauer <richard.littauer@gmail.com>\",\"a1300 <matthias-knopp@gmx.net>\",\"Ryan Bell <ryan@piing.net>\",\"ᴠɪᴄᴛᴏʀ ʙᴊᴇʟᴋʜᴏʟᴍ <victorbjelkholm@gmail.com>\",\"Franck Royer <franck@royer.one>\",\"Thomas Eizinger <thomas@eizinger.io>\",\"Giovanni T. Parra <fiatjaf@gmail.com>\",\"acolytec3 <17355484+acolytec3@users.noreply.github.com>\",\"Elven <mon.samuel@qq.com>\",\"Andrew Nesbitt <andrewnez@gmail.com>\",\"Samlior <samlior@foxmail.com>\",\"Didrik Nordström <didrik.nordstrom@gmail.com>\",\"RasmusErik Voel Jensen <github@solsort.com>\",\"Robert Kiel <robert.kiel@hoprnet.org>\",\"Smite Chow <xiaopengyou@live.com>\",\"Soeren <nikorpoulsen@gmail.com>\",\"Sönke Hahn <soenkehahn@gmail.com>\",\"TJKoury <TJKoury@gmail.com>\",\"Tiago Alves <alvesjtiago@gmail.com>\",\"XiaoZhang <zxinmyth@gmail.com>\",\"Yusef Napora <yusef@napora.org>\",\"Zane Starr <zcstarr@gmail.com>\",\"ebinks <elizabethjbinks@gmail.com>\",\"Aditya Bose <13054902+adbose@users.noreply.github.com>\",\"isan_rivkin <isanrivkin@gmail.com>\",\"mayerwin <mayerwin@users.noreply.github.com>\",\"mcclure <andi.m.mcclure@gmail.com>\",\"phillmac <phillmac@users.noreply.github.com>\",\"robertkiel <robert.kiel@validitylabs.org>\",\"shresthagrawal <34920931+shresthagrawal@users.noreply.github.com>\",\"swedneck <40505480+swedneck@users.noreply.github.com>\",\"greenSnot <greenSnot@users.noreply.github.com>\",\"Aleksei <vozhdb@gmail.com>\",\"Bernd Strehl <bernd.strehl@gmail.com>\",\"Chris Bratlien <chrisbratlien@gmail.com>\",\"Cindy Wu <ciindy.wu@gmail.com>\",\"Daijiro Wachi <daijiro.wachi@gmail.com>\",\"Diogo Silva <fsdiogo@gmail.com>\",\"Dmitriy Ryajov <dryajov@gmail.com>\",\"Ethan Lam <elmemphis2000@gmail.com>\",\"Fei Liu <liu.feiwood@gmail.com>\",\"Felipe Martins <felipebrasil93@gmail.com>\",\"Florian-Merle <florian.david.merle@gmail.com>\",\"Francis Gulotta <wizard@roborooter.com>\",\"Guy Sviry <32539816+guysv@users.noreply.github.com>\",\"Henrique Dias <hacdias@gmail.com>\",\"Irakli Gozalishvili <rfobic@gmail.com>\",\"Joel Gustafson <joelg@mit.edu>\",\"John Rees <johnrees@users.noreply.github.com>\",\"João Santos <joaosantos15@users.noreply.github.com>\",\"Julien Bouquillon <contact@revolunet.com>\",\"Kevin Kwok <antimatter15@gmail.com>\",\"Kevin Lacker <lacker@gmail.com>\",\"Lars Gierth <lgierth@users.noreply.github.com>\",\"Leask Wong <i@leaskh.com>\",\"Marcin Tojek <mtojek@users.noreply.github.com>\",\"Michael Burns <5170+mburns@users.noreply.github.com>\",\"Miguel Mota <miguelmota2@gmail.com>\",\"Nuno Nogueira <nunofmn@gmail.com>\",\"Philipp Muens <raute1337@gmx.de>\"]}");

},{}],"iivfC":[function(require,module,exports) {
'use strict';
const minute = 60000;
module.exports = {
    ADVERTISE_BOOT_DELAY: 15 * minute,
    ADVERTISE_TTL: 30 * minute,
    CIRCUIT_PROTO_CODE: 290,
    HOP_METADATA_KEY: 'hop_relay',
    HOP_METADATA_VALUE: 'true',
    RELAY_RENDEZVOUS_NS: '/libp2p/relay' // Relay HOP relay service namespace for discovery
};

},{}],"glzi6":[function(require,module,exports) {
'use strict';
const isPrivate = require('./multiaddr/is-private');
/**
 * @typedef {import('multiaddr').Multiaddr} Multiaddr
 */ /**
 * @typedef {Object} Address
 * @property {Multiaddr} multiaddr peer multiaddr.
 * @property {boolean} isCertified obtained from a signed peer record.
 */ /**
 * Compare function for array.sort().
 * This sort aims to move the private adresses to the end of the array.
 * In case of equality, a certified address will come first.
 *
 * @param {Address} a
 * @param {Address} b
 * @returns {number}
 */ function addressesPublicFirstCompareFunction(a, b) {
    const isAPrivate = isPrivate(a.multiaddr);
    const isBPrivate = isPrivate(b.multiaddr);
    if (isAPrivate && !isBPrivate) return 1;
    else if (!isAPrivate && isBPrivate) return -1;
    // Check certified?
    if (a.isCertified && !b.isCertified) return -1;
    else if (!a.isCertified && b.isCertified) return 1;
    return 0;
}
/**
 * Sort given addresses by putting public addresses first.
 * In case of equality, a certified address will come first.
 *
 * @param {Array<Address>} addresses
 * @returns {Array<Address>}
 */ function publicAddressesFirst(addresses) {
    return [
        ...addresses
    ].sort(addressesPublicFirstCompareFunction);
}
module.exports.publicAddressesFirst = publicAddressesFirst;

},{"./multiaddr/is-private":"c7QoZ"}],"c7QoZ":[function(require,module,exports) {
'use strict';
// @ts-ignore private-ip does not publish types
const isIpPrivate = require('private-ip');
/**
 * @typedef {import('multiaddr').Multiaddr} Multiaddr
 */ /**
 * Check if a given multiaddr has a private address.
 *
 * @param {Multiaddr} ma
 * @returns {boolean}
 */ function isPrivate(ma) {
    const { address  } = ma.nodeAddress();
    return isIpPrivate(address);
}
module.exports = isPrivate;

},{"private-ip":"4BzE5"}],"4BzE5":[function(require,module,exports) {
'use strict';
module.exports = require('./lib').default;

},{"./lib":"j4Gwq"}],"j4Gwq":[function(require,module,exports) {
"use strict";
var __importDefault = this && this.__importDefault || function(mod) {
    return mod && mod.__esModule ? mod : {
        "default": mod
    };
};
Object.defineProperty(exports, "__esModule", {
    value: true
});
const netmask_1 = require("netmask");
const ip_regex_1 = __importDefault(require("ip-regex"));
const is_ip_1 = __importDefault(require("is-ip"));
const ipaddr_js_1 = require("ipaddr.js");
const PRIVATE_IP_RANGES = [
    '0.0.0.0/8',
    '10.0.0.0/8',
    '100.64.0.0/10',
    '127.0.0.0/8',
    '169.254.0.0/16',
    '172.16.0.0/12',
    '192.0.0.0/24',
    '192.0.0.0/29',
    '192.0.0.8/32',
    '192.0.0.9/32',
    '192.0.0.10/32',
    '192.0.0.170/32',
    '192.0.0.171/32',
    '192.0.2.0/24',
    '192.31.196.0/24',
    '192.52.193.0/24',
    '192.88.99.0/24',
    '192.168.0.0/16',
    '192.175.48.0/24',
    '198.18.0.0/15',
    '198.51.100.0/24',
    '203.0.113.0/24',
    '240.0.0.0/4',
    '255.255.255.255/32'
];
const NETMASK_RANGES = PRIVATE_IP_RANGES.map((ip_range)=>new netmask_1.Netmask(ip_range)
);
function ipv4_check(ip_addr) {
    for (let r of NETMASK_RANGES){
        if (r.contains(ip_addr)) return true;
    }
    return false;
}
function ipv6_check(ip_addr) {
    return /^::$/.test(ip_addr) || /^::1$/.test(ip_addr) || /^::f{4}:([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/.test(ip_addr) || /^::f{4}:0.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/.test(ip_addr) || /^64:ff9b::([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/.test(ip_addr) || /^100::([0-9a-fA-F]{0,4}):?([0-9a-fA-F]{0,4}):?([0-9a-fA-F]{0,4}):?([0-9a-fA-F]{0,4})$/.test(ip_addr) || /^2001::([0-9a-fA-F]{0,4}):?([0-9a-fA-F]{0,4}):?([0-9a-fA-F]{0,4}):?([0-9a-fA-F]{0,4}):?([0-9a-fA-F]{0,4}):?([0-9a-fA-F]{0,4})$/.test(ip_addr) || /^2001:2[0-9a-fA-F]:([0-9a-fA-F]{0,4}):?([0-9a-fA-F]{0,4}):?([0-9a-fA-F]{0,4}):?([0-9a-fA-F]{0,4}):?([0-9a-fA-F]{0,4}):?([0-9a-fA-F]{0,4})$/.test(ip_addr) || /^2001:db8:([0-9a-fA-F]{0,4}):?([0-9a-fA-F]{0,4}):?([0-9a-fA-F]{0,4}):?([0-9a-fA-F]{0,4}):?([0-9a-fA-F]{0,4}):?([0-9a-fA-F]{0,4})$/.test(ip_addr) || /^2002:([0-9a-fA-F]{0,4}):?([0-9a-fA-F]{0,4}):?([0-9a-fA-F]{0,4}):?([0-9a-fA-F]{0,4}):?([0-9a-fA-F]{0,4}):?([0-9a-fA-F]{0,4}):?([0-9a-fA-F]{0,4})$/.test(ip_addr) || /^f[c-d]([0-9a-fA-F]{2,2}):/i.test(ip_addr) || /^fe[8-9a-bA-B][0-9a-fA-F]:/i.test(ip_addr) || /^ff([0-9a-fA-F]{2,2}):/i.test(ip_addr);
}
exports.default = (ip)=>{
    if (ipaddr_js_1.isValid(ip)) {
        const parsed = ipaddr_js_1.parse(ip);
        if (parsed.kind() === 'ipv4') return ipv4_check(parsed.toNormalizedString());
        else if (parsed.kind() === 'ipv6') return ipv6_check(ip);
    } else if (is_ip_1.default(ip) && ip_regex_1.default.v6().test(ip)) return ipv6_check(ip);
    return undefined;
};

},{"netmask":"kxkKy","ip-regex":"36RLZ","is-ip":"fEoXA","ipaddr.js":"jgj5T"}],"kxkKy":[function(require,module,exports) {
// Generated by CoffeeScript 1.12.7
(function() {
    var Netmask1, atob, chr, chr0, chrA, chra, ip2long, long2ip;
    long2ip = function(long) {
        var a, b, c, d;
        a = (long & -16777216) >>> 24;
        b = (long & 16711680) >>> 16;
        c = (long & 65280) >>> 8;
        d = long & 255;
        return [
            a,
            b,
            c,
            d
        ].join('.');
    };
    ip2long = function(ip) {
        var b, c, i, j, n, ref;
        b = [];
        for(i = j = 0; j <= 3; i = ++j){
            if (ip.length === 0) break;
            if (i > 0) {
                if (ip[0] !== '.') throw new Error('Invalid IP');
                ip = ip.substring(1);
            }
            ref = atob(ip), n = ref[0], c = ref[1];
            ip = ip.substring(c);
            b.push(n);
        }
        if (ip.length !== 0) throw new Error('Invalid IP');
        switch(b.length){
            case 1:
                if (b[0] > 4294967295) throw new Error('Invalid IP');
                return b[0] >>> 0;
            case 2:
                if (b[0] > 255 || b[1] > 16777215) throw new Error('Invalid IP');
                return (b[0] << 24 | b[1]) >>> 0;
            case 3:
                if (b[0] > 255 || b[1] > 255 || b[2] > 65535) throw new Error('Invalid IP');
                return (b[0] << 24 | b[1] << 16 | b[2]) >>> 0;
            case 4:
                if (b[0] > 255 || b[1] > 255 || b[2] > 255 || b[3] > 255) throw new Error('Invalid IP');
                return (b[0] << 24 | b[1] << 16 | b[2] << 8 | b[3]) >>> 0;
            default:
                throw new Error('Invalid IP');
        }
    };
    chr = function(b) {
        return b.charCodeAt(0);
    };
    chr0 = chr('0');
    chra = chr('a');
    chrA = chr('A');
    atob = function(s) {
        var base, dmax, i, n, start;
        n = 0;
        base = 10;
        dmax = '9';
        i = 0;
        if (s.length > 1 && s[i] === '0') {
            if (s[i + 1] === 'x' || s[i + 1] === 'X') {
                i += 2;
                base = 16;
            } else if ('0' <= s[i + 1] && s[i + 1] <= '9') {
                i++;
                base = 8;
                dmax = '7';
            }
        }
        start = i;
        while(i < s.length){
            if ('0' <= s[i] && s[i] <= dmax) n = n * base + (chr(s[i]) - chr0) >>> 0;
            else if (base === 16) {
                if ('a' <= s[i] && s[i] <= 'f') n = n * base + (10 + chr(s[i]) - chra) >>> 0;
                else if ('A' <= s[i] && s[i] <= 'F') n = n * base + (10 + chr(s[i]) - chrA) >>> 0;
                else break;
            } else break;
            if (n > 4294967295) throw new Error('too large');
            i++;
        }
        if (i === start) throw new Error('empty octet');
        return [
            n,
            i
        ];
    };
    Netmask1 = (function() {
        function Netmask(net, mask) {
            var error, i, j, ref;
            if (typeof net !== 'string') throw new Error("Missing `net' parameter");
            if (!mask) ref = net.split('/', 2), net = ref[0], mask = ref[1];
            if (!mask) mask = 32;
            if (typeof mask === 'string' && mask.indexOf('.') > -1) {
                try {
                    this.maskLong = ip2long(mask);
                } catch (error1) {
                    error = error1;
                    throw new Error("Invalid mask: " + mask);
                }
                for(i = j = 32; j >= 0; i = --j)if (this.maskLong === 4294967295 << 32 - i >>> 0) {
                    this.bitmask = i;
                    break;
                }
            } else if (mask || mask === 0) {
                this.bitmask = parseInt(mask, 10);
                this.maskLong = 0;
                if (this.bitmask > 0) this.maskLong = 4294967295 << 32 - this.bitmask >>> 0;
            } else throw new Error("Invalid mask: empty");
            try {
                this.netLong = (ip2long(net) & this.maskLong) >>> 0;
            } catch (error1) {
                error = error1;
                throw new Error("Invalid net address: " + net);
            }
            if (!(this.bitmask <= 32)) throw new Error("Invalid mask for ip4: " + mask);
            this.size = Math.pow(2, 32 - this.bitmask);
            this.base = long2ip(this.netLong);
            this.mask = long2ip(this.maskLong);
            this.hostmask = long2ip(~this.maskLong);
            this.first = this.bitmask <= 30 ? long2ip(this.netLong + 1) : this.base;
            this.last = this.bitmask <= 30 ? long2ip(this.netLong + this.size - 2) : long2ip(this.netLong + this.size - 1);
            this.broadcast = this.bitmask <= 30 ? long2ip(this.netLong + this.size - 1) : void 0;
        }
        Netmask.prototype.contains = function(ip) {
            if (typeof ip === 'string' && (ip.indexOf('/') > 0 || ip.split('.').length !== 4)) ip = new Netmask(ip);
            if (ip instanceof Netmask) return this.contains(ip.base) && this.contains(ip.broadcast || ip.last);
            else return (ip2long(ip) & this.maskLong) >>> 0 === (this.netLong & this.maskLong) >>> 0;
        };
        Netmask.prototype.next = function(count) {
            if (count == null) count = 1;
            return new Netmask(long2ip(this.netLong + this.size * count), this.mask);
        };
        Netmask.prototype.forEach = function(fn) {
            var index, lastLong, long;
            long = ip2long(this.first);
            lastLong = ip2long(this.last);
            index = 0;
            while(long <= lastLong){
                fn(long2ip(long), long, index);
                index++;
                long++;
            }
        };
        Netmask.prototype.toString = function() {
            return this.base + "/" + this.bitmask;
        };
        return Netmask;
    })();
    exports.ip2long = ip2long;
    exports.long2ip = long2ip;
    exports.Netmask = Netmask1;
}).call(this);

},{}],"jgj5T":[function(require,module,exports) {
(function(root) {
    // A list of regular expressions that match arbitrary IPv4 addresses,
    // for which a number of weird notations exist.
    // Note that an address like 0010.0xa5.1.1 is considered legal.
    const ipv4Part = '(0?\\d+|0x[a-f0-9]+)';
    const ipv4Regexes = {
        fourOctet: new RegExp(`^${ipv4Part}\\.${ipv4Part}\\.${ipv4Part}\\.${ipv4Part}$`, 'i'),
        threeOctet: new RegExp(`^${ipv4Part}\\.${ipv4Part}\\.${ipv4Part}$`, 'i'),
        twoOctet: new RegExp(`^${ipv4Part}\\.${ipv4Part}$`, 'i'),
        longValue: new RegExp(`^${ipv4Part}$`, 'i')
    };
    // Regular Expression for checking Octal numbers
    const octalRegex = new RegExp(`^0[0-7]+$`, 'i');
    const hexRegex = new RegExp(`^0x[a-f0-9]+$`, 'i');
    const zoneIndex = '%[0-9a-z]{1,}';
    // IPv6-matching regular expressions.
    // For IPv6, the task is simpler: it is enough to match the colon-delimited
    // hexadecimal IPv6 and a transitional variant with dotted-decimal IPv4 at
    // the end.
    const ipv6Part = '(?:[0-9a-f]+::?)+';
    const ipv6Regexes = {
        zoneIndex: new RegExp(zoneIndex, 'i'),
        'native': new RegExp(`^(::)?(${ipv6Part})?([0-9a-f]+)?(::)?(${zoneIndex})?$`, 'i'),
        deprecatedTransitional: new RegExp(`^(?:::)(${ipv4Part}\\.${ipv4Part}\\.${ipv4Part}\\.${ipv4Part}(${zoneIndex})?)$`, 'i'),
        transitional: new RegExp(`^((?:${ipv6Part})|(?:::)(?:${ipv6Part})?)${ipv4Part}\\.${ipv4Part}\\.${ipv4Part}\\.${ipv4Part}(${zoneIndex})?$`, 'i')
    };
    // Expand :: in an IPv6 address or address part consisting of `parts` groups.
    function expandIPv6(string, parts) {
        // More than one '::' means invalid adddress
        if (string.indexOf('::') !== string.lastIndexOf('::')) return null;
        let colonCount = 0;
        let lastColon = -1;
        let zoneId = (string.match(ipv6Regexes.zoneIndex) || [])[0];
        let replacement, replacementCount;
        // Remove zone index and save it for later
        if (zoneId) {
            zoneId = zoneId.substring(1);
            string = string.replace(/%.+$/, '');
        }
        // How many parts do we already have?
        while((lastColon = string.indexOf(':', lastColon + 1)) >= 0)colonCount++;
        // 0::0 is two parts more than ::
        if (string.substr(0, 2) === '::') colonCount--;
        if (string.substr(-2, 2) === '::') colonCount--;
        // The following loop would hang if colonCount > parts
        if (colonCount > parts) return null;
        // replacement = ':' + '0:' * (parts - colonCount)
        replacementCount = parts - colonCount;
        replacement = ':';
        while(replacementCount--)replacement += '0:';
        // Insert the missing zeroes
        string = string.replace('::', replacement);
        // Trim any garbage which may be hanging around if :: was at the edge in
        // the source strin
        if (string[0] === ':') string = string.slice(1);
        if (string[string.length - 1] === ':') string = string.slice(0, -1);
        parts = (function() {
            const ref = string.split(':');
            const results = [];
            for(let i = 0; i < ref.length; i++)results.push(parseInt(ref[i], 16));
            return results;
        })();
        return {
            parts: parts,
            zoneId: zoneId
        };
    }
    // A generic CIDR (Classless Inter-Domain Routing) RFC1518 range matcher.
    function matchCIDR(first, second, partSize, cidrBits) {
        if (first.length !== second.length) throw new Error('ipaddr: cannot match CIDR for objects with different lengths');
        let part = 0;
        let shift;
        while(cidrBits > 0){
            shift = partSize - cidrBits;
            if (shift < 0) shift = 0;
            if (first[part] >> shift !== second[part] >> shift) return false;
            cidrBits -= partSize;
            part += 1;
        }
        return true;
    }
    function parseIntAuto(string) {
        // Hexadedimal base 16 (0x#)
        if (hexRegex.test(string)) return parseInt(string, 16);
        // While octal representation is discouraged by ECMAScript 3
        // and forbidden by ECMAScript 5, we silently allow it to
        // work only if the rest of the string has numbers less than 8.
        if (string[0] === '0' && !isNaN(parseInt(string[1], 10))) {
            if (octalRegex.test(string)) return parseInt(string, 8);
            throw new Error(`ipaddr: cannot parse ${string} as octal`);
        }
        // Always include the base 10 radix!
        return parseInt(string, 10);
    }
    function padPart(part, length) {
        while(part.length < length)part = `0${part}`;
        return part;
    }
    const ipaddr = {
    };
    // An IPv4 address (RFC791).
    ipaddr.IPv4 = (function() {
        // Constructs a new IPv4 address from an array of four octets
        // in network order (MSB first)
        // Verifies the input.
        function IPv4(octets) {
            if (octets.length !== 4) throw new Error('ipaddr: ipv4 octet count should be 4');
            let i, octet;
            for(i = 0; i < octets.length; i++){
                octet = octets[i];
                if (!(0 <= octet && octet <= 255)) throw new Error('ipaddr: ipv4 octet should fit in 8 bits');
            }
            this.octets = octets;
        }
        // Special IPv4 address ranges.
        // See also https://en.wikipedia.org/wiki/Reserved_IP_addresses
        IPv4.prototype.SpecialRanges = {
            unspecified: [
                [
                    new IPv4([
                        0,
                        0,
                        0,
                        0
                    ]),
                    8
                ]
            ],
            broadcast: [
                [
                    new IPv4([
                        255,
                        255,
                        255,
                        255
                    ]),
                    32
                ]
            ],
            // RFC3171
            multicast: [
                [
                    new IPv4([
                        224,
                        0,
                        0,
                        0
                    ]),
                    4
                ]
            ],
            // RFC3927
            linkLocal: [
                [
                    new IPv4([
                        169,
                        254,
                        0,
                        0
                    ]),
                    16
                ]
            ],
            // RFC5735
            loopback: [
                [
                    new IPv4([
                        127,
                        0,
                        0,
                        0
                    ]),
                    8
                ]
            ],
            // RFC6598
            carrierGradeNat: [
                [
                    new IPv4([
                        100,
                        64,
                        0,
                        0
                    ]),
                    10
                ]
            ],
            // RFC1918
            'private': [
                [
                    new IPv4([
                        10,
                        0,
                        0,
                        0
                    ]),
                    8
                ],
                [
                    new IPv4([
                        172,
                        16,
                        0,
                        0
                    ]),
                    12
                ],
                [
                    new IPv4([
                        192,
                        168,
                        0,
                        0
                    ]),
                    16
                ]
            ],
            // Reserved and testing-only ranges; RFCs 5735, 5737, 2544, 1700
            reserved: [
                [
                    new IPv4([
                        192,
                        0,
                        0,
                        0
                    ]),
                    24
                ],
                [
                    new IPv4([
                        192,
                        0,
                        2,
                        0
                    ]),
                    24
                ],
                [
                    new IPv4([
                        192,
                        88,
                        99,
                        0
                    ]),
                    24
                ],
                [
                    new IPv4([
                        198,
                        51,
                        100,
                        0
                    ]),
                    24
                ],
                [
                    new IPv4([
                        203,
                        0,
                        113,
                        0
                    ]),
                    24
                ],
                [
                    new IPv4([
                        240,
                        0,
                        0,
                        0
                    ]),
                    4
                ]
            ]
        };
        // The 'kind' method exists on both IPv4 and IPv6 classes.
        IPv4.prototype.kind = function() {
            return 'ipv4';
        };
        // Checks if this address matches other one within given CIDR range.
        IPv4.prototype.match = function(other, cidrRange) {
            let ref;
            if (cidrRange === undefined) {
                ref = other;
                other = ref[0];
                cidrRange = ref[1];
            }
            if (other.kind() !== 'ipv4') throw new Error('ipaddr: cannot match ipv4 address with non-ipv4 one');
            return matchCIDR(this.octets, other.octets, 8, cidrRange);
        };
        // returns a number of leading ones in IPv4 address, making sure that
        // the rest is a solid sequence of 0's (valid netmask)
        // returns either the CIDR length or null if mask is not valid
        IPv4.prototype.prefixLengthFromSubnetMask = function() {
            let cidr = 0;
            // non-zero encountered stop scanning for zeroes
            let stop = false;
            // number of zeroes in octet
            const zerotable = {
                0: 8,
                128: 7,
                192: 6,
                224: 5,
                240: 4,
                248: 3,
                252: 2,
                254: 1,
                255: 0
            };
            let i, octet, zeros;
            for(i = 3; i >= 0; i -= 1){
                octet = this.octets[i];
                if (octet in zerotable) {
                    zeros = zerotable[octet];
                    if (stop && zeros !== 0) return null;
                    if (zeros !== 8) stop = true;
                    cidr += zeros;
                } else return null;
            }
            return 32 - cidr;
        };
        // Checks if the address corresponds to one of the special ranges.
        IPv4.prototype.range = function() {
            return ipaddr.subnetMatch(this, this.SpecialRanges);
        };
        // Returns an array of byte-sized values in network order (MSB first)
        IPv4.prototype.toByteArray = function() {
            return this.octets.slice(0);
        };
        // Converts this IPv4 address to an IPv4-mapped IPv6 address.
        IPv4.prototype.toIPv4MappedAddress = function() {
            return ipaddr.IPv6.parse(`::ffff:${this.toString()}`);
        };
        // Symmetrical method strictly for aligning with the IPv6 methods.
        IPv4.prototype.toNormalizedString = function() {
            return this.toString();
        };
        // Returns the address in convenient, decimal-dotted format.
        IPv4.prototype.toString = function() {
            return this.octets.join('.');
        };
        return IPv4;
    })();
    // A utility function to return broadcast address given the IPv4 interface and prefix length in CIDR notation
    ipaddr.IPv4.broadcastAddressFromCIDR = function(string) {
        try {
            const cidr = this.parseCIDR(string);
            const ipInterfaceOctets = cidr[0].toByteArray();
            const subnetMaskOctets = this.subnetMaskFromPrefixLength(cidr[1]).toByteArray();
            const octets = [];
            let i = 0;
            while(i < 4){
                // Broadcast address is bitwise OR between ip interface and inverted mask
                octets.push(parseInt(ipInterfaceOctets[i], 10) | parseInt(subnetMaskOctets[i], 10) ^ 255);
                i++;
            }
            return new this(octets);
        } catch (e) {
            throw new Error('ipaddr: the address does not have IPv4 CIDR format');
        }
    };
    // Checks if a given string is formatted like IPv4 address.
    ipaddr.IPv4.isIPv4 = function(string) {
        return this.parser(string) !== null;
    };
    // Checks if a given string is a valid IPv4 address.
    ipaddr.IPv4.isValid = function(string) {
        try {
            new this(this.parser(string));
            return true;
        } catch (e) {
            return false;
        }
    };
    // Checks if a given string is a full four-part IPv4 Address.
    ipaddr.IPv4.isValidFourPartDecimal = function(string) {
        if (ipaddr.IPv4.isValid(string) && string.match(/^(0|[1-9]\d*)(\.(0|[1-9]\d*)){3}$/)) return true;
        else return false;
    };
    // A utility function to return network address given the IPv4 interface and prefix length in CIDR notation
    ipaddr.IPv4.networkAddressFromCIDR = function(string) {
        let cidr, i, ipInterfaceOctets, octets, subnetMaskOctets;
        try {
            cidr = this.parseCIDR(string);
            ipInterfaceOctets = cidr[0].toByteArray();
            subnetMaskOctets = this.subnetMaskFromPrefixLength(cidr[1]).toByteArray();
            octets = [];
            i = 0;
            while(i < 4){
                // Network address is bitwise AND between ip interface and mask
                octets.push(parseInt(ipInterfaceOctets[i], 10) & parseInt(subnetMaskOctets[i], 10));
                i++;
            }
            return new this(octets);
        } catch (e) {
            throw new Error('ipaddr: the address does not have IPv4 CIDR format');
        }
    };
    // Tries to parse and validate a string with IPv4 address.
    // Throws an error if it fails.
    ipaddr.IPv4.parse = function(string) {
        const parts = this.parser(string);
        if (parts === null) throw new Error('ipaddr: string is not formatted like an IPv4 Address');
        return new this(parts);
    };
    // Parses the string as an IPv4 Address with CIDR Notation.
    ipaddr.IPv4.parseCIDR = function(string) {
        let match;
        if (match = string.match(/^(.+)\/(\d+)$/)) {
            const maskLength = parseInt(match[2]);
            if (maskLength >= 0 && maskLength <= 32) {
                const parsed = [
                    this.parse(match[1]),
                    maskLength
                ];
                Object.defineProperty(parsed, 'toString', {
                    value: function() {
                        return this.join('/');
                    }
                });
                return parsed;
            }
        }
        throw new Error('ipaddr: string is not formatted like an IPv4 CIDR range');
    };
    // Classful variants (like a.b, where a is an octet, and b is a 24-bit
    // value representing last three octets; this corresponds to a class C
    // address) are omitted due to classless nature of modern Internet.
    ipaddr.IPv4.parser = function(string) {
        let match, part, value;
        // parseInt recognizes all that octal & hexadecimal weirdness for us
        if (match = string.match(ipv4Regexes.fourOctet)) return (function() {
            const ref = match.slice(1, 6);
            const results = [];
            for(let i = 0; i < ref.length; i++){
                part = ref[i];
                results.push(parseIntAuto(part));
            }
            return results;
        })();
        else if (match = string.match(ipv4Regexes.longValue)) {
            value = parseIntAuto(match[1]);
            if (value > 4294967295 || value < 0) throw new Error('ipaddr: address outside defined range');
            return (function() {
                const results = [];
                let shift;
                for(shift = 0; shift <= 24; shift += 8)results.push(value >> shift & 255);
                return results;
            })().reverse();
        } else if (match = string.match(ipv4Regexes.twoOctet)) return (function() {
            const ref = match.slice(1, 4);
            const results = [];
            value = parseIntAuto(ref[1]);
            if (value > 16777215 || value < 0) throw new Error('ipaddr: address outside defined range');
            results.push(parseIntAuto(ref[0]));
            results.push(value >> 16 & 255);
            results.push(value >> 8 & 255);
            results.push(value & 255);
            return results;
        })();
        else if (match = string.match(ipv4Regexes.threeOctet)) return (function() {
            const ref = match.slice(1, 5);
            const results = [];
            value = parseIntAuto(ref[2]);
            if (value > 65535 || value < 0) throw new Error('ipaddr: address outside defined range');
            results.push(parseIntAuto(ref[0]));
            results.push(parseIntAuto(ref[1]));
            results.push(value >> 8 & 255);
            results.push(value & 255);
            return results;
        })();
        else return null;
    };
    // A utility function to return subnet mask in IPv4 format given the prefix length
    ipaddr.IPv4.subnetMaskFromPrefixLength = function(prefix) {
        prefix = parseInt(prefix);
        if (prefix < 0 || prefix > 32) throw new Error('ipaddr: invalid IPv4 prefix length');
        const octets = [
            0,
            0,
            0,
            0
        ];
        let j = 0;
        const filledOctetCount = Math.floor(prefix / 8);
        while(j < filledOctetCount){
            octets[j] = 255;
            j++;
        }
        if (filledOctetCount < 4) octets[filledOctetCount] = Math.pow(2, prefix % 8) - 1 << 8 - prefix % 8;
        return new this(octets);
    };
    // An IPv6 address (RFC2460)
    ipaddr.IPv6 = (function() {
        // Constructs an IPv6 address from an array of eight 16 - bit parts
        // or sixteen 8 - bit parts in network order(MSB first).
        // Throws an error if the input is invalid.
        function IPv6(parts, zoneId) {
            let i, part;
            if (parts.length === 16) {
                this.parts = [];
                for(i = 0; i <= 14; i += 2)this.parts.push(parts[i] << 8 | parts[i + 1]);
            } else if (parts.length === 8) this.parts = parts;
            else throw new Error('ipaddr: ipv6 part count should be 8 or 16');
            for(i = 0; i < this.parts.length; i++){
                part = this.parts[i];
                if (!(0 <= part && part <= 65535)) throw new Error('ipaddr: ipv6 part should fit in 16 bits');
            }
            if (zoneId) this.zoneId = zoneId;
        }
        // Special IPv6 ranges
        IPv6.prototype.SpecialRanges = {
            // RFC4291, here and after
            unspecified: [
                new IPv6([
                    0,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0
                ]),
                128
            ],
            linkLocal: [
                new IPv6([
                    65152,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0
                ]),
                10
            ],
            multicast: [
                new IPv6([
                    65280,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0
                ]),
                8
            ],
            loopback: [
                new IPv6([
                    0,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0,
                    1
                ]),
                128
            ],
            uniqueLocal: [
                new IPv6([
                    64512,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0
                ]),
                7
            ],
            ipv4Mapped: [
                new IPv6([
                    0,
                    0,
                    0,
                    0,
                    0,
                    65535,
                    0,
                    0
                ]),
                96
            ],
            // RFC6145
            rfc6145: [
                new IPv6([
                    0,
                    0,
                    0,
                    0,
                    65535,
                    0,
                    0,
                    0
                ]),
                96
            ],
            // RFC6052
            rfc6052: [
                new IPv6([
                    100,
                    65435,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0
                ]),
                96
            ],
            // RFC3056
            '6to4': [
                new IPv6([
                    8194,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0
                ]),
                16
            ],
            // RFC6052, RFC6146
            teredo: [
                new IPv6([
                    8193,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0
                ]),
                32
            ],
            // RFC4291
            reserved: [
                [
                    new IPv6([
                        8193,
                        3512,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0
                    ]),
                    32
                ]
            ]
        };
        // Checks if this address is an IPv4-mapped IPv6 address.
        IPv6.prototype.isIPv4MappedAddress = function() {
            return this.range() === 'ipv4Mapped';
        };
        // The 'kind' method exists on both IPv4 and IPv6 classes.
        IPv6.prototype.kind = function() {
            return 'ipv6';
        };
        // Checks if this address matches other one within given CIDR range.
        IPv6.prototype.match = function(other, cidrRange) {
            let ref;
            if (cidrRange === undefined) {
                ref = other;
                other = ref[0];
                cidrRange = ref[1];
            }
            if (other.kind() !== 'ipv6') throw new Error('ipaddr: cannot match ipv6 address with non-ipv6 one');
            return matchCIDR(this.parts, other.parts, 16, cidrRange);
        };
        // returns a number of leading ones in IPv6 address, making sure that
        // the rest is a solid sequence of 0's (valid netmask)
        // returns either the CIDR length or null if mask is not valid
        IPv6.prototype.prefixLengthFromSubnetMask = function() {
            let cidr = 0;
            // non-zero encountered stop scanning for zeroes
            let stop = false;
            // number of zeroes in octet
            const zerotable = {
                0: 16,
                32768: 15,
                49152: 14,
                57344: 13,
                61440: 12,
                63488: 11,
                64512: 10,
                65024: 9,
                65280: 8,
                65408: 7,
                65472: 6,
                65504: 5,
                65520: 4,
                65528: 3,
                65532: 2,
                65534: 1,
                65535: 0
            };
            let part, zeros;
            for(let i = 7; i >= 0; i -= 1){
                part = this.parts[i];
                if (part in zerotable) {
                    zeros = zerotable[part];
                    if (stop && zeros !== 0) return null;
                    if (zeros !== 16) stop = true;
                    cidr += zeros;
                } else return null;
            }
            return 128 - cidr;
        };
        // Checks if the address corresponds to one of the special ranges.
        IPv6.prototype.range = function() {
            return ipaddr.subnetMatch(this, this.SpecialRanges);
        };
        // Returns an array of byte-sized values in network order (MSB first)
        IPv6.prototype.toByteArray = function() {
            let part;
            const bytes = [];
            const ref = this.parts;
            for(let i = 0; i < ref.length; i++){
                part = ref[i];
                bytes.push(part >> 8);
                bytes.push(part & 255);
            }
            return bytes;
        };
        // Returns the address in expanded format with all zeroes included, like
        // 2001:0db8:0008:0066:0000:0000:0000:0001
        IPv6.prototype.toFixedLengthString = function() {
            const addr = (function() {
                const results = [];
                for(let i = 0; i < this.parts.length; i++)results.push(padPart(this.parts[i].toString(16), 4));
                return results;
            }).call(this).join(':');
            let suffix = '';
            if (this.zoneId) suffix = `%${this.zoneId}`;
            return addr + suffix;
        };
        // Converts this address to IPv4 address if it is an IPv4-mapped IPv6 address.
        // Throws an error otherwise.
        IPv6.prototype.toIPv4Address = function() {
            if (!this.isIPv4MappedAddress()) throw new Error('ipaddr: trying to convert a generic ipv6 address to ipv4');
            const ref = this.parts.slice(-2);
            const high = ref[0];
            const low = ref[1];
            return new ipaddr.IPv4([
                high >> 8,
                high & 255,
                low >> 8,
                low & 255
            ]);
        };
        // Returns the address in expanded format with all zeroes included, like
        // 2001:db8:8:66:0:0:0:1
        //
        // Deprecated: use toFixedLengthString() instead.
        IPv6.prototype.toNormalizedString = function() {
            const addr = (function() {
                const results = [];
                for(let i = 0; i < this.parts.length; i++)results.push(this.parts[i].toString(16));
                return results;
            }).call(this).join(':');
            let suffix = '';
            if (this.zoneId) suffix = `%${this.zoneId}`;
            return addr + suffix;
        };
        // Returns the address in compact, human-readable format like
        // 2001:db8:8:66::1
        // in line with RFC 5952 (see https://tools.ietf.org/html/rfc5952#section-4)
        IPv6.prototype.toRFC5952String = function() {
            const regex = /((^|:)(0(:|$)){2,})/g;
            const string = this.toNormalizedString();
            let bestMatchIndex = 0;
            let bestMatchLength = -1;
            let match;
            while(match = regex.exec(string))if (match[0].length > bestMatchLength) {
                bestMatchIndex = match.index;
                bestMatchLength = match[0].length;
            }
            if (bestMatchLength < 0) return string;
            return `${string.substring(0, bestMatchIndex)}::${string.substring(bestMatchIndex + bestMatchLength)}`;
        };
        // Returns the address in compact, human-readable format like
        // 2001:db8:8:66::1
        //
        // Deprecated: use toRFC5952String() instead.
        IPv6.prototype.toString = function() {
            // Replace the first sequence of 1 or more '0' parts with '::'
            return this.toNormalizedString().replace(/((^|:)(0(:|$))+)/, '::');
        };
        return IPv6;
    })();
    // A utility function to return broadcast address given the IPv6 interface and prefix length in CIDR notation
    ipaddr.IPv6.broadcastAddressFromCIDR = function(string) {
        try {
            const cidr = this.parseCIDR(string);
            const ipInterfaceOctets = cidr[0].toByteArray();
            const subnetMaskOctets = this.subnetMaskFromPrefixLength(cidr[1]).toByteArray();
            const octets = [];
            let i = 0;
            while(i < 16){
                // Broadcast address is bitwise OR between ip interface and inverted mask
                octets.push(parseInt(ipInterfaceOctets[i], 10) | parseInt(subnetMaskOctets[i], 10) ^ 255);
                i++;
            }
            return new this(octets);
        } catch (e) {
            throw new Error(`ipaddr: the address does not have IPv6 CIDR format (${e})`);
        }
    };
    // Checks if a given string is formatted like IPv6 address.
    ipaddr.IPv6.isIPv6 = function(string) {
        return this.parser(string) !== null;
    };
    // Checks to see if string is a valid IPv6 Address
    ipaddr.IPv6.isValid = function(string) {
        // Since IPv6.isValid is always called first, this shortcut
        // provides a substantial performance gain.
        if (typeof string === 'string' && string.indexOf(':') === -1) return false;
        try {
            const addr = this.parser(string);
            new this(addr.parts, addr.zoneId);
            return true;
        } catch (e) {
            return false;
        }
    };
    // A utility function to return network address given the IPv6 interface and prefix length in CIDR notation
    ipaddr.IPv6.networkAddressFromCIDR = function(string) {
        let cidr, i, ipInterfaceOctets, octets, subnetMaskOctets;
        try {
            cidr = this.parseCIDR(string);
            ipInterfaceOctets = cidr[0].toByteArray();
            subnetMaskOctets = this.subnetMaskFromPrefixLength(cidr[1]).toByteArray();
            octets = [];
            i = 0;
            while(i < 16){
                // Network address is bitwise AND between ip interface and mask
                octets.push(parseInt(ipInterfaceOctets[i], 10) & parseInt(subnetMaskOctets[i], 10));
                i++;
            }
            return new this(octets);
        } catch (e) {
            throw new Error(`ipaddr: the address does not have IPv6 CIDR format (${e})`);
        }
    };
    // Tries to parse and validate a string with IPv6 address.
    // Throws an error if it fails.
    ipaddr.IPv6.parse = function(string) {
        const addr = this.parser(string);
        if (addr.parts === null) throw new Error('ipaddr: string is not formatted like an IPv6 Address');
        return new this(addr.parts, addr.zoneId);
    };
    ipaddr.IPv6.parseCIDR = function(string) {
        let maskLength, match, parsed;
        if (match = string.match(/^(.+)\/(\d+)$/)) {
            maskLength = parseInt(match[2]);
            if (maskLength >= 0 && maskLength <= 128) {
                parsed = [
                    this.parse(match[1]),
                    maskLength
                ];
                Object.defineProperty(parsed, 'toString', {
                    value: function() {
                        return this.join('/');
                    }
                });
                return parsed;
            }
        }
        throw new Error('ipaddr: string is not formatted like an IPv6 CIDR range');
    };
    // Parse an IPv6 address.
    ipaddr.IPv6.parser = function(string) {
        let addr, i, match, octet, octets, zoneId;
        if (match = string.match(ipv6Regexes.deprecatedTransitional)) return this.parser(`::ffff:${match[1]}`);
        if (ipv6Regexes.native.test(string)) return expandIPv6(string, 8);
        if (match = string.match(ipv6Regexes.transitional)) {
            zoneId = match[6] || '';
            addr = expandIPv6(match[1].slice(0, -1) + zoneId, 6);
            if (addr.parts) {
                octets = [
                    parseInt(match[2]),
                    parseInt(match[3]),
                    parseInt(match[4]),
                    parseInt(match[5])
                ];
                for(i = 0; i < octets.length; i++){
                    octet = octets[i];
                    if (!(0 <= octet && octet <= 255)) return null;
                }
                addr.parts.push(octets[0] << 8 | octets[1]);
                addr.parts.push(octets[2] << 8 | octets[3]);
                return {
                    parts: addr.parts,
                    zoneId: addr.zoneId
                };
            }
        }
        return null;
    };
    // A utility function to return subnet mask in IPv6 format given the prefix length
    ipaddr.IPv6.subnetMaskFromPrefixLength = function(prefix) {
        prefix = parseInt(prefix);
        if (prefix < 0 || prefix > 128) throw new Error('ipaddr: invalid IPv6 prefix length');
        const octets = [
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0
        ];
        let j = 0;
        const filledOctetCount = Math.floor(prefix / 8);
        while(j < filledOctetCount){
            octets[j] = 255;
            j++;
        }
        if (filledOctetCount < 16) octets[filledOctetCount] = Math.pow(2, prefix % 8) - 1 << 8 - prefix % 8;
        return new this(octets);
    };
    // Try to parse an array in network order (MSB first) for IPv4 and IPv6
    ipaddr.fromByteArray = function(bytes) {
        const length = bytes.length;
        if (length === 4) return new ipaddr.IPv4(bytes);
        else if (length === 16) return new ipaddr.IPv6(bytes);
        else throw new Error('ipaddr: the binary input is neither an IPv6 nor IPv4 address');
    };
    // Checks if the address is valid IP address
    ipaddr.isValid = function(string) {
        return ipaddr.IPv6.isValid(string) || ipaddr.IPv4.isValid(string);
    };
    // Attempts to parse an IP Address, first through IPv6 then IPv4.
    // Throws an error if it could not be parsed.
    ipaddr.parse = function(string) {
        if (ipaddr.IPv6.isValid(string)) return ipaddr.IPv6.parse(string);
        else if (ipaddr.IPv4.isValid(string)) return ipaddr.IPv4.parse(string);
        else throw new Error('ipaddr: the address has neither IPv6 nor IPv4 format');
    };
    // Attempt to parse CIDR notation, first through IPv6 then IPv4.
    // Throws an error if it could not be parsed.
    ipaddr.parseCIDR = function(string) {
        try {
            return ipaddr.IPv6.parseCIDR(string);
        } catch (e) {
            try {
                return ipaddr.IPv4.parseCIDR(string);
            } catch (e2) {
                throw new Error('ipaddr: the address has neither IPv6 nor IPv4 CIDR format');
            }
        }
    };
    // Parse an address and return plain IPv4 address if it is an IPv4-mapped address
    ipaddr.process = function(string) {
        const addr = this.parse(string);
        if (addr.kind() === 'ipv6' && addr.isIPv4MappedAddress()) return addr.toIPv4Address();
        else return addr;
    };
    // An utility function to ease named range matching. See examples below.
    // rangeList can contain both IPv4 and IPv6 subnet entries and will not throw errors
    // on matching IPv4 addresses to IPv6 ranges or vice versa.
    ipaddr.subnetMatch = function(address, rangeList, defaultName) {
        let i, rangeName, rangeSubnets, subnet;
        if (defaultName === undefined || defaultName === null) defaultName = 'unicast';
        for(rangeName in rangeList)if (Object.prototype.hasOwnProperty.call(rangeList, rangeName)) {
            rangeSubnets = rangeList[rangeName];
            // ECMA5 Array.isArray isn't available everywhere
            if (rangeSubnets[0] && !(rangeSubnets[0] instanceof Array)) rangeSubnets = [
                rangeSubnets
            ];
            for(i = 0; i < rangeSubnets.length; i++){
                subnet = rangeSubnets[i];
                if (address.kind() === subnet[0].kind() && address.match.apply(address, subnet)) return rangeName;
            }
        }
        return defaultName;
    };
    // Export for both the CommonJS and browser-like environment
    if (typeof module !== 'undefined' && module.exports) module.exports = ipaddr;
    else root.ipaddr = ipaddr;
})(this);

},{}],"fdmmy":[function(require,module,exports) {
'use strict';
const debug = require('debug');
const log = Object.assign(debug('libp2p:transports'), {
    error: debug('libp2p:transports:err')
});
const pSettle = require('p-settle');
const { codes  } = require('./errors');
const errCode = require('err-code');
const { updateSelfPeerRecord  } = require('./record/utils');
/**
 * @typedef {import('multiaddr').Multiaddr} Multiaddr
 * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection
 * @typedef {import('libp2p-interfaces/src/transport/types').TransportFactory<any, any>} TransportFactory
 * @typedef {import('libp2p-interfaces/src/transport/types').Transport<any, any>} Transport
 *
 * @typedef {Object} TransportManagerProperties
 * @property {import('./')} libp2p
 * @property {import('./upgrader')} upgrader
 *
 * @typedef {Object} TransportManagerOptions
 * @property {number} [faultTolerance = FAULT_TOLERANCE.FATAL_ALL] - Address listen error tolerance.
 */ class TransportManager {
    /**
   * @class
   * @param {TransportManagerProperties & TransportManagerOptions} options
   */ constructor({ libp2p , upgrader , faultTolerance =FAULT_TOLERANCE.FATAL_ALL  }){
        this.libp2p = libp2p;
        this.upgrader = upgrader;
        /** @type {Map<string, Transport>} */ this._transports = new Map();
        this._listeners = new Map();
        this._listenerOptions = new Map();
        this.faultTolerance = faultTolerance;
    }
    /**
   * Adds a `Transport` to the manager
   *
   * @param {string} key
   * @param {TransportFactory} Transport
   * @param {*} transportOptions - Additional options to pass to the transport
   * @returns {void}
   */ add(key, Transport, transportOptions = {
    }) {
        log('adding %s', key);
        if (!key) throw errCode(new Error(`Transport must have a valid key, was given '${key}'`), codes.ERR_INVALID_KEY);
        if (this._transports.has(key)) throw errCode(new Error('There is already a transport with this key'), codes.ERR_DUPLICATE_TRANSPORT);
        const transport = new Transport({
            ...transportOptions,
            libp2p: this.libp2p,
            upgrader: this.upgrader
        });
        this._transports.set(key, transport);
        this._listenerOptions.set(key, transportOptions.listenerOptions || {
        });
        if (!this._listeners.has(key)) this._listeners.set(key, []);
    }
    /**
   * Stops all listeners
   *
   * @async
   */ async close() {
        const tasks = [];
        for (const [key, listeners] of this._listeners){
            log('closing listeners for %s', key);
            while(listeners.length){
                const listener = listeners.pop();
                listener.removeAllListeners('listening');
                listener.removeAllListeners('close');
                tasks.push(listener.close());
            }
        }
        await Promise.all(tasks);
        log('all listeners closed');
        for (const key1 of this._listeners.keys())this._listeners.set(key1, []);
    }
    /**
   * Dials the given Multiaddr over it's supported transport
   *
   * @param {Multiaddr} ma
   * @param {*} options
   * @returns {Promise<Connection>}
   */ async dial(ma, options) {
        const transport = this.transportForMultiaddr(ma);
        if (!transport) throw errCode(new Error(`No transport available for address ${String(ma)}`), codes.ERR_TRANSPORT_UNAVAILABLE);
        try {
            return await transport.dial(ma, options);
        } catch (err) {
            if (!err.code) err.code = codes.ERR_TRANSPORT_DIAL_FAILED;
            throw err;
        }
    }
    /**
   * Returns all Multiaddr's the listeners are using
   *
   * @returns {Multiaddr[]}
   */ getAddrs() {
        /** @type {Multiaddr[]} */ let addrs = [];
        for (const listeners of this._listeners.values())for (const listener of listeners)addrs = [
            ...addrs,
            ...listener.getAddrs()
        ];
        return addrs;
    }
    /**
   * Returns all the transports instances.
   *
   * @returns {IterableIterator<Transport>}
   */ getTransports() {
        return this._transports.values();
    }
    /**
   * Finds a transport that matches the given Multiaddr
   *
   * @param {Multiaddr} ma
   * @returns {Transport|null}
   */ transportForMultiaddr(ma1) {
        for (const transport of this._transports.values()){
            const addrs = transport.filter([
                ma1
            ]);
            if (addrs.length) return transport;
        }
        return null;
    }
    /**
   * Starts listeners for each listen Multiaddr.
   *
   * @async
   * @param {Multiaddr[]} addrs - addresses to attempt to listen on
   */ async listen(addrs) {
        if (!addrs || addrs.length === 0) {
            log('no addresses were provided for listening, this node is dial only');
            return;
        }
        const couldNotListen = [];
        for (const [key, transport] of this._transports.entries()){
            const supportedAddrs = transport.filter(addrs);
            const tasks = [];
            // For each supported multiaddr, create a listener
            for (const addr of supportedAddrs){
                log('creating listener for %s on %s', key, addr);
                const listener = transport.createListener(this._listenerOptions.get(key));
                this._listeners.get(key).push(listener);
                // Track listen/close events
                listener.on('listening', ()=>updateSelfPeerRecord(this.libp2p)
                );
                listener.on('close', ()=>updateSelfPeerRecord(this.libp2p)
                );
                // We need to attempt to listen on everything
                tasks.push(listener.listen(addr));
            }
            // Keep track of transports we had no addresses for
            if (tasks.length === 0) {
                couldNotListen.push(key);
                continue;
            }
            const results = await pSettle(tasks);
            // If we are listening on at least 1 address, succeed.
            // TODO: we should look at adding a retry (`p-retry`) here to better support
            // listening on remote addresses as they may be offline. We could then potentially
            // just wait for any (`p-any`) listener to succeed on each transport before returning
            const isListening = results.find((r)=>r.isFulfilled === true
            );
            if (!isListening && this.faultTolerance !== FAULT_TOLERANCE.NO_FATAL) throw errCode(new Error(`Transport (${key}) could not listen on any available address`), codes.ERR_NO_VALID_ADDRESSES);
        }
        // If no transports were able to listen, throw an error. This likely
        // means we were given addresses we do not have transports for
        if (couldNotListen.length === this._transports.size) {
            const message = `no valid addresses were provided for transports [${couldNotListen}]`;
            if (this.faultTolerance === FAULT_TOLERANCE.FATAL_ALL) throw errCode(new Error(message), codes.ERR_NO_VALID_ADDRESSES);
            log(`libp2p in dial mode only: ${message}`);
        }
    }
    /**
   * Removes the given transport from the manager.
   * If a transport has any running listeners, they will be closed.
   *
   * @async
   * @param {string} key
   */ async remove(key2) {
        log('removing %s', key2);
        if (this._listeners.has(key2)) // Close any running listeners
        for (const listener of this._listeners.get(key2)){
            listener.removeAllListeners('listening');
            listener.removeAllListeners('close');
            await listener.close();
        }
        this._transports.delete(key2);
        this._listeners.delete(key2);
    }
    /**
   * Removes all transports from the manager.
   * If any listeners are running, they will be closed.
   *
   * @async
   */ async removeAll() {
        const tasks = [];
        for (const key of this._transports.keys())tasks.push(this.remove(key));
        await Promise.all(tasks);
    }
}
/**
 * Enum Transport Manager Fault Tolerance values.
 * FATAL_ALL should be used for failing in any listen circumstance.
 * NO_FATAL should be used for not failing when not listening.
 *
 * @readonly
 * @enum {number}
 */ const FAULT_TOLERANCE = {
    FATAL_ALL: 0,
    NO_FATAL: 1
};
TransportManager.FaultTolerance = FAULT_TOLERANCE;
module.exports = TransportManager;

},{"debug":"lWlU4","p-settle":"3dHn0","./errors":"dO31S","err-code":"eQvyh","./record/utils":"6p0gR"}],"3dHn0":[function(require,module,exports) {
'use strict';
const pReflect = require('p-reflect');
const pLimit = require('p-limit');
module.exports = async (array, options = {
})=>{
    const { concurrency =Infinity  } = options;
    const limit = pLimit(concurrency);
    return Promise.all(array.map((element)=>{
        if (element && typeof element.then === 'function') return pReflect(element);
        if (typeof element === 'function') return pReflect(limit(()=>element()
        ));
        return pReflect(Promise.resolve(element));
    }));
};

},{"p-reflect":"5kyrt","p-limit":"940fO"}],"5kyrt":[function(require,module,exports) {
'use strict';
const pReflect = async (promise)=>{
    try {
        const value = await promise;
        return {
            isFulfilled: true,
            isRejected: false,
            value
        };
    } catch (error) {
        return {
            isFulfilled: false,
            isRejected: true,
            reason: error
        };
    }
};
module.exports = pReflect;
// TODO: Remove this for the next major release
module.exports.default = pReflect;

},{}],"940fO":[function(require,module,exports) {
'use strict';
const pTry = require('p-try');
const pLimit = (concurrency)=>{
    if (!((Number.isInteger(concurrency) || concurrency === Infinity) && concurrency > 0)) return Promise.reject(new TypeError('Expected `concurrency` to be a number from 1 and up'));
    const queue = [];
    let activeCount = 0;
    const next = ()=>{
        activeCount--;
        if (queue.length > 0) queue.shift()();
    };
    const run = (fn, resolve, ...args)=>{
        activeCount++;
        const result = pTry(fn, ...args);
        resolve(result);
        result.then(next, next);
    };
    const enqueue = (fn, resolve, ...args)=>{
        if (activeCount < concurrency) run(fn, resolve, ...args);
        else queue.push(run.bind(null, fn, resolve, ...args));
    };
    const generator = (fn, ...args)=>new Promise((resolve)=>enqueue(fn, resolve, ...args)
        )
    ;
    Object.defineProperties(generator, {
        activeCount: {
            get: ()=>activeCount
        },
        pendingCount: {
            get: ()=>queue.length
        },
        clearQueue: {
            value: ()=>{
                queue.length = 0;
            }
        }
    });
    return generator;
};
module.exports = pLimit;
module.exports.default = pLimit;

},{"p-try":"2uVXt"}],"2uVXt":[function(require,module,exports) {
'use strict';
const pTry = (fn, ...arguments_)=>new Promise((resolve)=>{
        resolve(fn(...arguments_));
    })
;
module.exports = pTry;
// TODO: remove this in the next major version
module.exports.default = pTry;

},{}],"6p0gR":[function(require,module,exports) {
'use strict';
const Envelope = require('./envelope');
const PeerRecord = require('./peer-record');
/**
 * @typedef {import('../')} Libp2p
 */ /**
 * Create (or update if existing) self peer record and store it in the AddressBook.
 *
 * @param {Libp2p} libp2p
 * @returns {Promise<void>}
 */ async function updateSelfPeerRecord(libp2p) {
    const peerRecord = new PeerRecord({
        peerId: libp2p.peerId,
        multiaddrs: libp2p.multiaddrs
    });
    const envelope = await Envelope.seal(peerRecord, libp2p.peerId);
    libp2p.peerStore.addressBook.consumePeerRecord(envelope);
}
module.exports.updateSelfPeerRecord = updateSelfPeerRecord;

},{"./envelope":"dFiHn","./peer-record":"2gkB6"}],"2gkB6":[function(require,module,exports) {
'use strict';
const { Multiaddr  } = require('multiaddr');
const PeerId = require('peer-id');
const arrayEquals = require('libp2p-utils/src/array-equals');
const { PeerRecord: Protobuf  } = require('./peer-record');
const { ENVELOPE_DOMAIN_PEER_RECORD , ENVELOPE_PAYLOAD_TYPE_PEER_RECORD  } = require('./consts');
/**
 * @typedef {import('../../peer-store/address-book.js').Address} Address
 * @typedef {import('libp2p-interfaces/src/record/types').Record} Record
 */ /**
 * @implements {Record}
 */ class PeerRecord {
    /**
   * The PeerRecord is used for distributing peer routing records across the network.
   * It contains the peer's reachable listen addresses.
   *
   * @class
   * @param {Object} params
   * @param {PeerId} params.peerId
   * @param {Multiaddr[]} params.multiaddrs - addresses of the associated peer.
   * @param {number} [params.seqNumber] - monotonically-increasing sequence counter that's used to order PeerRecords in time.
   */ constructor({ peerId: peerId1 , multiaddrs: multiaddrs1 = [] , seqNumber: seqNumber1 = Date.now()  }){
        this.domain = ENVELOPE_DOMAIN_PEER_RECORD;
        this.codec = ENVELOPE_PAYLOAD_TYPE_PEER_RECORD;
        this.peerId = peerId1;
        this.multiaddrs = multiaddrs1;
        this.seqNumber = seqNumber1;
        // Cache
        this._marshal = undefined;
    }
    /**
   * Marshal a record to be used in an envelope.
   *
   * @returns {Uint8Array}
   */ marshal() {
        if (this._marshal) return this._marshal;
        this._marshal = Protobuf.encode({
            peerId: this.peerId.toBytes(),
            seq: this.seqNumber,
            addresses: this.multiaddrs.map((m)=>({
                    multiaddr: m.bytes
                })
            )
        }).finish();
        return this._marshal;
    }
    /**
   * Returns true if `this` record equals the `other`.
   *
   * @param {unknown} other
   * @returns {boolean}
   */ equals(other) {
        if (!(other instanceof PeerRecord)) return false;
        // Validate PeerId
        if (!this.peerId.equals(other.peerId)) return false;
        // Validate seqNumber
        if (this.seqNumber !== other.seqNumber) return false;
        // Validate multiaddrs
        if (!arrayEquals(this.multiaddrs, other.multiaddrs)) return false;
        return true;
    }
}
/**
 * Unmarshal Peer Record Protobuf.
 *
 * @param {Uint8Array} buf - marshaled peer record.
 * @returns {PeerRecord}
 */ PeerRecord.createFromProtobuf = (buf)=>{
    const peerRecord = Protobuf.decode(buf);
    const peerId = PeerId.createFromBytes(peerRecord.peerId);
    const multiaddrs = (peerRecord.addresses || []).map((a)=>new Multiaddr(a.multiaddr)
    );
    const seqNumber = Number(peerRecord.seq);
    return new PeerRecord({
        peerId,
        multiaddrs,
        seqNumber
    });
};
PeerRecord.DOMAIN = ENVELOPE_DOMAIN_PEER_RECORD;
module.exports = PeerRecord;

},{"multiaddr":"kOPrF","peer-id":"4VGWt","libp2p-utils/src/array-equals":"RsW2m","./peer-record":"gM73U","./consts":"g3tru"}],"RsW2m":[function(require,module,exports) {
'use strict';
/**
 * Verify if two arrays of non primitive types with the "equals" function are equal.
 * Compatible with multiaddr, peer-id and others.
 *
 * @param {Array<*>} a
 * @param {Array<*>} b
 * @returns {boolean}
 */ function arrayEquals(a, b) {
    return a.length === b.length && b.sort() && a.sort().every((item, index)=>b[index].equals(item)
    );
}
module.exports = arrayEquals;

},{}],"gM73U":[function(require,module,exports) {
/*eslint-disable*/ "use strict";
var $protobuf = require("protobufjs/minimal");
// Common aliases
var $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util;
// Exported root namespace
var $root = $protobuf.roots["libp2p-peer-record"] || ($protobuf.roots["libp2p-peer-record"] = {
});
$root.PeerRecord = (function() {
    /**
     * Properties of a PeerRecord.
     * @exports IPeerRecord
     * @interface IPeerRecord
     * @property {Uint8Array|null} [peerId] PeerRecord peerId
     * @property {number|null} [seq] PeerRecord seq
     * @property {Array.<PeerRecord.IAddressInfo>|null} [addresses] PeerRecord addresses
     */ /**
     * Constructs a new PeerRecord.
     * @exports PeerRecord
     * @classdesc Represents a PeerRecord.
     * @implements IPeerRecord
     * @constructor
     * @param {IPeerRecord=} [p] Properties to set
     */ function PeerRecord(p) {
        this.addresses = [];
        if (p) {
            for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
        }
    }
    /**
     * PeerRecord peerId.
     * @member {Uint8Array} peerId
     * @memberof PeerRecord
     * @instance
     */ PeerRecord.prototype.peerId = $util.newBuffer([]);
    /**
     * PeerRecord seq.
     * @member {number} seq
     * @memberof PeerRecord
     * @instance
     */ PeerRecord.prototype.seq = $util.Long ? $util.Long.fromBits(0, 0, true) : 0;
    /**
     * PeerRecord addresses.
     * @member {Array.<PeerRecord.IAddressInfo>} addresses
     * @memberof PeerRecord
     * @instance
     */ PeerRecord.prototype.addresses = $util.emptyArray;
    /**
     * Encodes the specified PeerRecord message. Does not implicitly {@link PeerRecord.verify|verify} messages.
     * @function encode
     * @memberof PeerRecord
     * @static
     * @param {IPeerRecord} m PeerRecord message or plain object to encode
     * @param {$protobuf.Writer} [w] Writer to encode to
     * @returns {$protobuf.Writer} Writer
     */ PeerRecord.encode = function encode(m, w) {
        if (!w) w = $Writer.create();
        if (m.peerId != null && Object.hasOwnProperty.call(m, "peerId")) w.uint32(10).bytes(m.peerId);
        if (m.seq != null && Object.hasOwnProperty.call(m, "seq")) w.uint32(16).uint64(m.seq);
        if (m.addresses != null && m.addresses.length) for(var i = 0; i < m.addresses.length; ++i)$root.PeerRecord.AddressInfo.encode(m.addresses[i], w.uint32(26).fork()).ldelim();
        return w;
    };
    /**
     * Decodes a PeerRecord message from the specified reader or buffer.
     * @function decode
     * @memberof PeerRecord
     * @static
     * @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
     * @param {number} [l] Message length if known beforehand
     * @returns {PeerRecord} PeerRecord
     * @throws {Error} If the payload is not a reader or valid buffer
     * @throws {$protobuf.util.ProtocolError} If required fields are missing
     */ PeerRecord.decode = function decode(r, l) {
        if (!(r instanceof $Reader)) r = $Reader.create(r);
        var c = l === undefined ? r.len : r.pos + l, m = new $root.PeerRecord();
        while(r.pos < c){
            var t = r.uint32();
            switch(t >>> 3){
                case 1:
                    m.peerId = r.bytes();
                    break;
                case 2:
                    m.seq = r.uint64();
                    break;
                case 3:
                    if (!(m.addresses && m.addresses.length)) m.addresses = [];
                    m.addresses.push($root.PeerRecord.AddressInfo.decode(r, r.uint32()));
                    break;
                default:
                    r.skipType(t & 7);
                    break;
            }
        }
        return m;
    };
    /**
     * Creates a PeerRecord message from a plain object. Also converts values to their respective internal types.
     * @function fromObject
     * @memberof PeerRecord
     * @static
     * @param {Object.<string,*>} d Plain object
     * @returns {PeerRecord} PeerRecord
     */ PeerRecord.fromObject = function fromObject(d) {
        if (d instanceof $root.PeerRecord) return d;
        var m = new $root.PeerRecord();
        if (d.peerId != null) {
            if (typeof d.peerId === "string") $util.base64.decode(d.peerId, m.peerId = $util.newBuffer($util.base64.length(d.peerId)), 0);
            else if (d.peerId.length) m.peerId = d.peerId;
        }
        if (d.seq != null) {
            if ($util.Long) (m.seq = $util.Long.fromValue(d.seq)).unsigned = true;
            else if (typeof d.seq === "string") m.seq = parseInt(d.seq, 10);
            else if (typeof d.seq === "number") m.seq = d.seq;
            else if (typeof d.seq === "object") m.seq = new $util.LongBits(d.seq.low >>> 0, d.seq.high >>> 0).toNumber(true);
        }
        if (d.addresses) {
            if (!Array.isArray(d.addresses)) throw TypeError(".PeerRecord.addresses: array expected");
            m.addresses = [];
            for(var i = 0; i < d.addresses.length; ++i){
                if (typeof d.addresses[i] !== "object") throw TypeError(".PeerRecord.addresses: object expected");
                m.addresses[i] = $root.PeerRecord.AddressInfo.fromObject(d.addresses[i]);
            }
        }
        return m;
    };
    /**
     * Creates a plain object from a PeerRecord message. Also converts values to other types if specified.
     * @function toObject
     * @memberof PeerRecord
     * @static
     * @param {PeerRecord} m PeerRecord
     * @param {$protobuf.IConversionOptions} [o] Conversion options
     * @returns {Object.<string,*>} Plain object
     */ PeerRecord.toObject = function toObject(m, o) {
        if (!o) o = {
        };
        var d = {
        };
        if (o.arrays || o.defaults) d.addresses = [];
        if (o.defaults) {
            if (o.bytes === String) d.peerId = "";
            else {
                d.peerId = [];
                if (o.bytes !== Array) d.peerId = $util.newBuffer(d.peerId);
            }
            if ($util.Long) {
                var n = new $util.Long(0, 0, true);
                d.seq = o.longs === String ? n.toString() : o.longs === Number ? n.toNumber() : n;
            } else d.seq = o.longs === String ? "0" : 0;
        }
        if (m.peerId != null && m.hasOwnProperty("peerId")) d.peerId = o.bytes === String ? $util.base64.encode(m.peerId, 0, m.peerId.length) : o.bytes === Array ? Array.prototype.slice.call(m.peerId) : m.peerId;
        if (m.seq != null && m.hasOwnProperty("seq")) {
            if (typeof m.seq === "number") d.seq = o.longs === String ? String(m.seq) : m.seq;
            else d.seq = o.longs === String ? $util.Long.prototype.toString.call(m.seq) : o.longs === Number ? new $util.LongBits(m.seq.low >>> 0, m.seq.high >>> 0).toNumber(true) : m.seq;
        }
        if (m.addresses && m.addresses.length) {
            d.addresses = [];
            for(var j = 0; j < m.addresses.length; ++j)d.addresses[j] = $root.PeerRecord.AddressInfo.toObject(m.addresses[j], o);
        }
        return d;
    };
    /**
     * Converts this PeerRecord to JSON.
     * @function toJSON
     * @memberof PeerRecord
     * @instance
     * @returns {Object.<string,*>} JSON object
     */ PeerRecord.prototype.toJSON = function toJSON() {
        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
    };
    PeerRecord.AddressInfo = (function() {
        /**
         * Properties of an AddressInfo.
         * @memberof PeerRecord
         * @interface IAddressInfo
         * @property {Uint8Array|null} [multiaddr] AddressInfo multiaddr
         */ /**
         * Constructs a new AddressInfo.
         * @memberof PeerRecord
         * @classdesc Represents an AddressInfo.
         * @implements IAddressInfo
         * @constructor
         * @param {PeerRecord.IAddressInfo=} [p] Properties to set
         */ function AddressInfo(p) {
            if (p) {
                for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
            }
        }
        /**
         * AddressInfo multiaddr.
         * @member {Uint8Array} multiaddr
         * @memberof PeerRecord.AddressInfo
         * @instance
         */ AddressInfo.prototype.multiaddr = $util.newBuffer([]);
        /**
         * Encodes the specified AddressInfo message. Does not implicitly {@link PeerRecord.AddressInfo.verify|verify} messages.
         * @function encode
         * @memberof PeerRecord.AddressInfo
         * @static
         * @param {PeerRecord.IAddressInfo} m AddressInfo message or plain object to encode
         * @param {$protobuf.Writer} [w] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */ AddressInfo.encode = function encode(m, w) {
            if (!w) w = $Writer.create();
            if (m.multiaddr != null && Object.hasOwnProperty.call(m, "multiaddr")) w.uint32(10).bytes(m.multiaddr);
            return w;
        };
        /**
         * Decodes an AddressInfo message from the specified reader or buffer.
         * @function decode
         * @memberof PeerRecord.AddressInfo
         * @static
         * @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
         * @param {number} [l] Message length if known beforehand
         * @returns {PeerRecord.AddressInfo} AddressInfo
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */ AddressInfo.decode = function decode(r, l) {
            if (!(r instanceof $Reader)) r = $Reader.create(r);
            var c = l === undefined ? r.len : r.pos + l, m = new $root.PeerRecord.AddressInfo();
            while(r.pos < c){
                var t = r.uint32();
                switch(t >>> 3){
                    case 1:
                        m.multiaddr = r.bytes();
                        break;
                    default:
                        r.skipType(t & 7);
                        break;
                }
            }
            return m;
        };
        /**
         * Creates an AddressInfo message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof PeerRecord.AddressInfo
         * @static
         * @param {Object.<string,*>} d Plain object
         * @returns {PeerRecord.AddressInfo} AddressInfo
         */ AddressInfo.fromObject = function fromObject(d) {
            if (d instanceof $root.PeerRecord.AddressInfo) return d;
            var m = new $root.PeerRecord.AddressInfo();
            if (d.multiaddr != null) {
                if (typeof d.multiaddr === "string") $util.base64.decode(d.multiaddr, m.multiaddr = $util.newBuffer($util.base64.length(d.multiaddr)), 0);
                else if (d.multiaddr.length) m.multiaddr = d.multiaddr;
            }
            return m;
        };
        /**
         * Creates a plain object from an AddressInfo message. Also converts values to other types if specified.
         * @function toObject
         * @memberof PeerRecord.AddressInfo
         * @static
         * @param {PeerRecord.AddressInfo} m AddressInfo
         * @param {$protobuf.IConversionOptions} [o] Conversion options
         * @returns {Object.<string,*>} Plain object
         */ AddressInfo.toObject = function toObject(m, o) {
            if (!o) o = {
            };
            var d = {
            };
            if (o.defaults) {
                if (o.bytes === String) d.multiaddr = "";
                else {
                    d.multiaddr = [];
                    if (o.bytes !== Array) d.multiaddr = $util.newBuffer(d.multiaddr);
                }
            }
            if (m.multiaddr != null && m.hasOwnProperty("multiaddr")) d.multiaddr = o.bytes === String ? $util.base64.encode(m.multiaddr, 0, m.multiaddr.length) : o.bytes === Array ? Array.prototype.slice.call(m.multiaddr) : m.multiaddr;
            return d;
        };
        /**
         * Converts this AddressInfo to JSON.
         * @function toJSON
         * @memberof PeerRecord.AddressInfo
         * @instance
         * @returns {Object.<string,*>} JSON object
         */ AddressInfo.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };
        return AddressInfo;
    })();
    return PeerRecord;
})();
module.exports = $root;

},{"protobufjs/minimal":"9Jmso"}],"g3tru":[function(require,module,exports) {
'use strict';
// The domain string used for peer records contained in a Envelope.
const domain = 'libp2p-peer-record';
// The type hint used to identify peer records in a Envelope.
// Defined in https://github.com/multiformats/multicodec/blob/master/table.csv
// with name "libp2p-peer-record"
const payloadType = Uint8Array.from([
    3,
    1
]);
module.exports = {
    ENVELOPE_DOMAIN_PEER_RECORD: domain,
    ENVELOPE_PAYLOAD_TYPE_PEER_RECORD: payloadType
};

},{}],"kRtIc":[function(require,module,exports) {
'use strict';
const { EventEmitter  } = require('events');
const { Multiaddr  } = require('multiaddr');
const PeerId = require('peer-id');
/**
 * @typedef {Object} AddressManagerOptions
 * @property {string[]} [listen = []] - list of multiaddrs string representation to listen.
 * @property {string[]} [announce = []] - list of multiaddrs string representation to announce.
 */ /**
 * @fires AddressManager#change:addresses Emitted when a addresses change.
 */ class AddressManager extends EventEmitter {
    /**
   * Responsible for managing the peer addresses.
   * Peers can specify their listen and announce addresses.
   * The listen addresses will be used by the libp2p transports to listen for new connections,
   * while the announce addresses will be used for the peer addresses' to other peers in the network.
   *
   * @class
   * @param {PeerId} peerId - The Peer ID of the node
   * @param {object} [options]
   * @param {Array<string>} [options.listen = []] - list of multiaddrs string representation to listen.
   * @param {Array<string>} [options.announce = []] - list of multiaddrs string representation to announce.
   */ constructor(peerId, { listen =[] , announce =[]  } = {
    }){
        super();
        this.peerId = peerId;
        this.listen = new Set(listen.map((ma)=>ma.toString()
        ));
        this.announce = new Set(announce.map((ma)=>ma.toString()
        ));
        this.observed = new Set();
    }
    /**
   * Get peer listen multiaddrs.
   *
   * @returns {Multiaddr[]}
   */ getListenAddrs() {
        return Array.from(this.listen).map((a)=>new Multiaddr(a)
        );
    }
    /**
   * Get peer announcing multiaddrs.
   *
   * @returns {Multiaddr[]}
   */ getAnnounceAddrs() {
        return Array.from(this.announce).map((a)=>new Multiaddr(a)
        );
    }
    /**
   * Get observed multiaddrs.
   *
   * @returns {Array<Multiaddr>}
   */ getObservedAddrs() {
        return Array.from(this.observed).map((a)=>new Multiaddr(a)
        );
    }
    /**
   * Add peer observed addresses
   *
   * @param {string | Multiaddr} addr
   */ addObservedAddr(addr) {
        let ma = new Multiaddr(addr);
        const remotePeer = ma.getPeerId();
        // strip our peer id if it has been passed
        if (remotePeer) {
            const remotePeerId = PeerId.createFromB58String(remotePeer);
            // use same encoding for comparison
            if (remotePeerId.equals(this.peerId)) ma = ma.decapsulate(new Multiaddr(`/p2p/${this.peerId}`));
        }
        const addrString = ma.toString();
        // do not trigger the change:addresses event if we already know about this address
        if (this.observed.has(addrString)) return;
        this.observed.add(addrString);
        this.emit('change:addresses');
    }
}
module.exports = AddressManager;

},{"events":"bHM3D","multiaddr":"kOPrF","peer-id":"4VGWt"}],"RxH4d":[function(require,module,exports) {
'use strict';
const debug = require('debug');
const log = Object.assign(debug('libp2p:connection-manager'), {
    error: debug('libp2p:connection-manager:err')
});
const errcode = require('err-code');
const mergeOptions = require('merge-options');
const LatencyMonitor = require('./latency-monitor');
// @ts-ignore retimer does not have types
const retimer = require('retimer');
const { EventEmitter  } = require('events');
const PeerId = require('peer-id');
const { codes: { ERR_INVALID_PARAMETERS  }  } = require('../errors');
const defaultOptions = {
    maxConnections: Infinity,
    minConnections: 0,
    maxData: Infinity,
    maxSentData: Infinity,
    maxReceivedData: Infinity,
    maxEventLoopDelay: Infinity,
    pollInterval: 2000,
    autoDialInterval: 10000,
    movingAverageInterval: 60000,
    defaultPeerValue: 1
};
/**
 * @typedef {import('../')} Libp2p
 * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection
 */ /**
 * @typedef {Object} ConnectionManagerOptions
 * @property {number} [maxConnections = Infinity] - The maximum number of connections allowed.
 * @property {number} [minConnections = 0] - The minimum number of connections to avoid pruning.
 * @property {number} [maxData = Infinity] - The max data (in and out), per average interval to allow.
 * @property {number} [maxSentData = Infinity] - The max outgoing data, per average interval to allow.
 * @property {number} [maxReceivedData = Infinity] - The max incoming data, per average interval to allow.
 * @property {number} [maxEventLoopDelay = Infinity] - The upper limit the event loop can take to run.
 * @property {number} [pollInterval = 2000] - How often, in milliseconds, metrics and latency should be checked.
 * @property {number} [movingAverageInterval = 60000] - How often, in milliseconds, to compute averages.
 * @property {number} [defaultPeerValue = 1] - The value of the peer.
 * @property {boolean} [autoDial = true] - Should preemptively guarantee connections are above the low watermark.
 * @property {number} [autoDialInterval = 10000] - How often, in milliseconds, it should preemptively guarantee connections are above the low watermark.
 */ /**
 *
 * @fires ConnectionManager#peer:connect Emitted when a new peer is connected.
 * @fires ConnectionManager#peer:disconnect Emitted when a peer is disconnected.
 */ class ConnectionManager extends EventEmitter {
    /**
   * Responsible for managing known connections.
   *
   * @class
   * @param {Libp2p} libp2p
   * @param {ConnectionManagerOptions} options
   */ constructor(libp2p, options = {
    }){
        super();
        this._libp2p = libp2p;
        this._peerId = libp2p.peerId.toB58String();
        this._options = mergeOptions.call({
            ignoreUndefined: true
        }, defaultOptions, options);
        if (this._options.maxConnections < this._options.minConnections) throw errcode(new Error('Connection Manager maxConnections must be greater than minConnections'), ERR_INVALID_PARAMETERS);
        log('options: %j', this._options);
        /**
     * Map of peer identifiers to their peer value for pruning connections.
     *
     * @type {Map<string, number>}
     */ this._peerValues = new Map();
        /**
     * Map of connections per peer
     *
     * @type {Map<string, Connection[]>}
     */ this.connections = new Map();
        this._started = false;
        this._timer = null;
        this._autoDialTimeout = null;
        this._checkMetrics = this._checkMetrics.bind(this);
        this._autoDial = this._autoDial.bind(this);
        this._latencyMonitor = new LatencyMonitor({
            latencyCheckIntervalMs: this._options.pollInterval,
            dataEmitIntervalMs: this._options.pollInterval
        });
    }
    /**
   * Get current number of open connections.
   */ get size() {
        return Array.from(this.connections.values()).reduce((accumulator, value)=>accumulator + value.length
        , 0);
    }
    /**
   * Starts the Connection Manager. If Metrics are not enabled on libp2p
   * only event loop and connection limits will be monitored.
   */ start() {
        if (this._libp2p.metrics) this._timer = this._timer || retimer(this._checkMetrics, this._options.pollInterval);
        // latency monitor
        this._latencyMonitor.start();
        this._onLatencyMeasure = this._onLatencyMeasure.bind(this);
        this._latencyMonitor.on('data', this._onLatencyMeasure);
        this._started = true;
        log('started');
        this._options.autoDial && this._autoDial();
    }
    /**
   * Stops the Connection Manager
   *
   * @async
   */ async stop() {
        this._autoDialTimeout && this._autoDialTimeout.clear();
        this._timer && this._timer.clear();
        this._latencyMonitor.removeListener('data', this._onLatencyMeasure);
        this._latencyMonitor.stop();
        this._started = false;
        await this._close();
        log('stopped');
    }
    /**
   * Cleans up the connections
   *
   * @async
   */ async _close() {
        // Close all connections we're tracking
        const tasks = [];
        for (const connectionList of this.connections.values())for (const connection of connectionList)tasks.push(connection.close());
        await Promise.all(tasks);
        this.connections.clear();
    }
    /**
   * Sets the value of the given peer. Peers with lower values
   * will be disconnected first.
   *
   * @param {PeerId} peerId
   * @param {number} value - A number between 0 and 1
   * @returns {void}
   */ setPeerValue(peerId, value) {
        if (value < 0 || value > 1) throw new Error('value should be a number between 0 and 1');
        this._peerValues.set(peerId.toB58String(), value);
    }
    /**
   * Checks the libp2p metrics to determine if any values have exceeded
   * the configured maximums.
   *
   * @private
   */ _checkMetrics() {
        if (this._libp2p.metrics) {
            const movingAverages = this._libp2p.metrics.global.movingAverages;
            // @ts-ignore moving averages object types
            const received = movingAverages.dataReceived[this._options.movingAverageInterval].movingAverage();
            this._checkMaxLimit('maxReceivedData', received);
            // @ts-ignore moving averages object types
            const sent = movingAverages.dataSent[this._options.movingAverageInterval].movingAverage();
            this._checkMaxLimit('maxSentData', sent);
            const total = received + sent;
            this._checkMaxLimit('maxData', total);
            log('metrics update', total);
            this._timer = retimer(this._checkMetrics, this._options.pollInterval);
        }
    }
    /**
   * Tracks the incoming connection and check the connection limit
   *
   * @param {Connection} connection
   * @returns {void}
   */ onConnect(connection2) {
        const peerId = connection2.remotePeer;
        const peerIdStr = peerId.toB58String();
        const storedConn = this.connections.get(peerIdStr);
        this.emit('peer:connect', connection2);
        if (storedConn) storedConn.push(connection2);
        else this.connections.set(peerIdStr, [
            connection2
        ]);
        this._libp2p.peerStore.keyBook.set(peerId, peerId.pubKey);
        if (!this._peerValues.has(peerIdStr)) this._peerValues.set(peerIdStr, this._options.defaultPeerValue);
        this._checkMaxLimit('maxConnections', this.size);
    }
    /**
   * Removes the connection from tracking
   *
   * @param {Connection} connection
   * @returns {void}
   */ onDisconnect(connection1) {
        const peerId = connection1.remotePeer.toB58String();
        let storedConn = this.connections.get(peerId);
        if (storedConn && storedConn.length > 1) {
            storedConn = storedConn.filter((conn)=>conn.id !== connection1.id
            );
            this.connections.set(peerId, storedConn);
        } else if (storedConn) {
            this.connections.delete(peerId);
            this._peerValues.delete(connection1.remotePeer.toB58String());
            this.emit('peer:disconnect', connection1);
        }
    }
    /**
   * Get a connection with a peer.
   *
   * @param {PeerId} peerId
   * @returns {Connection|null}
   */ get(peerId1) {
        const connections = this.getAll(peerId1);
        if (connections.length) return connections[0];
        return null;
    }
    /**
   * Get all open connections with a peer.
   *
   * @param {PeerId} peerId
   * @returns {Connection[]}
   */ getAll(peerId2) {
        if (!PeerId.isPeerId(peerId2)) throw errcode(new Error('peerId must be an instance of peer-id'), ERR_INVALID_PARAMETERS);
        const id = peerId2.toB58String();
        const connections = this.connections.get(id);
        // Return all open connections
        if (connections) return connections.filter((connection)=>connection.stat.status === 'open'
        );
        return [];
    }
    /**
   * If the event loop is slow, maybe close a connection
   *
   * @private
   * @param {*} summary - The LatencyMonitor summary
   */ _onLatencyMeasure(summary) {
        this._checkMaxLimit('maxEventLoopDelay', summary.avgMs);
    }
    /**
   * If the `value` of `name` has exceeded its limit, maybe close a connection
   *
   * @private
   * @param {string} name - The name of the field to check limits for
   * @param {number} value - The current value of the field
   */ _checkMaxLimit(name, value1) {
        const limit = this._options[name];
        log('checking limit of %s. current value: %d of %d', name, value1, limit);
        if (value1 > limit) {
            log('%s: limit exceeded: %s, %d', this._peerId, name, value1);
            this._maybeDisconnectOne();
        }
    }
    /**
   * Proactively tries to connect to known peers stored in the PeerStore.
   * It will keep the number of connections below the upper limit and sort
   * the peers to connect based on wether we know their keys and protocols.
   *
   * @async
   * @private
   */ async _autoDial() {
        const minConnections = this._options.minConnections;
        // Already has enough connections
        if (this.size >= minConnections) {
            this._autoDialTimeout = retimer(this._autoDial, this._options.autoDialInterval);
            return;
        }
        // Sort peers on wether we know protocols of public keys for them
        const peers = Array.from(this._libp2p.peerStore.peers.values()).sort((a, b)=>{
            if (b.protocols && b.protocols.length && (!a.protocols || !a.protocols.length)) return 1;
            else if (b.id.pubKey && !a.id.pubKey) return 1;
            return -1;
        });
        for(let i = 0; i < peers.length && this.size < minConnections; i++)if (!this.get(peers[i].id)) {
            log('connecting to a peerStore stored peer %s', peers[i].id.toB58String());
            try {
                await this._libp2p.dialer.connectToPeer(peers[i].id);
                // Connection Manager was stopped
                if (!this._started) return;
            } catch (err) {
                log.error('could not connect to peerStore stored peer', err);
            }
        }
        this._autoDialTimeout = retimer(this._autoDial, this._options.autoDialInterval);
    }
    /**
   * If we have more connections than our maximum, close a connection
   * to the lowest valued peer.
   *
   * @private
   */ _maybeDisconnectOne() {
        if (this._options.minConnections < this.connections.size) {
            const peerValues = Array.from(new Map([
                ...this._peerValues.entries()
            ].sort((a, b)=>a[1] - b[1]
            )));
            log('%s: sorted peer values: %j', this._peerId, peerValues);
            const disconnectPeer = peerValues[0];
            if (disconnectPeer) {
                const peerId = disconnectPeer[0];
                log('%s: lowest value peer is %s', this._peerId, peerId);
                log('%s: closing a connection to %j', this._peerId, peerId);
                for (const connections of this.connections.values())if (connections[0].remotePeer.toB58String() === peerId) {
                    connections[0].close();
                    break;
                }
            }
        }
    }
}
module.exports = ConnectionManager;

},{"debug":"lWlU4","err-code":"eQvyh","merge-options":"8VjFj","./latency-monitor":"irzjt","retimer":"kYXdk","events":"bHM3D","peer-id":"4VGWt","../errors":"dO31S"}],"irzjt":[function(require,module,exports) {
// @ts-nocheck
'use strict';
/**
 * This code is based on `latency-monitor` (https://github.com/mlucool/latency-monitor) by `mlucool` (https://github.com/mlucool), available under Apache License 2.0 (https://github.com/mlucool/latency-monitor/blob/master/LICENSE)
 */ const { EventEmitter  } = require('events');
const VisibilityChangeEmitter = require('./visibility-change-emitter');
const debug = require('debug')('latency-monitor:LatencyMonitor');
/**
 * @typedef {Object} SummaryObject
 * @property {number} events How many events were called
 * @property {number} minMS What was the min time for a cb to be called
 * @property {number} maxMS What was the max time for a cb to be called
 * @property {number} avgMs What was the average time for a cb to be called
 * @property {number} lengthMs How long this interval was in ms
 *
 * @typedef {Object} LatencyMonitorOptions
 * @property {number} [latencyCheckIntervalMs=500] - How often to add a latency check event (ms)
 * @property {number} [dataEmitIntervalMs=5000] - How often to summarize latency check events. null or 0 disables event firing
 * @property {Function} [asyncTestFn] - What cb-style async function to use
 * @property {number} [latencyRandomPercentage=5] - What percent (+/-) of latencyCheckIntervalMs should we randomly use? This helps avoid alignment to other events.
 */ /**
 * A class to monitor latency of any async function which works in a browser or node. This works by periodically calling
 * the asyncTestFn and timing how long it takes the callback to be called. It can also periodically emit stats about this.
 * This can be disabled and stats can be pulled via setting dataEmitIntervalMs = 0.
 *
 * @extends {EventEmitter}
 *
 * The default implementation is an event loop latency monitor. This works by firing periodic events into the event loop
 * and timing how long it takes to get back.
 *
 * @example
 * const monitor = new LatencyMonitor();
 * monitor.on('data', (summary) => console.log('Event Loop Latency: %O', summary));
 *
 * @example
 * const monitor = new LatencyMonitor({latencyCheckIntervalMs: 1000, dataEmitIntervalMs: 60000, asyncTestFn:ping});
 * monitor.on('data', (summary) => console.log('Ping Pong Latency: %O', summary));
 */ class LatencyMonitor extends EventEmitter {
    /**
   * @class
   * @param {LatencyMonitorOptions} [options]
   */ constructor({ latencyCheckIntervalMs , dataEmitIntervalMs , asyncTestFn , latencyRandomPercentage  } = {
    }){
        super();
        const that = this;
        // 0 isn't valid here, so its ok to use ||
        that.latencyCheckIntervalMs = latencyCheckIntervalMs || 500 // 0.5s
        ;
        that.latencyRandomPercentage = latencyRandomPercentage || 10;
        that._latecyCheckMultiply = 2 * (that.latencyRandomPercentage / 100) * that.latencyCheckIntervalMs;
        that._latecyCheckSubtract = that._latecyCheckMultiply / 2;
        that.dataEmitIntervalMs = dataEmitIntervalMs === null || dataEmitIntervalMs === 0 ? undefined : dataEmitIntervalMs || 5000 // 5s
        ;
        debug('latencyCheckIntervalMs: %s dataEmitIntervalMs: %s', that.latencyCheckIntervalMs, that.dataEmitIntervalMs);
        if (that.dataEmitIntervalMs) debug('Expecting ~%s events per summary', that.latencyCheckIntervalMs / that.dataEmitIntervalMs);
        else debug('Not emitting summaries');
        that.asyncTestFn = asyncTestFn // If there is no asyncFn, we measure latency
        ;
    }
    start() {
        // If process: use high resolution timer
        if (globalThis.process && globalThis.process.hrtime) {
            debug('Using process.hrtime for timing');
            this.now = globalThis.process.hrtime // eslint-disable-line no-undef
            ;
            this.getDeltaMS = (startTime)=>{
                const hrtime = this.now(startTime);
                return hrtime[0] * 1000 + hrtime[1] / 1000000;
            };
        // Let's try for a timer that only monotonically increases
        } else if (typeof window !== 'undefined' && window.performance && window.performance.now) {
            debug('Using performance.now for timing');
            this.now = window.performance.now.bind(window.performance);
            this.getDeltaMS = (startTime)=>Math.round(this.now() - startTime)
            ;
        } else {
            debug('Using Date.now for timing');
            this.now = Date.now;
            this.getDeltaMS = (startTime)=>this.now() - startTime
            ;
        }
        this._latencyData = this._initLatencyData();
        // We check for isBrowser because of browsers set max rates of timeouts when a page is hidden,
        // so we fall back to another library
        // See: http://stackoverflow.com/questions/6032429/chrome-timeouts-interval-suspended-in-background-tabs
        if (isBrowser()) {
            this._visibilityChangeEmitter = new VisibilityChangeEmitter();
            this._visibilityChangeEmitter.on('visibilityChange', (pageInFocus)=>{
                if (pageInFocus) this._startTimers();
                else {
                    this._emitSummary();
                    this._stopTimers();
                }
            });
        }
        if (!this._visibilityChangeEmitter || this._visibilityChangeEmitter.isVisible()) this._startTimers();
    }
    stop() {
        this._stopTimers();
    }
    /**
   * Start internal timers
   *
   * @private
   */ _startTimers() {
        // Timer already started, ignore this
        if (this._checkLatencyID) return;
        this._checkLatency();
        if (this.dataEmitIntervalMs) {
            this._emitIntervalID = setInterval(()=>this._emitSummary()
            , this.dataEmitIntervalMs);
            if (typeof this._emitIntervalID.unref === 'function') this._emitIntervalID.unref() // Doesn't block exit
            ;
        }
    }
    /**
   * Stop internal timers
   *
   * @private
   */ _stopTimers() {
        if (this._checkLatencyID) {
            clearTimeout(this._checkLatencyID);
            this._checkLatencyID = undefined;
        }
        if (this._emitIntervalID) {
            clearInterval(this._emitIntervalID);
            this._emitIntervalID = undefined;
        }
    }
    /**
   * Emit summary only if there were events. It might not have any events if it was forced via a page hidden/show
   *
   * @private
   */ _emitSummary() {
        const summary = this.getSummary();
        if (summary.events > 0) this.emit('data', summary);
    }
    /**
   * Calling this function will end the collection period. If a timing event was already fired and somewhere in the queue,
   * it will not count for this time period
   *
   * @returns {SummaryObject}
   */ getSummary() {
        // We might want to adjust for the number of expected events
        // Example: first 1 event it comes back, then such a long blocker that the next emit check comes
        // Then this fires - looks like no latency!!
        const latency = {
            events: this._latencyData.events,
            minMs: this._latencyData.minMs,
            maxMs: this._latencyData.maxMs,
            avgMs: this._latencyData.events ? this._latencyData.totalMs / this._latencyData.events : Number.POSITIVE_INFINITY,
            lengthMs: this.getDeltaMS(this._latencyData.startTime)
        };
        this._latencyData = this._initLatencyData() // Clear
        ;
        debug('Summary: %O', latency);
        return latency;
    }
    /**
   * Randomly calls an async fn every roughly latencyCheckIntervalMs (plus some randomness). If no async fn is found,
   * it will simply report on event loop latency.
   *
   * @private
   */ _checkLatency() {
        const that = this;
        // Randomness is needed to avoid alignment by accident to regular things in the event loop
        const randomness = Math.random() * that._latecyCheckMultiply - that._latecyCheckSubtract;
        // We use this to ensure that in case some overlap somehow, we don't take the wrong startTime/offset
        const localData = {
            deltaOffset: Math.ceil(that.latencyCheckIntervalMs + randomness),
            startTime: that.now()
        };
        const cb = ()=>{
            // We are already stopped, ignore this datapoint
            if (!this._checkLatencyID) return;
            const deltaMS = that.getDeltaMS(localData.startTime) - localData.deltaOffset;
            that._checkLatency() // Start again ASAP
            ;
            // Add the data point. If this gets complex, refactor it
            that._latencyData.events++;
            that._latencyData.minMs = Math.min(that._latencyData.minMs, deltaMS);
            that._latencyData.maxMs = Math.max(that._latencyData.maxMs, deltaMS);
            that._latencyData.totalMs += deltaMS;
            debug('MS: %s Data: %O', deltaMS, that._latencyData);
        };
        debug('localData: %O', localData);
        this._checkLatencyID = setTimeout(()=>{
            // This gets rid of including event loop
            if (that.asyncTestFn) {
                // Clear timing related things
                localData.deltaOffset = 0;
                localData.startTime = that.now();
                that.asyncTestFn(cb);
            } else {
                // setTimeout is not more accurate than 1ms, so this will ensure positive numbers. Add 1 to emitted data to remove.
                // This is not the best, but for now it'll be just fine. This isn't meant to be sub ms accurate.
                localData.deltaOffset -= 1;
                // If there is no function to test, we mean check latency which is a special case that is really cb => cb()
                // We avoid that for the few extra function all overheads. Also, we want to keep the timers different
                cb();
            }
        }, localData.deltaOffset);
        if (typeof this._checkLatencyID.unref === 'function') this._checkLatencyID.unref() // Doesn't block exit
        ;
    }
    _initLatencyData() {
        return {
            startTime: this.now(),
            minMs: Number.POSITIVE_INFINITY,
            maxMs: Number.NEGATIVE_INFINITY,
            events: 0,
            totalMs: 0
        };
    }
}
function isBrowser() {
    return typeof window !== 'undefined';
}
module.exports = LatencyMonitor;

},{"events":"bHM3D","./visibility-change-emitter":"bUKSL","debug":"lWlU4"}],"bUKSL":[function(require,module,exports) {
// @ts-nocheck
/* global document */ /**
 * This code is based on `latency-monitor` (https://github.com/mlucool/latency-monitor) by `mlucool` (https://github.com/mlucool), available under Apache License 2.0 (https://github.com/mlucool/latency-monitor/blob/master/LICENSE)
 */ 'use strict';
const { EventEmitter  } = require('events');
const debug = require('debug')('latency-monitor:VisibilityChangeEmitter');
/**
 * Listen to page visibility change events (i.e. when the page is focused / blurred) by an event emitter.
 *
 * Warning: This does not work on all browsers, but should work on all modern browsers
 *
 * @example
 *
 *     const myVisibilityEmitter = new VisibilityChangeEmitter();
 *
 *     myVisibilityEmitter.on('visibilityChange', (pageInFocus) => {
 *        if ( pageInFocus ){
 *            // Page is in focus
 *            console.log('In focus');
 *        }
 *        else {
 *            // Page is blurred
 *            console.log('Out of focus');
 *        }
 *     });
 *     // To access the visibility state directly, call:
 *     console.log('Am I focused now? ' + myVisibilityEmitter.isVisible());
 */ class VisibilityChangeEmitter extends EventEmitter {
    /**
   * Creates a VisibilityChangeEmitter
   *
   * @class
   */ constructor(){
        super();
        if (typeof document === 'undefined') {
            debug('This is not a browser, no "document" found. Stopping.');
            return;
        }
        this._initializeVisibilityVarNames();
        this._addVisibilityChangeListener();
    }
    /**
   * document.hidden and document.visibilityChange are the two variables we need to check for;
   * Since these variables are named differently in different browsers, this function sets
   * the appropriate name based on the browser being used. Once executed, tha actual names of
   * document.hidden and document.visibilityChange are found in this._hidden and this._visibilityChange
   * respectively
   *
   * @private
   */ _initializeVisibilityVarNames() {
        let hidden;
        let visibilityChange;
        if (typeof document.hidden !== 'undefined') {
            hidden = 'hidden';
            visibilityChange = 'visibilitychange';
        } else if (typeof document.mozHidden !== 'undefined') {
            hidden = 'mozHidden';
            visibilityChange = 'mozvisibilitychange';
        } else if (typeof document.msHidden !== 'undefined') {
            hidden = 'msHidden';
            visibilityChange = 'msvisibilitychange';
        } else if (typeof document.webkitHidden !== 'undefined') {
            hidden = 'webkitHidden';
            visibilityChange = 'webkitvisibilitychange';
        }
        this._hidden = hidden;
        this._visibilityChange = visibilityChange;
    }
    /**
   * Adds an event listener on the document that listens to changes in document.visibilityChange
   * (or whatever name by which the visibilityChange variable is known in the browser)
   *
   * @private
   */ _addVisibilityChangeListener() {
        if (typeof document.addEventListener === 'undefined' || typeof document[this._hidden] === 'undefined') debug('Checking page visibility requires a browser that supports the Page Visibility API.');
        else // Handle page visibility change
        document.addEventListener(this._visibilityChange, this._handleVisibilityChange.bind(this), false);
    }
    /**
   * The function returns ```true``` if the page is visible or ```false``` if the page is not visible and
   * ```undefined``` if the page visibility API is not supported by the browser.
   *
   * @returns {boolean | void} whether the page is now visible or not (undefined is unknown)
   */ isVisible() {
        if (this._hidden === undefined || document[this._hidden] === undefined) return undefined;
        return !document[this._hidden];
    }
    /**
   * The function that is called when document.visibilityChange has changed
   * It emits an event called visibilityChange and sends the value of document.hidden as a
   * parameter
   *
   * @private
   */ _handleVisibilityChange() {
        const visible = !document[this._hidden];
        debug(visible ? 'Page Visible' : 'Page Hidden');
        // Emit the event
        this.emit('visibilityChange', visible);
    }
}
module.exports = VisibilityChangeEmitter;

},{"events":"bHM3D","debug":"lWlU4"}],"kYXdk":[function(require,module,exports) {
'use strict';
const getTime = require('./time');
class Retimer {
    constructor(callback, timeout, args1){
        const that = this;
        this._started = getTime();
        this._rescheduled = 0;
        this._scheduled = timeout;
        this._args = args1;
        this._triggered = false;
        this._timerWrapper = ()=>{
            if (that._rescheduled > 0) {
                that._scheduled = that._rescheduled - (getTime() - that._started);
                that._schedule(that._scheduled);
            } else {
                that._triggered = true;
                callback.apply(null, that._args);
            }
        };
        this._timer = setTimeout(this._timerWrapper, timeout);
    }
    reschedule(timeout1) {
        if (!timeout1) timeout1 = this._scheduled;
        const now = getTime();
        if (now + timeout1 - (this._started + this._scheduled) < 0) {
            clearTimeout(this._timer);
            this._schedule(timeout1);
        } else if (!this._triggered) {
            this._started = now;
            this._rescheduled = timeout1;
        } else this._schedule(timeout1);
    }
    _schedule(timeout2) {
        this._triggered = false;
        this._started = getTime();
        this._rescheduled = 0;
        this._scheduled = timeout2;
        this._timer = setTimeout(this._timerWrapper, timeout2);
    }
    clear() {
        clearTimeout(this._timer);
    }
}
function retimer() {
    if (typeof arguments[0] !== 'function') throw new Error('callback needed');
    if (typeof arguments[1] !== 'number') throw new Error('timeout needed');
    let args;
    if (arguments.length > 0) {
        args = new Array(arguments.length - 2);
        /* eslint-disable no-var */ for(var i = 0; i < args.length; i++)args[i] = arguments[i + 2];
    }
    return new Retimer(arguments[0], arguments[1], args);
}
module.exports = retimer;

},{"./time":"jmFVE"}],"jmFVE":[function(require,module,exports) {
'use strict';
module.exports = function getTime() {
    return Date.now();
};

},{}],"6Ysb8":[function(require,module,exports) {
'use strict';
const debug = require('debug');
const log = Object.assign(debug('libp2p:circuit'), {
    error: debug('libp2p:circuit:err')
});
const errCode = require('err-code');
const mafmt = require('mafmt');
const { Multiaddr  } = require('multiaddr');
const PeerId = require('peer-id');
const { CircuitRelay: CircuitPB  } = require('./protocol');
const { codes  } = require('../errors');
const toConnection = require('libp2p-utils/src/stream-to-ma-conn');
const { relay: multicodec  } = require('./multicodec');
const createListener = require('./listener');
const { handleCanHop , handleHop , hop  } = require('./circuit/hop');
const { handleStop  } = require('./circuit/stop');
const StreamHandler = require('./circuit/stream-handler');
const transportSymbol = Symbol.for('@libp2p/js-libp2p-circuit/circuit');
/**
 * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection
 * @typedef {import('libp2p-interfaces/src/stream-muxer/types').MuxedStream} MuxedStream
 */ class Circuit {
    /**
   * Creates an instance of the Circuit Transport.
   *
   * @class
   * @param {object} options
   * @param {import('../')} options.libp2p
   * @param {import('../upgrader')} options.upgrader
   */ constructor({ libp2p , upgrader  }){
        this._dialer = libp2p.dialer;
        this._registrar = libp2p.registrar;
        this._connectionManager = libp2p.connectionManager;
        this._upgrader = upgrader;
        this._options = libp2p._config.relay;
        this._libp2p = libp2p;
        this.peerId = libp2p.peerId;
        this._registrar.handle(multicodec, this._onProtocol.bind(this));
    }
    /**
   * @param {Object} props
   * @param {Connection} props.connection
   * @param {MuxedStream} props.stream
   */ async _onProtocol({ connection , stream  }) {
        /** @type {import('./circuit/stream-handler')} */ const streamHandler = new StreamHandler({
            stream
        });
        const request = await streamHandler.read();
        if (!request) return;
        const circuit = this;
        let virtualConnection;
        switch(request.type){
            case CircuitPB.Type.CAN_HOP:
                log('received CAN_HOP request from %s', connection.remotePeer.toB58String());
                await handleCanHop({
                    circuit,
                    connection,
                    streamHandler
                });
                break;
            case CircuitPB.Type.HOP:
                log('received HOP request from %s', connection.remotePeer.toB58String());
                virtualConnection = await handleHop({
                    connection,
                    request,
                    streamHandler,
                    circuit
                });
                break;
            case CircuitPB.Type.STOP:
                log('received STOP request from %s', connection.remotePeer.toB58String());
                virtualConnection = await handleStop({
                    connection,
                    request,
                    streamHandler
                });
                break;
            default:
                log('Request of type %s not supported', request.type);
        }
        if (virtualConnection) {
            // @ts-ignore dst peer will not be undefined
            const remoteAddr = new Multiaddr(request.dstPeer.addrs[0]);
            // @ts-ignore src peer will not be undefined
            const localAddr = new Multiaddr(request.srcPeer.addrs[0]);
            const maConn = toConnection({
                stream: virtualConnection,
                remoteAddr,
                localAddr
            });
            const type = request.type === CircuitPB.Type.HOP ? 'relay' : 'inbound';
            log('new %s connection %s', type, maConn.remoteAddr);
            const conn = await this._upgrader.upgradeInbound(maConn);
            log('%s connection %s upgraded', type, maConn.remoteAddr);
            this.handler && this.handler(conn);
        }
    }
    /**
   * Dial a peer over a relay
   *
   * @param {Multiaddr} ma - the multiaddr of the peer to dial
   * @param {Object} options - dial options
   * @param {AbortSignal} [options.signal] - An optional abort signal
   * @returns {Promise<Connection>} - the connection
   */ async dial(ma1, options) {
        // Check the multiaddr to see if it contains a relay and a destination peer
        const addrs = ma1.toString().split('/p2p-circuit');
        const relayAddr = new Multiaddr(addrs[0]);
        const destinationAddr = new Multiaddr(addrs[addrs.length - 1]);
        const relayId = relayAddr.getPeerId();
        const destinationId = destinationAddr.getPeerId();
        if (!relayId || !destinationId) {
            const errMsg = 'Circuit relay dial failed as addresses did not have peer id';
            log.error(errMsg);
            throw errCode(new Error(errMsg), codes.ERR_RELAYED_DIAL);
        }
        const relayPeer = PeerId.createFromB58String(relayId);
        const destinationPeer = PeerId.createFromB58String(destinationId);
        let disconnectOnFailure = false;
        let relayConnection = this._connectionManager.get(relayPeer);
        if (!relayConnection) {
            relayConnection = await this._dialer.connectToPeer(relayAddr, options);
            disconnectOnFailure = true;
        }
        try {
            const virtualConnection = await hop({
                connection: relayConnection,
                request: {
                    type: CircuitPB.Type.HOP,
                    srcPeer: {
                        id: this.peerId.toBytes(),
                        addrs: this._libp2p.multiaddrs.map((addr)=>addr.bytes
                        )
                    },
                    dstPeer: {
                        id: destinationPeer.toBytes(),
                        addrs: [
                            new Multiaddr(destinationAddr).bytes
                        ]
                    }
                }
            });
            const localAddr = relayAddr.encapsulate(`/p2p-circuit/p2p/${this.peerId.toB58String()}`);
            const maConn = toConnection({
                stream: virtualConnection,
                remoteAddr: ma1,
                localAddr
            });
            log('new outbound connection %s', maConn.remoteAddr);
            return this._upgrader.upgradeOutbound(maConn);
        } catch (err) {
            log.error('Circuit relay dial failed', err);
            disconnectOnFailure && await relayConnection.close();
            throw err;
        }
    }
    /**
   * Create a listener
   *
   * @param {any} options
   * @param {Function} handler
   * @returns {import('libp2p-interfaces/src/transport/types').Listener}
   */ createListener(options1, handler) {
        if (typeof options1 === 'function') {
            handler = options1;
            options1 = {
            };
        }
        // Called on successful HOP and STOP requests
        this.handler = handler;
        return createListener(this._libp2p);
    }
    /**
   * Filter check for all Multiaddrs that this transport can dial on
   *
   * @param {Multiaddr[]} multiaddrs
   * @returns {Multiaddr[]}
   */ filter(multiaddrs) {
        multiaddrs = Array.isArray(multiaddrs) ? multiaddrs : [
            multiaddrs
        ];
        return multiaddrs.filter((ma)=>{
            return mafmt.Circuit.matches(ma);
        });
    }
    get [Symbol.toStringTag]() {
        return 'Circuit';
    }
    /**
   * Checks if the given value is a Transport instance.
   *
   * @param {any} other
   * @returns {other is Transport}
   */ static isTransport(other) {
        return Boolean(other && other[transportSymbol]);
    }
}
module.exports = Circuit;

},{"debug":"lWlU4","err-code":"eQvyh","mafmt":"hdtcj","multiaddr":"kOPrF","peer-id":"4VGWt","./protocol":"kSXvy","../errors":"dO31S","libp2p-utils/src/stream-to-ma-conn":"fC5Br","./multicodec":"fdlQ4","./listener":"7KJrg","./circuit/hop":"63pMA","./circuit/stop":"eTYqE","./circuit/stream-handler":"87JAa"}],"kSXvy":[function(require,module,exports) {
/*eslint-disable*/ "use strict";
var $protobuf = require("protobufjs/minimal");
// Common aliases
var $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util;
// Exported root namespace
var $root = $protobuf.roots["libp2p-circuit"] || ($protobuf.roots["libp2p-circuit"] = {
});
$root.CircuitRelay = (function() {
    /**
     * Properties of a CircuitRelay.
     * @exports ICircuitRelay
     * @interface ICircuitRelay
     * @property {CircuitRelay.Type|null} [type] CircuitRelay type
     * @property {CircuitRelay.IPeer|null} [srcPeer] CircuitRelay srcPeer
     * @property {CircuitRelay.IPeer|null} [dstPeer] CircuitRelay dstPeer
     * @property {CircuitRelay.Status|null} [code] CircuitRelay code
     */ /**
     * Constructs a new CircuitRelay.
     * @exports CircuitRelay
     * @classdesc Represents a CircuitRelay.
     * @implements ICircuitRelay
     * @constructor
     * @param {ICircuitRelay=} [p] Properties to set
     */ function CircuitRelay(p) {
        if (p) {
            for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
        }
    }
    /**
     * CircuitRelay type.
     * @member {CircuitRelay.Type} type
     * @memberof CircuitRelay
     * @instance
     */ CircuitRelay.prototype.type = 1;
    /**
     * CircuitRelay srcPeer.
     * @member {CircuitRelay.IPeer|null|undefined} srcPeer
     * @memberof CircuitRelay
     * @instance
     */ CircuitRelay.prototype.srcPeer = null;
    /**
     * CircuitRelay dstPeer.
     * @member {CircuitRelay.IPeer|null|undefined} dstPeer
     * @memberof CircuitRelay
     * @instance
     */ CircuitRelay.prototype.dstPeer = null;
    /**
     * CircuitRelay code.
     * @member {CircuitRelay.Status} code
     * @memberof CircuitRelay
     * @instance
     */ CircuitRelay.prototype.code = 100;
    /**
     * Encodes the specified CircuitRelay message. Does not implicitly {@link CircuitRelay.verify|verify} messages.
     * @function encode
     * @memberof CircuitRelay
     * @static
     * @param {ICircuitRelay} m CircuitRelay message or plain object to encode
     * @param {$protobuf.Writer} [w] Writer to encode to
     * @returns {$protobuf.Writer} Writer
     */ CircuitRelay.encode = function encode(m, w) {
        if (!w) w = $Writer.create();
        if (m.type != null && Object.hasOwnProperty.call(m, "type")) w.uint32(8).int32(m.type);
        if (m.srcPeer != null && Object.hasOwnProperty.call(m, "srcPeer")) $root.CircuitRelay.Peer.encode(m.srcPeer, w.uint32(18).fork()).ldelim();
        if (m.dstPeer != null && Object.hasOwnProperty.call(m, "dstPeer")) $root.CircuitRelay.Peer.encode(m.dstPeer, w.uint32(26).fork()).ldelim();
        if (m.code != null && Object.hasOwnProperty.call(m, "code")) w.uint32(32).int32(m.code);
        return w;
    };
    /**
     * Decodes a CircuitRelay message from the specified reader or buffer.
     * @function decode
     * @memberof CircuitRelay
     * @static
     * @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
     * @param {number} [l] Message length if known beforehand
     * @returns {CircuitRelay} CircuitRelay
     * @throws {Error} If the payload is not a reader or valid buffer
     * @throws {$protobuf.util.ProtocolError} If required fields are missing
     */ CircuitRelay.decode = function decode(r, l) {
        if (!(r instanceof $Reader)) r = $Reader.create(r);
        var c = l === undefined ? r.len : r.pos + l, m = new $root.CircuitRelay();
        while(r.pos < c){
            var t = r.uint32();
            switch(t >>> 3){
                case 1:
                    m.type = r.int32();
                    break;
                case 2:
                    m.srcPeer = $root.CircuitRelay.Peer.decode(r, r.uint32());
                    break;
                case 3:
                    m.dstPeer = $root.CircuitRelay.Peer.decode(r, r.uint32());
                    break;
                case 4:
                    m.code = r.int32();
                    break;
                default:
                    r.skipType(t & 7);
                    break;
            }
        }
        return m;
    };
    /**
     * Creates a CircuitRelay message from a plain object. Also converts values to their respective internal types.
     * @function fromObject
     * @memberof CircuitRelay
     * @static
     * @param {Object.<string,*>} d Plain object
     * @returns {CircuitRelay} CircuitRelay
     */ CircuitRelay.fromObject = function fromObject(d) {
        if (d instanceof $root.CircuitRelay) return d;
        var m = new $root.CircuitRelay();
        switch(d.type){
            case "HOP":
            case 1:
                m.type = 1;
                break;
            case "STOP":
            case 2:
                m.type = 2;
                break;
            case "STATUS":
            case 3:
                m.type = 3;
                break;
            case "CAN_HOP":
            case 4:
                m.type = 4;
                break;
        }
        if (d.srcPeer != null) {
            if (typeof d.srcPeer !== "object") throw TypeError(".CircuitRelay.srcPeer: object expected");
            m.srcPeer = $root.CircuitRelay.Peer.fromObject(d.srcPeer);
        }
        if (d.dstPeer != null) {
            if (typeof d.dstPeer !== "object") throw TypeError(".CircuitRelay.dstPeer: object expected");
            m.dstPeer = $root.CircuitRelay.Peer.fromObject(d.dstPeer);
        }
        switch(d.code){
            case "SUCCESS":
            case 100:
                m.code = 100;
                break;
            case "HOP_SRC_ADDR_TOO_LONG":
            case 220:
                m.code = 220;
                break;
            case "HOP_DST_ADDR_TOO_LONG":
            case 221:
                m.code = 221;
                break;
            case "HOP_SRC_MULTIADDR_INVALID":
            case 250:
                m.code = 250;
                break;
            case "HOP_DST_MULTIADDR_INVALID":
            case 251:
                m.code = 251;
                break;
            case "HOP_NO_CONN_TO_DST":
            case 260:
                m.code = 260;
                break;
            case "HOP_CANT_DIAL_DST":
            case 261:
                m.code = 261;
                break;
            case "HOP_CANT_OPEN_DST_STREAM":
            case 262:
                m.code = 262;
                break;
            case "HOP_CANT_SPEAK_RELAY":
            case 270:
                m.code = 270;
                break;
            case "HOP_CANT_RELAY_TO_SELF":
            case 280:
                m.code = 280;
                break;
            case "STOP_SRC_ADDR_TOO_LONG":
            case 320:
                m.code = 320;
                break;
            case "STOP_DST_ADDR_TOO_LONG":
            case 321:
                m.code = 321;
                break;
            case "STOP_SRC_MULTIADDR_INVALID":
            case 350:
                m.code = 350;
                break;
            case "STOP_DST_MULTIADDR_INVALID":
            case 351:
                m.code = 351;
                break;
            case "STOP_RELAY_REFUSED":
            case 390:
                m.code = 390;
                break;
            case "MALFORMED_MESSAGE":
            case 400:
                m.code = 400;
                break;
        }
        return m;
    };
    /**
     * Creates a plain object from a CircuitRelay message. Also converts values to other types if specified.
     * @function toObject
     * @memberof CircuitRelay
     * @static
     * @param {CircuitRelay} m CircuitRelay
     * @param {$protobuf.IConversionOptions} [o] Conversion options
     * @returns {Object.<string,*>} Plain object
     */ CircuitRelay.toObject = function toObject(m, o) {
        if (!o) o = {
        };
        var d = {
        };
        if (o.defaults) {
            d.type = o.enums === String ? "HOP" : 1;
            d.srcPeer = null;
            d.dstPeer = null;
            d.code = o.enums === String ? "SUCCESS" : 100;
        }
        if (m.type != null && m.hasOwnProperty("type")) d.type = o.enums === String ? $root.CircuitRelay.Type[m.type] : m.type;
        if (m.srcPeer != null && m.hasOwnProperty("srcPeer")) d.srcPeer = $root.CircuitRelay.Peer.toObject(m.srcPeer, o);
        if (m.dstPeer != null && m.hasOwnProperty("dstPeer")) d.dstPeer = $root.CircuitRelay.Peer.toObject(m.dstPeer, o);
        if (m.code != null && m.hasOwnProperty("code")) d.code = o.enums === String ? $root.CircuitRelay.Status[m.code] : m.code;
        return d;
    };
    /**
     * Converts this CircuitRelay to JSON.
     * @function toJSON
     * @memberof CircuitRelay
     * @instance
     * @returns {Object.<string,*>} JSON object
     */ CircuitRelay.prototype.toJSON = function toJSON() {
        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
    };
    /**
     * Status enum.
     * @name CircuitRelay.Status
     * @enum {number}
     * @property {number} SUCCESS=100 SUCCESS value
     * @property {number} HOP_SRC_ADDR_TOO_LONG=220 HOP_SRC_ADDR_TOO_LONG value
     * @property {number} HOP_DST_ADDR_TOO_LONG=221 HOP_DST_ADDR_TOO_LONG value
     * @property {number} HOP_SRC_MULTIADDR_INVALID=250 HOP_SRC_MULTIADDR_INVALID value
     * @property {number} HOP_DST_MULTIADDR_INVALID=251 HOP_DST_MULTIADDR_INVALID value
     * @property {number} HOP_NO_CONN_TO_DST=260 HOP_NO_CONN_TO_DST value
     * @property {number} HOP_CANT_DIAL_DST=261 HOP_CANT_DIAL_DST value
     * @property {number} HOP_CANT_OPEN_DST_STREAM=262 HOP_CANT_OPEN_DST_STREAM value
     * @property {number} HOP_CANT_SPEAK_RELAY=270 HOP_CANT_SPEAK_RELAY value
     * @property {number} HOP_CANT_RELAY_TO_SELF=280 HOP_CANT_RELAY_TO_SELF value
     * @property {number} STOP_SRC_ADDR_TOO_LONG=320 STOP_SRC_ADDR_TOO_LONG value
     * @property {number} STOP_DST_ADDR_TOO_LONG=321 STOP_DST_ADDR_TOO_LONG value
     * @property {number} STOP_SRC_MULTIADDR_INVALID=350 STOP_SRC_MULTIADDR_INVALID value
     * @property {number} STOP_DST_MULTIADDR_INVALID=351 STOP_DST_MULTIADDR_INVALID value
     * @property {number} STOP_RELAY_REFUSED=390 STOP_RELAY_REFUSED value
     * @property {number} MALFORMED_MESSAGE=400 MALFORMED_MESSAGE value
     */ CircuitRelay.Status = (function() {
        var valuesById = {
        }, values = Object.create(valuesById);
        values[valuesById[100] = "SUCCESS"] = 100;
        values[valuesById[220] = "HOP_SRC_ADDR_TOO_LONG"] = 220;
        values[valuesById[221] = "HOP_DST_ADDR_TOO_LONG"] = 221;
        values[valuesById[250] = "HOP_SRC_MULTIADDR_INVALID"] = 250;
        values[valuesById[251] = "HOP_DST_MULTIADDR_INVALID"] = 251;
        values[valuesById[260] = "HOP_NO_CONN_TO_DST"] = 260;
        values[valuesById[261] = "HOP_CANT_DIAL_DST"] = 261;
        values[valuesById[262] = "HOP_CANT_OPEN_DST_STREAM"] = 262;
        values[valuesById[270] = "HOP_CANT_SPEAK_RELAY"] = 270;
        values[valuesById[280] = "HOP_CANT_RELAY_TO_SELF"] = 280;
        values[valuesById[320] = "STOP_SRC_ADDR_TOO_LONG"] = 320;
        values[valuesById[321] = "STOP_DST_ADDR_TOO_LONG"] = 321;
        values[valuesById[350] = "STOP_SRC_MULTIADDR_INVALID"] = 350;
        values[valuesById[351] = "STOP_DST_MULTIADDR_INVALID"] = 351;
        values[valuesById[390] = "STOP_RELAY_REFUSED"] = 390;
        values[valuesById[400] = "MALFORMED_MESSAGE"] = 400;
        return values;
    })();
    /**
     * Type enum.
     * @name CircuitRelay.Type
     * @enum {number}
     * @property {number} HOP=1 HOP value
     * @property {number} STOP=2 STOP value
     * @property {number} STATUS=3 STATUS value
     * @property {number} CAN_HOP=4 CAN_HOP value
     */ CircuitRelay.Type = (function() {
        var valuesById = {
        }, values = Object.create(valuesById);
        values[valuesById[1] = "HOP"] = 1;
        values[valuesById[2] = "STOP"] = 2;
        values[valuesById[3] = "STATUS"] = 3;
        values[valuesById[4] = "CAN_HOP"] = 4;
        return values;
    })();
    CircuitRelay.Peer = (function() {
        /**
         * Properties of a Peer.
         * @memberof CircuitRelay
         * @interface IPeer
         * @property {Uint8Array} id Peer id
         * @property {Array.<Uint8Array>|null} [addrs] Peer addrs
         */ /**
         * Constructs a new Peer.
         * @memberof CircuitRelay
         * @classdesc Represents a Peer.
         * @implements IPeer
         * @constructor
         * @param {CircuitRelay.IPeer=} [p] Properties to set
         */ function Peer(p) {
            this.addrs = [];
            if (p) {
                for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
            }
        }
        /**
         * Peer id.
         * @member {Uint8Array} id
         * @memberof CircuitRelay.Peer
         * @instance
         */ Peer.prototype.id = $util.newBuffer([]);
        /**
         * Peer addrs.
         * @member {Array.<Uint8Array>} addrs
         * @memberof CircuitRelay.Peer
         * @instance
         */ Peer.prototype.addrs = $util.emptyArray;
        /**
         * Encodes the specified Peer message. Does not implicitly {@link CircuitRelay.Peer.verify|verify} messages.
         * @function encode
         * @memberof CircuitRelay.Peer
         * @static
         * @param {CircuitRelay.IPeer} m Peer message or plain object to encode
         * @param {$protobuf.Writer} [w] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */ Peer.encode = function encode(m, w) {
            if (!w) w = $Writer.create();
            w.uint32(10).bytes(m.id);
            if (m.addrs != null && m.addrs.length) for(var i = 0; i < m.addrs.length; ++i)w.uint32(18).bytes(m.addrs[i]);
            return w;
        };
        /**
         * Decodes a Peer message from the specified reader or buffer.
         * @function decode
         * @memberof CircuitRelay.Peer
         * @static
         * @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
         * @param {number} [l] Message length if known beforehand
         * @returns {CircuitRelay.Peer} Peer
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */ Peer.decode = function decode(r, l) {
            if (!(r instanceof $Reader)) r = $Reader.create(r);
            var c = l === undefined ? r.len : r.pos + l, m = new $root.CircuitRelay.Peer();
            while(r.pos < c){
                var t = r.uint32();
                switch(t >>> 3){
                    case 1:
                        m.id = r.bytes();
                        break;
                    case 2:
                        if (!(m.addrs && m.addrs.length)) m.addrs = [];
                        m.addrs.push(r.bytes());
                        break;
                    default:
                        r.skipType(t & 7);
                        break;
                }
            }
            if (!m.hasOwnProperty("id")) throw $util.ProtocolError("missing required 'id'", {
                instance: m
            });
            return m;
        };
        /**
         * Creates a Peer message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof CircuitRelay.Peer
         * @static
         * @param {Object.<string,*>} d Plain object
         * @returns {CircuitRelay.Peer} Peer
         */ Peer.fromObject = function fromObject(d) {
            if (d instanceof $root.CircuitRelay.Peer) return d;
            var m = new $root.CircuitRelay.Peer();
            if (d.id != null) {
                if (typeof d.id === "string") $util.base64.decode(d.id, m.id = $util.newBuffer($util.base64.length(d.id)), 0);
                else if (d.id.length) m.id = d.id;
            }
            if (d.addrs) {
                if (!Array.isArray(d.addrs)) throw TypeError(".CircuitRelay.Peer.addrs: array expected");
                m.addrs = [];
                for(var i = 0; i < d.addrs.length; ++i){
                    if (typeof d.addrs[i] === "string") $util.base64.decode(d.addrs[i], m.addrs[i] = $util.newBuffer($util.base64.length(d.addrs[i])), 0);
                    else if (d.addrs[i].length) m.addrs[i] = d.addrs[i];
                }
            }
            return m;
        };
        /**
         * Creates a plain object from a Peer message. Also converts values to other types if specified.
         * @function toObject
         * @memberof CircuitRelay.Peer
         * @static
         * @param {CircuitRelay.Peer} m Peer
         * @param {$protobuf.IConversionOptions} [o] Conversion options
         * @returns {Object.<string,*>} Plain object
         */ Peer.toObject = function toObject(m, o) {
            if (!o) o = {
            };
            var d = {
            };
            if (o.arrays || o.defaults) d.addrs = [];
            if (o.defaults) {
                if (o.bytes === String) d.id = "";
                else {
                    d.id = [];
                    if (o.bytes !== Array) d.id = $util.newBuffer(d.id);
                }
            }
            if (m.id != null && m.hasOwnProperty("id")) d.id = o.bytes === String ? $util.base64.encode(m.id, 0, m.id.length) : o.bytes === Array ? Array.prototype.slice.call(m.id) : m.id;
            if (m.addrs && m.addrs.length) {
                d.addrs = [];
                for(var j = 0; j < m.addrs.length; ++j)d.addrs[j] = o.bytes === String ? $util.base64.encode(m.addrs[j], 0, m.addrs[j].length) : o.bytes === Array ? Array.prototype.slice.call(m.addrs[j]) : m.addrs[j];
            }
            return d;
        };
        /**
         * Converts this Peer to JSON.
         * @function toJSON
         * @memberof CircuitRelay.Peer
         * @instance
         * @returns {Object.<string,*>} JSON object
         */ Peer.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };
        return Peer;
    })();
    return CircuitRelay;
})();
module.exports = $root;

},{"protobufjs/minimal":"9Jmso"}],"fC5Br":[function(require,module,exports) {
'use strict';
const { source: abortable  } = require('abortable-iterator');
const debug = require('debug');
const log = debug('libp2p:stream:converter');
/**
 * @typedef {import('multiaddr').Multiaddr} Multiaddr
 * @typedef {import('libp2p-interfaces/src/stream-muxer/types').MuxedStream} MuxedStream
 *
 * @typedef {Object} Timeline
 * @property {number} open - connection opening timestamp.
 * @property {number} [upgraded] - connection upgraded timestamp.
 * @property {number} [close]
 */ /**
 * Convert a duplex iterable into a MultiaddrConnection.
 * https://github.com/libp2p/interface-transport#multiaddrconnection
 *
 * @param {object} streamProperties
 * @param {MuxedStream} streamProperties.stream
 * @param {Multiaddr} streamProperties.remoteAddr
 * @param {Multiaddr} streamProperties.localAddr
 * @param {object} [options]
 * @param {AbortSignal} [options.signal]
 * @returns {import('libp2p-interfaces/src/transport/types').MultiaddrConnection}
 */ function streamToMaConnection({ stream , remoteAddr , localAddr  }, options = {
}) {
    const { sink , source: source1  } = stream;
    const maConn = {
        /**
     * @param {Uint8Array} source
     */ async sink (source) {
            if (options.signal) // @ts-ignore ts infers source template will be a number
            source = abortable(source, options.signal);
            try {
                await sink(source);
            } catch (err) {
                // If aborted we can safely ignore
                if (err.type !== 'aborted') // If the source errored the socket will already have been destroyed by
                // toIterable.duplex(). If the socket errored it will already be
                // destroyed. There's nothing to do here except log the error & return.
                log(err);
            }
            close();
        },
        source: options.signal ? abortable(source1, options.signal) : source1,
        conn: stream,
        localAddr,
        remoteAddr,
        /** @type {Timeline} */ timeline: {
            open: Date.now(),
            close: undefined
        },
        close () {
            sink(new Uint8Array(0));
            return close();
        }
    };
    function close() {
        if (!maConn.timeline.close) maConn.timeline.close = Date.now();
        return Promise.resolve();
    }
    return maConn;
}
module.exports = streamToMaConnection;

},{"abortable-iterator":"3n79Y","debug":"lWlU4"}],"fdlQ4":[function(require,module,exports) {
'use strict';
module.exports = {
    relay: '/libp2p/circuit/relay/0.1.0'
};

},{}],"7KJrg":[function(require,module,exports) {
'use strict';
const { EventEmitter  } = require('events');
const { Multiaddr  } = require('multiaddr');
/**
 * @typedef {import('libp2p-interfaces/src/transport/types').Listener} Listener
 */ /**
 * @param {import('../')} libp2p
 * @returns {Listener} a transport listener
 */ module.exports = (libp2p)=>{
    const listeningAddrs = new Map();
    /**
   * Add swarm handler and listen for incoming connections
   *
   * @param {Multiaddr} addr
   * @returns {Promise<void>}
   */ async function listen(addr) {
        const addrString = String(addr).split('/p2p-circuit').find((a)=>a !== ''
        );
        const relayConn = await libp2p.dial(new Multiaddr(addrString));
        const relayedAddr = relayConn.remoteAddr.encapsulate('/p2p-circuit');
        listeningAddrs.set(relayConn.remotePeer.toB58String(), relayedAddr);
        listener.emit('listening');
    }
    /**
   * Get fixed up multiaddrs
   *
   * NOTE: This method will grab the peers multiaddrs and expand them such that:
   *
   * a) If it's an existing /p2p-circuit address for a specific relay i.e.
   * `/ip4/0.0.0.0/tcp/0/ipfs/QmRelay/p2p-circuit` this method will expand the
   * address to `/ip4/0.0.0.0/tcp/0/ipfs/QmRelay/p2p-circuit/ipfs/QmPeer` where
   * `QmPeer` is this peers id
   * b) If it's not a /p2p-circuit address, it will encapsulate the address as a /p2p-circuit
   * addr, such when dialing over a relay with this address, it will create the circuit using
   * the encapsulated transport address. This is useful when for example, a peer should only
   * be dialed over TCP rather than any other transport
   *
   * @returns {Multiaddr[]}
   */ function getAddrs() {
        const addrs = [];
        for (const addr of listeningAddrs.values())addrs.push(addr);
        return addrs;
    }
    /** @type Listener */ const listener = Object.assign(new EventEmitter(), {
        close: ()=>Promise.resolve()
        ,
        listen,
        getAddrs
    });
    // Remove listeningAddrs when a peer disconnects
    libp2p.connectionManager.on('peer:disconnect', (connection)=>{
        const deleted = listeningAddrs.delete(connection.remotePeer.toB58String());
        if (deleted) // Announce listen addresses change
        listener.emit('close');
    });
    return listener;
};

},{"events":"bHM3D","multiaddr":"kOPrF"}],"63pMA":[function(require,module,exports) {
'use strict';
const debug = require('debug');
const log = Object.assign(debug('libp2p:circuit:hop'), {
    error: debug('libp2p:circuit:hop:err')
});
const errCode = require('err-code');
const PeerId = require('peer-id');
const { validateAddrs  } = require('./utils');
const StreamHandler = require('./stream-handler');
const { CircuitRelay: CircuitPB  } = require('../protocol');
const { pipe  } = require('it-pipe');
const { codes: Errors  } = require('../../errors');
const { stop  } = require('./stop');
const multicodec = require('./../multicodec');
/**
 * @typedef {import('../protocol').ICircuitRelay} ICircuitRelay
 * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection
 * @typedef {import('libp2p-interfaces/src/stream-muxer/types').MuxedStream} MuxedStream
 * @typedef {import('../transport')} Transport
 */ /**
 * @typedef {Object} HopRequest
 * @property {Connection} connection
 * @property {ICircuitRelay} request
 * @property {StreamHandler} streamHandler
 * @property {Transport} circuit
 */ /**
 * @param {HopRequest} options
 * @returns {Promise<void>}
 */ async function handleHop({ connection , request , streamHandler , circuit  }) {
    // Ensure hop is enabled
    if (!circuit._options.hop.enabled) {
        log('HOP request received but we are not acting as a relay');
        return streamHandler.end({
            type: CircuitPB.Type.STATUS,
            code: CircuitPB.Status.HOP_CANT_SPEAK_RELAY
        });
    }
    // Validate the HOP request has the required input
    try {
        validateAddrs(request, streamHandler);
    } catch (err) {
        return log.error('invalid hop request via peer %s', connection.remotePeer.toB58String(), err);
    }
    if (!request.dstPeer) {
        log('HOP request received but we do not receive a dstPeer');
        return;
    }
    // Get the connection to the destination (stop) peer
    const destinationPeer = new PeerId(request.dstPeer.id);
    const destinationConnection = circuit._connectionManager.get(destinationPeer);
    if (!destinationConnection && !circuit._options.hop.active) {
        log('HOP request received but we are not connected to the destination peer');
        return streamHandler.end({
            type: CircuitPB.Type.STATUS,
            code: CircuitPB.Status.HOP_NO_CONN_TO_DST
        });
    }
    // TODO: Handle being an active relay
    if (!destinationConnection) return;
    // Handle the incoming HOP request by performing a STOP request
    const stopRequest = {
        type: CircuitPB.Type.STOP,
        dstPeer: request.dstPeer,
        srcPeer: request.srcPeer
    };
    let destinationStream;
    try {
        destinationStream = await stop({
            connection: destinationConnection,
            request: stopRequest
        });
    } catch (err1) {
        return log.error(err1);
    }
    log('hop request from %s is valid', connection.remotePeer.toB58String());
    streamHandler.write({
        type: CircuitPB.Type.STATUS,
        code: CircuitPB.Status.SUCCESS
    });
    const sourceStream = streamHandler.rest();
    // Short circuit the two streams to create the relayed connection
    return pipe(sourceStream, destinationStream, sourceStream);
}
/**
 * Performs a HOP request to a relay peer, to request a connection to another
 * peer. A new, virtual, connection will be created between the two via the relay.
 *
 * @param {object} options
 * @param {Connection} options.connection - Connection to the relay
 * @param {ICircuitRelay} options.request
 * @returns {Promise<MuxedStream>}
 */ async function hop({ connection , request  }) {
    // Create a new stream to the relay
    const { stream  } = await connection.newStream([
        multicodec.relay
    ]);
    // Send the HOP request
    const streamHandler = new StreamHandler({
        stream
    });
    streamHandler.write(request);
    const response = await streamHandler.read();
    if (!response) throw errCode(new Error('HOP request had no response'), Errors.ERR_HOP_REQUEST_FAILED);
    if (response.code === CircuitPB.Status.SUCCESS) {
        log('hop request was successful');
        return streamHandler.rest();
    }
    log('hop request failed with code %d, closing stream', response.code);
    streamHandler.close();
    throw errCode(new Error(`HOP request failed with code ${response.code}`), Errors.ERR_HOP_REQUEST_FAILED);
}
/**
 * Performs a CAN_HOP request to a relay peer, in order to understand its capabilities.
 *
 * @param {object} options
 * @param {Connection} options.connection - Connection to the relay
 * @returns {Promise<boolean>}
 */ async function canHop1({ connection  }) {
    // Create a new stream to the relay
    const { stream  } = await connection.newStream([
        multicodec.relay
    ]);
    // Send the HOP request
    const streamHandler = new StreamHandler({
        stream
    });
    streamHandler.write({
        type: CircuitPB.Type.CAN_HOP
    });
    const response = await streamHandler.read();
    await streamHandler.close();
    if (!response || response.code !== CircuitPB.Status.SUCCESS) return false;
    return true;
}
/**
 * Creates an unencoded CAN_HOP response based on the Circuits configuration
 *
 * @param {Object} options
 * @param {Connection} options.connection
 * @param {StreamHandler} options.streamHandler
 * @param {Transport} options.circuit
 * @private
 */ function handleCanHop({ connection , streamHandler , circuit  }) {
    const canHop = circuit._options.hop.enabled;
    log('can hop (%s) request from %s', canHop, connection.remotePeer.toB58String());
    streamHandler.end({
        type: CircuitPB.Type.STATUS,
        code: canHop ? CircuitPB.Status.SUCCESS : CircuitPB.Status.HOP_CANT_SPEAK_RELAY
    });
}
module.exports = {
    handleHop,
    hop,
    canHop: canHop1,
    handleCanHop
};

},{"debug":"lWlU4","err-code":"eQvyh","peer-id":"4VGWt","./utils":"437DM","./stream-handler":"87JAa","../protocol":"kSXvy","it-pipe":"4jukm","../../errors":"dO31S","./stop":"eTYqE","./../multicodec":"fdlQ4"}],"437DM":[function(require,module,exports) {
'use strict';
const { Multiaddr  } = require('multiaddr');
const { CircuitRelay  } = require('../protocol');
/**
 * @typedef {import('./stream-handler')} StreamHandler
 * @typedef {import('../protocol').ICircuitRelay} ICircuitRelay
 */ /**
 * Write a response
 *
 * @param {StreamHandler} streamHandler
 * @param {import('../protocol').CircuitRelay.Status} status
 */ function writeResponse(streamHandler, status) {
    streamHandler.write({
        type: CircuitRelay.Type.STATUS,
        code: status
    });
}
/**
 * Validate incomming HOP/STOP message
 *
 * @param {ICircuitRelay} msg - A CircuitRelay unencoded protobuf message
 * @param {StreamHandler} streamHandler
 */ function validateAddrs(msg, streamHandler) {
    try {
        if (msg.dstPeer && msg.dstPeer.addrs) msg.dstPeer.addrs.forEach((addr)=>{
            return new Multiaddr(addr);
        });
    } catch (err) {
        writeResponse(streamHandler, msg.type === CircuitRelay.Type.HOP ? CircuitRelay.Status.HOP_DST_MULTIADDR_INVALID : CircuitRelay.Status.STOP_DST_MULTIADDR_INVALID);
        throw err;
    }
    try {
        if (msg.srcPeer && msg.srcPeer.addrs) msg.srcPeer.addrs.forEach((addr)=>{
            return new Multiaddr(addr);
        });
    } catch (err1) {
        writeResponse(streamHandler, msg.type === CircuitRelay.Type.HOP ? CircuitRelay.Status.HOP_SRC_MULTIADDR_INVALID : CircuitRelay.Status.STOP_SRC_MULTIADDR_INVALID);
        throw err1;
    }
}
module.exports = {
    validateAddrs
};

},{"multiaddr":"kOPrF","../protocol":"kSXvy"}],"87JAa":[function(require,module,exports) {
'use strict';
const debug = require('debug');
const log = Object.assign(debug('libp2p:circuit:stream-handler'), {
    error: debug('libp2p:circuit:stream-handler:err')
});
const lp = require('it-length-prefixed');
// @ts-ignore it-handshake does not export types
const handshake = require('it-handshake');
const { CircuitRelay  } = require('../protocol');
/**
 * @typedef {import('libp2p-interfaces/src/stream-muxer/types').MuxedStream} MuxedStream
 * @typedef {import('../protocol').ICircuitRelay} ICircuitRelay
 */ class StreamHandler {
    /**
   * Create a stream handler for connection
   *
   * @class
   * @param {object} options
   * @param {MuxedStream} options.stream - A duplex iterable
   * @param {number} [options.maxLength = 4096] - max bytes length of message
   */ constructor({ stream , maxLength =4096  }){
        this.stream = stream;
        this.shake = handshake(this.stream);
        // @ts-ignore options are not optional
        this.decoder = lp.decode.fromReader(this.shake.reader, {
            maxDataLength: maxLength
        });
    }
    /**
   * Read and decode message
   *
   * @async
   */ async read() {
        const msg = await this.decoder.next();
        if (msg.value) {
            const value = CircuitRelay.decode(msg.value.slice());
            log('read message type', value.type);
            return value;
        }
        log('read received no value, closing stream');
        // End the stream, we didn't get data
        this.close();
    }
    /**
   * Encode and write array of buffers
   *
   * @param {ICircuitRelay} msg - An unencoded CircuitRelay protobuf message
   * @returns {void}
   */ write(msg) {
        log('write message type %s', msg.type);
        // @ts-ignore lp.encode expects type type 'Buffer | BufferList', not 'Uint8Array'
        this.shake.write(lp.encode.single(CircuitRelay.encode(msg).finish()));
    }
    /**
   * Return the handshake rest stream and invalidate handler
   *
   * @returns {*} A duplex iterable
   */ rest() {
        this.shake.rest();
        return this.shake.stream;
    }
    /**
   * @param {ICircuitRelay} msg - An unencoded CircuitRelay protobuf message
   */ end(msg1) {
        this.write(msg1);
        this.close();
    }
    /**
   * Close the stream
   *
   * @returns {void}
   */ close() {
        log('closing the stream');
        this.rest().sink([]);
    }
}
module.exports = StreamHandler;

},{"debug":"lWlU4","it-length-prefixed":"2cvC1","it-handshake":"gkdlr","../protocol":"kSXvy"}],"eTYqE":[function(require,module,exports) {
'use strict';
const debug = require('debug');
const log = Object.assign(debug('libp2p:circuit:stop'), {
    error: debug('libp2p:circuit:stop:err')
});
const { CircuitRelay: CircuitPB  } = require('../protocol');
const multicodec = require('../multicodec');
const StreamHandler = require('./stream-handler');
const { validateAddrs  } = require('./utils');
/**
 * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection
 * @typedef {import('libp2p-interfaces/src/stream-muxer/types').MuxedStream} MuxedStream
 * @typedef {import('../protocol').ICircuitRelay} ICircuitRelay
 */ /**
 * Handles incoming STOP requests
 *
 * @private
 * @param {Object} options
 * @param {Connection} options.connection
 * @param {ICircuitRelay} options.request - The CircuitRelay protobuf request (unencoded)
 * @param {StreamHandler} options.streamHandler
 * @returns {Promise<MuxedStream>|void} Resolves a duplex iterable
 */ module.exports.handleStop = function handleStop({ connection , request , streamHandler  }) {
    // Validate the STOP request has the required input
    try {
        validateAddrs(request, streamHandler);
    } catch (err) {
        return log.error('invalid stop request via peer %s', connection.remotePeer.toB58String(), err);
    }
    // The request is valid
    log('stop request is valid');
    streamHandler.write({
        type: CircuitPB.Type.STATUS,
        code: CircuitPB.Status.SUCCESS
    });
    return streamHandler.rest();
};
/**
 * Creates a STOP request
 *
 * @private
 * @param {Object} options
 * @param {Connection} options.connection
 * @param {ICircuitRelay} options.request - The CircuitRelay protobuf request (unencoded)
 * @returns {Promise<MuxedStream|void>} Resolves a duplex iterable
 */ module.exports.stop = async function stop({ connection , request  }) {
    const { stream  } = await connection.newStream([
        multicodec.relay
    ]);
    log('starting stop request to %s', connection.remotePeer.toB58String());
    const streamHandler = new StreamHandler({
        stream
    });
    streamHandler.write(request);
    const response = await streamHandler.read();
    if (!response) return streamHandler.close();
    if (response.code === CircuitPB.Status.SUCCESS) {
        log('stop request to %s was successful', connection.remotePeer.toB58String());
        return streamHandler.rest();
    }
    log('stop request failed with code %d', response.code);
    streamHandler.close();
};

},{"debug":"lWlU4","../protocol":"kSXvy","../multicodec":"fdlQ4","./stream-handler":"87JAa","./utils":"437DM"}],"1RcZC":[function(require,module,exports) {
'use strict';
const debug = require('debug');
const log = Object.assign(debug('libp2p:relay'), {
    error: debug('libp2p:relay:err')
});
const { setDelayedInterval , clearDelayedInterval  } = require('set-delayed-interval');
const AutoRelay = require('./auto-relay');
const { namespaceToCid  } = require('./utils');
const { RELAY_RENDEZVOUS_NS  } = require('./constants');
/**
 * @typedef {import('../')} Libp2p
 *
 * @typedef {Object} RelayAdvertiseOptions
 * @property {number} [bootDelay = ADVERTISE_BOOT_DELAY]
 * @property {boolean} [enabled = true]
 * @property {number} [ttl = ADVERTISE_TTL]
 *
 * @typedef {Object} HopOptions
 * @property {boolean} [enabled = false]
 * @property {boolean} [active = false]
 *
 * @typedef {Object} AutoRelayOptions
 * @property {number} [maxListeners = 2] - maximum number of relays to listen.
 * @property {boolean} [enabled = false]
 */ class Relay {
    /**
   * Creates an instance of Relay.
   *
   * @class
   * @param {Libp2p} libp2p
   */ constructor(libp2p){
        this._libp2p = libp2p;
        this._options = {
            ...libp2p._config.relay
        };
        // Create autoRelay if enabled
        this._autoRelay = this._options.autoRelay.enabled && new AutoRelay({
            libp2p,
            ...this._options.autoRelay
        });
        this._advertiseService = this._advertiseService.bind(this);
    }
    /**
   * Start Relay service.
   *
   * @returns {void}
   */ start() {
        // Advertise service if HOP enabled
        const canHop = this._options.hop.enabled;
        if (canHop && this._options.advertise.enabled) this._timeout = setDelayedInterval(this._advertiseService, this._options.advertise.ttl, this._options.advertise.bootDelay);
    }
    /**
   * Stop Relay service.
   *
   * @returns {void}
   */ stop() {
        clearDelayedInterval(this._timeout);
    }
    /**
   * Advertise hop relay service in the network.
   *
   * @returns {Promise<void>}
   */ async _advertiseService() {
        try {
            const cid = await namespaceToCid(RELAY_RENDEZVOUS_NS);
            await this._libp2p.contentRouting.provide(cid);
        } catch (err) {
            if (err.code === 'NO_ROUTERS_AVAILABLE') {
                log.error('a content router, such as a DHT, must be provided in order to advertise the relay service', err);
                // Stop the advertise
                this.stop();
            } else log.error(err);
        }
    }
}
module.exports = Relay;

},{"debug":"lWlU4","set-delayed-interval":"jrB3f","./auto-relay":"lMe7L","./utils":"gujwr","./constants":"iivfC"}],"lMe7L":[function(require,module,exports) {
'use strict';
const debug = require('debug');
const log = Object.assign(debug('libp2p:auto-relay'), {
    error: debug('libp2p:auto-relay:err')
});
const { fromString: uint8ArrayFromString  } = require('uint8arrays/from-string');
const { toString: uint8ArrayToString  } = require('uint8arrays/to-string');
const { Multiaddr  } = require('multiaddr');
const PeerId = require('peer-id');
const { relay: multicodec  } = require('./multicodec');
const { canHop  } = require('./circuit/hop');
const { namespaceToCid  } = require('./utils');
const { CIRCUIT_PROTO_CODE , HOP_METADATA_KEY , HOP_METADATA_VALUE , RELAY_RENDEZVOUS_NS  } = require('./constants');
/**
 * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection
 * @typedef {import('../peer-store/address-book').Address} Address
 */ /**
 * @typedef {Object} AutoRelayProperties
 * @property {import('../')} libp2p
 *
 * @typedef {Object} AutoRelayOptions
 * @property {number} [maxListeners = 1] - maximum number of relays to listen.
 * @property {(error: Error, msg?: string) => {}} [onError]
 */ class AutoRelay {
    /**
   * Creates an instance of AutoRelay.
   *
   * @class
   * @param {AutoRelayProperties & AutoRelayOptions} props
   */ constructor({ libp2p , maxListeners =1 , onError  }){
        this._libp2p = libp2p;
        this._peerId = libp2p.peerId;
        this._peerStore = libp2p.peerStore;
        this._connectionManager = libp2p.connectionManager;
        this._transportManager = libp2p.transportManager;
        this._addressSorter = libp2p.dialer.addressSorter;
        this.maxListeners = maxListeners;
        /**
     * @type {Set<string>}
     */ this._listenRelays = new Set();
        this._onProtocolChange = this._onProtocolChange.bind(this);
        this._onPeerDisconnected = this._onPeerDisconnected.bind(this);
        this._peerStore.on('change:protocols', this._onProtocolChange);
        this._connectionManager.on('peer:disconnect', this._onPeerDisconnected);
        /**
     * @param {Error} error
     * @param {string} [msg]
     */ this._onError = (error, msg)=>{
            log.error(msg || error);
            onError && onError(error, msg);
        };
    }
    /**
   * Check if a peer supports the relay protocol.
   * If the protocol is not supported, check if it was supported before and remove it as a listen relay.
   * If the protocol is supported, check if the peer supports **HOP** and add it as a listener if
   * inside the threshold.
   *
   * @param {Object} props
   * @param {PeerId} props.peerId
   * @param {string[]} props.protocols
   * @returns {Promise<void>}
   */ async _onProtocolChange({ peerId , protocols  }) {
        const id = peerId.toB58String();
        // Check if it has the protocol
        const hasProtocol = protocols.find((protocol)=>protocol === multicodec
        );
        // If no protocol, check if we were keeping the peer before as a listenRelay
        if (!hasProtocol && this._listenRelays.has(id)) {
            this._removeListenRelay(id);
            return;
        } else if (!hasProtocol || this._listenRelays.has(id)) return;
        // If protocol, check if can hop, store info in the metadataBook and listen on it
        try {
            const connection = this._connectionManager.get(peerId);
            if (!connection) return;
            // Do not hop on a relayed connection
            if (connection.remoteAddr.protoCodes().includes(CIRCUIT_PROTO_CODE)) {
                log(`relayed connection to ${id} will not be used to hop on`);
                return;
            }
            const supportsHop = await canHop({
                connection
            });
            if (supportsHop) {
                this._peerStore.metadataBook.set(peerId, HOP_METADATA_KEY, uint8ArrayFromString(HOP_METADATA_VALUE));
                await this._addListenRelay(connection, id);
            }
        } catch (err) {
            this._onError(err);
        }
    }
    /**
   * Peer disconnects.
   *
   * @param {Connection} connection - connection to the peer
   * @returns {void}
   */ _onPeerDisconnected(connection) {
        const peerId = connection.remotePeer;
        const id = peerId.toB58String();
        // Not listening on this relay
        if (!this._listenRelays.has(id)) return;
        this._removeListenRelay(id);
    }
    /**
   * Attempt to listen on the given relay connection.
   *
   * @private
   * @param {Connection} connection - connection to the peer
   * @param {string} id - peer identifier string
   * @returns {Promise<void>}
   */ async _addListenRelay(connection1, id) {
        // Check if already listening on enough relays
        if (this._listenRelays.size >= this.maxListeners) return;
        // Get peer known addresses and sort them per public addresses first
        const remoteAddrs = this._peerStore.addressBook.getMultiaddrsForPeer(connection1.remotePeer, this._addressSorter);
        if (!remoteAddrs || !remoteAddrs.length) return;
        const listenAddr = `${remoteAddrs[0].toString()}/p2p-circuit`;
        this._listenRelays.add(id);
        // Attempt to listen on relay
        try {
            await this._transportManager.listen([
                new Multiaddr(listenAddr)
            ]);
        // Announce multiaddrs will update on listen success by TransportManager event being triggered
        } catch (err) {
            this._onError(err);
            this._listenRelays.delete(id);
        }
    }
    /**
   * Remove listen relay.
   *
   * @private
   * @param {string} id - peer identifier string.
   * @returns {void}
   */ _removeListenRelay(id1) {
        if (this._listenRelays.delete(id1)) // TODO: this should be responsibility of the connMgr
        this._listenOnAvailableHopRelays([
            id1
        ]);
    }
    /**
   * Try to listen on available hop relay connections.
   * The following order will happen while we do not have enough relays.
   * 1. Check the metadata store for known relays, try to listen on the ones we are already connected.
   * 2. Dial and try to listen on the peers we know that support hop but are not connected.
   * 3. Search the network.
   *
   * @param {string[]} [peersToIgnore]
   * @returns {Promise<void>}
   */ async _listenOnAvailableHopRelays(peersToIgnore = []) {
        // TODO: The peer redial issue on disconnect should be handled by connection gating
        // Check if already listening on enough relays
        if (this._listenRelays.size >= this.maxListeners) return;
        const knownHopsToDial = [];
        // Check if we have known hop peers to use and attempt to listen on the already connected
        for (const [id, metadataMap] of this._peerStore.metadataBook.data.entries()){
            // Continue to next if listening on this or peer to ignore
            if (this._listenRelays.has(id) || peersToIgnore.includes(id)) continue;
            const supportsHop = metadataMap.get(HOP_METADATA_KEY);
            // Continue to next if it does not support Hop
            if (!supportsHop || uint8ArrayToString(supportsHop) !== HOP_METADATA_VALUE) continue;
            const peerId = PeerId.createFromB58String(id);
            const connection = this._connectionManager.get(peerId);
            // If not connected, store for possible later use.
            if (!connection) {
                knownHopsToDial.push(peerId);
                continue;
            }
            await this._addListenRelay(connection, id);
            // Check if already listening on enough relays
            if (this._listenRelays.size >= this.maxListeners) return;
        }
        // Try to listen on known peers that are not connected
        for (const peerId of knownHopsToDial){
            await this._tryToListenOnRelay(peerId);
            // Check if already listening on enough relays
            if (this._listenRelays.size >= this.maxListeners) return;
        }
        // Try to find relays to hop on the network
        try {
            const cid = await namespaceToCid(RELAY_RENDEZVOUS_NS);
            for await (const provider of this._libp2p.contentRouting.findProviders(cid)){
                if (!provider.multiaddrs.length) continue;
                const peerId = provider.id;
                this._peerStore.addressBook.add(peerId, provider.multiaddrs);
                await this._tryToListenOnRelay(peerId);
                // Check if already listening on enough relays
                if (this._listenRelays.size >= this.maxListeners) return;
            }
        } catch (err) {
            this._onError(err);
        }
    }
    /**
   * @param {PeerId} peerId
   */ async _tryToListenOnRelay(peerId1) {
        try {
            const connection = await this._libp2p.dial(peerId1);
            await this._addListenRelay(connection, peerId1.toB58String());
        } catch (err) {
            this._onError(err, `could not connect and listen on known hop relay ${peerId1.toB58String()}`);
        }
    }
}
module.exports = AutoRelay;

},{"debug":"lWlU4","uint8arrays/from-string":"lo45E","uint8arrays/to-string":"g3mCQ","multiaddr":"kOPrF","peer-id":"4VGWt","./multicodec":"fdlQ4","./circuit/hop":"63pMA","./utils":"gujwr","./constants":"iivfC"}],"gujwr":[function(require,module,exports) {
'use strict';
const { CID  } = require('multiformats/cid');
const { sha256  } = require('multiformats/hashes/sha2');
/**
 * Convert a namespace string into a cid.
 *
 * @param {string} namespace
 * @returns {Promise<CID>}
 */ module.exports.namespaceToCid = async (namespace)=>{
    const bytes = new TextEncoder().encode(namespace);
    const hash = await sha256.digest(bytes);
    return CID.createV0(hash);
};

},{"multiformats/cid":"fJJnW","multiformats/hashes/sha2":"i8JnP"}],"dakOv":[function(require,module,exports) {
'use strict';
const debug = require('debug');
const log = Object.assign(debug('libp2p:dialer'), {
    error: debug('libp2p:dialer:err')
});
const errCode = require('err-code');
const { Multiaddr  } = require('multiaddr');
// @ts-ignore timeout-abourt-controles does not export types
const TimeoutController = require('timeout-abort-controller');
const { AbortError  } = require('abortable-iterator');
const { anySignal  } = require('any-signal');
const DialRequest = require('./dial-request');
const { publicAddressesFirst  } = require('libp2p-utils/src/address-sort');
const getPeer = require('../get-peer');
const { codes  } = require('../errors');
const { DIAL_TIMEOUT , MAX_PARALLEL_DIALS , MAX_PER_PEER_DIALS , MAX_ADDRS_TO_DIAL  } = require('../constants');
/**
 * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection
 * @typedef {import('peer-id')} PeerId
 * @typedef {import('../peer-store')} PeerStore
 * @typedef {import('../peer-store/address-book').Address} Address
 * @typedef {import('../transport-manager')} TransportManager
 */ /**
 * @typedef {Object} DialerProperties
 * @property {PeerStore} peerStore
 * @property {TransportManager} transportManager
 *
 * @typedef {(addr:Multiaddr) => Promise<string[]>} Resolver
 *
 * @typedef {Object} DialerOptions
 * @property {(addresses: Address[]) => Address[]} [options.addressSorter = publicAddressesFirst] - Sort the known addresses of a peer before trying to dial.
 * @property {number} [maxParallelDials = MAX_PARALLEL_DIALS] - Number of max concurrent dials.
 * @property {number} [maxAddrsToDial = MAX_ADDRS_TO_DIAL] - Number of max addresses to dial for a given peer.
 * @property {number} [maxDialsPerPeer = MAX_PER_PEER_DIALS] - Number of max concurrent dials per peer.
 * @property {number} [dialTimeout = DIAL_TIMEOUT] - How long a dial attempt is allowed to take.
 * @property {Record<string, Resolver>} [resolvers = {}] - multiaddr resolvers to use when dialing
 *
 * @typedef DialTarget
 * @property {string} id
 * @property {Multiaddr[]} addrs
 *
 * @typedef PendingDial
 * @property {DialRequest} dialRequest
 * @property {TimeoutController} controller
 * @property {Promise<Connection>} promise
 * @property {function():void} destroy
 */ class Dialer {
    /**
   * @class
   * @param {DialerProperties & DialerOptions} options
   */ constructor({ transportManager , peerStore , addressSorter =publicAddressesFirst , maxParallelDials =MAX_PARALLEL_DIALS , maxAddrsToDial =MAX_ADDRS_TO_DIAL , dialTimeout =DIAL_TIMEOUT , maxDialsPerPeer =MAX_PER_PEER_DIALS , resolvers ={
    }  }){
        this.transportManager = transportManager;
        this.peerStore = peerStore;
        this.addressSorter = addressSorter;
        this.maxParallelDials = maxParallelDials;
        this.maxAddrsToDial = maxAddrsToDial;
        this.timeout = dialTimeout;
        this.maxDialsPerPeer = maxDialsPerPeer;
        this.tokens = [
            ...new Array(maxParallelDials)
        ].map((_, index)=>index
        );
        this._pendingDials = new Map();
        this._pendingDialTargets = new Map();
        for (const [key, value] of Object.entries(resolvers))Multiaddr.resolvers.set(key, value);
    }
    /**
   * Clears any pending dials
   */ destroy() {
        for (const dial of this._pendingDials.values())try {
            dial.controller.abort();
        } catch (err) {
            log.error(err);
        }
        this._pendingDials.clear();
        for (const pendingTarget of this._pendingDialTargets.values())pendingTarget.reject(new AbortError('Dialer was destroyed'));
        this._pendingDialTargets.clear();
    }
    /**
   * Connects to a given `peer` by dialing all of its known addresses.
   * The dial to the first address that is successfully able to upgrade a connection
   * will be used.
   *
   * @param {PeerId|Multiaddr|string} peer - The peer to dial
   * @param {object} [options]
   * @param {AbortSignal} [options.signal] - An AbortController signal
   * @returns {Promise<Connection>}
   */ async connectToPeer(peer, options2 = {
    }) {
        const dialTarget = await this._createCancellableDialTarget(peer);
        if (!dialTarget.addrs.length) throw errCode(new Error('The dial request has no valid addresses'), codes.ERR_NO_VALID_ADDRESSES);
        const pendingDial = this._pendingDials.get(dialTarget.id) || this._createPendingDial(dialTarget, options2);
        try {
            const connection = await pendingDial.promise;
            log('dial succeeded to %s', dialTarget.id);
            return connection;
        } catch (err) {
            // Error is a timeout
            if (pendingDial.controller.signal.aborted) err.code = codes.ERR_TIMEOUT;
            log.error(err);
            throw err;
        } finally{
            pendingDial.destroy();
        }
    }
    /**
   * Connects to a given `peer` by dialing all of its known addresses.
   * The dial to the first address that is successfully able to upgrade a connection
   * will be used.
   *
   * @param {PeerId|Multiaddr|string} peer - The peer to dial
   * @returns {Promise<DialTarget>}
   */ async _createCancellableDialTarget(peer1) {
        // Make dial target promise cancellable
        const id = `${parseInt(String(Math.random() * 1000000000), 10).toString() + Date.now()}`;
        const cancellablePromise = new Promise((resolve, reject)=>{
            this._pendingDialTargets.set(id, {
                resolve,
                reject
            });
        });
        const dialTarget = await Promise.race([
            this._createDialTarget(peer1),
            cancellablePromise
        ]);
        this._pendingDialTargets.delete(id);
        return dialTarget;
    }
    /**
   * Creates a DialTarget. The DialTarget is used to create and track
   * the DialRequest to a given peer.
   * If a multiaddr is received it should be the first address attempted.
   * Multiaddrs not supported by the available transports will be filtered out.
   *
   * @private
   * @param {PeerId|Multiaddr|string} peer - A PeerId or Multiaddr
   * @returns {Promise<DialTarget>}
   */ async _createDialTarget(peer2) {
        const { id , multiaddrs  } = getPeer(peer2);
        if (multiaddrs) this.peerStore.addressBook.add(id, multiaddrs);
        let knownAddrs = this.peerStore.addressBook.getMultiaddrsForPeer(id, this.addressSorter) || [];
        // If received a multiaddr to dial, it should be the first to use
        // But, if we know other multiaddrs for the peer, we should try them too.
        if (Multiaddr.isMultiaddr(peer2)) {
            knownAddrs = knownAddrs.filter((addr)=>!peer2.equals(addr)
            );
            knownAddrs.unshift(peer2);
        }
        /** @type {Multiaddr[]} */ const addrs = [];
        for (const a1 of knownAddrs){
            const resolvedAddrs = await this._resolve(a1);
            resolvedAddrs.forEach((ra)=>addrs.push(ra)
            );
        }
        // Multiaddrs not supported by the available transports will be filtered out.
        const supportedAddrs = addrs.filter((a)=>this.transportManager.transportForMultiaddr(a)
        );
        if (supportedAddrs.length > this.maxAddrsToDial) {
            this.peerStore.delete(id);
            throw errCode(new Error('dial with more addresses than allowed'), codes.ERR_TOO_MANY_ADDRESSES);
        }
        return {
            id: id.toB58String(),
            addrs: supportedAddrs
        };
    }
    /**
   * Creates a PendingDial that wraps the underlying DialRequest
   *
   * @private
   * @param {DialTarget} dialTarget
   * @param {object} [options]
   * @param {AbortSignal} [options.signal] - An AbortController signal
   * @returns {PendingDial}
   */ _createPendingDial(dialTarget, options1 = {
    }) {
        /**
     * @param {Multiaddr} addr
     * @param {{ signal: { aborted: any; }; }} options
     */ const dialAction = (addr, options)=>{
            if (options.signal.aborted) throw errCode(new Error('already aborted'), codes.ERR_ALREADY_ABORTED);
            return this.transportManager.dial(addr, options);
        };
        const dialRequest = new DialRequest({
            addrs: dialTarget.addrs,
            dialAction,
            dialer: this
        });
        // Combine the timeout signal and options.signal, if provided
        const timeoutController = new TimeoutController(this.timeout);
        const signals = [
            timeoutController.signal
        ];
        options1.signal && signals.push(options1.signal);
        const signal = anySignal(signals);
        const pendingDial = {
            dialRequest,
            controller: timeoutController,
            promise: dialRequest.run({
                ...options1,
                signal
            }),
            destroy: ()=>{
                timeoutController.clear();
                this._pendingDials.delete(dialTarget.id);
            }
        };
        this._pendingDials.set(dialTarget.id, pendingDial);
        return pendingDial;
    }
    /**
   * @param {number} num
   */ getTokens(num) {
        const total = Math.min(num, this.maxDialsPerPeer, this.tokens.length);
        const tokens = this.tokens.splice(0, total);
        log('%d tokens request, returning %d, %d remaining', num, total, this.tokens.length);
        return tokens;
    }
    /**
   * @param {number} token
   */ releaseToken(token) {
        // Guard against duplicate releases
        if (this.tokens.indexOf(token) > -1) return;
        log('token %d released', token);
        this.tokens.push(token);
    }
    /**
   * Resolve multiaddr recursively.
   *
   * @param {Multiaddr} ma
   * @returns {Promise<Multiaddr[]>}
   */ async _resolve(ma) {
        // TODO: recursive logic should live in multiaddr once dns4/dns6 support is in place
        // Now only supporting resolve for dnsaddr
        const resolvableProto = ma.protoNames().includes('dnsaddr');
        // Multiaddr is not resolvable? End recursion!
        if (!resolvableProto) return [
            ma
        ];
        const resolvedMultiaddrs = await this._resolveRecord(ma);
        const recursiveMultiaddrs = await Promise.all(resolvedMultiaddrs.map((nm)=>{
            return this._resolve(nm);
        }));
        const addrs = recursiveMultiaddrs.flat();
        return addrs.reduce((array, newM)=>{
            if (!array.find((m)=>m.equals(newM)
            )) array.push(newM);
            return array;
        }, []);
    }
    /**
   * Resolve a given multiaddr. If this fails, an empty array will be returned
   *
   * @param {Multiaddr} ma
   * @returns {Promise<Multiaddr[]>}
   */ async _resolveRecord(ma1) {
        try {
            ma1 = new Multiaddr(ma1.toString()) // Use current multiaddr module
            ;
            const multiaddrs = await ma1.resolve();
            return multiaddrs;
        } catch (_) {
            log.error(`multiaddr ${ma1} could not be resolved`);
            return [];
        }
    }
}
module.exports = Dialer;

},{"debug":"lWlU4","err-code":"eQvyh","multiaddr":"kOPrF","timeout-abort-controller":"gYeUY","abortable-iterator":"3n79Y","any-signal":"1586s","./dial-request":"kF8Hl","libp2p-utils/src/address-sort":"glzi6","../get-peer":"8B3xC","../errors":"dO31S","../constants":"7AgPB"}],"kF8Hl":[function(require,module,exports) {
'use strict';
const errCode = require('err-code');
const AbortController = require('abort-controller').default;
const { anySignal  } = require('any-signal');
// @ts-ignore p-fifo does not export types
const FIFO = require('p-fifo');
const pAny = require('p-any');
/**
 * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection
 * @typedef {import('./')} Dialer
 * @typedef {import('multiaddr').Multiaddr} Multiaddr
 */ /**
 * @typedef {Object} DialOptions
 * @property {AbortSignal} signal
 *
 * @typedef {Object} DialRequestOptions
 * @property {Multiaddr[]} addrs
 * @property {(m: Multiaddr, options: DialOptions) => Promise<Connection>} dialAction
 * @property {Dialer} dialer
 */ class DialRequest {
    /**
   * Manages running the `dialAction` on multiple provided `addrs` in parallel
   * up to a maximum determined by the number of tokens returned
   * from `dialer.getTokens`. Once a DialRequest is created, it can be
   * started using `DialRequest.run(options)`. Once a single dial has succeeded,
   * all other dials in the request will be cancelled.
   *
   * @class
   * @param {DialRequestOptions} options
   */ constructor({ addrs , dialAction , dialer  }){
        this.addrs = addrs;
        this.dialer = dialer;
        this.dialAction = dialAction;
    }
    /**
   * @async
   * @param {object} [options]
   * @param {AbortSignal} [options.signal] - An AbortController signal
   * @returns {Promise<Connection>}
   */ async run(options = {
    }) {
        const tokens = this.dialer.getTokens(this.addrs.length);
        // If no tokens are available, throw
        if (tokens.length < 1) throw errCode(new Error('No dial tokens available'), 'ERR_NO_DIAL_TOKENS');
        const tokenHolder = new FIFO();
        tokens.forEach((token)=>tokenHolder.push(token)
        );
        const dialAbortControllers = this.addrs.map(()=>new AbortController()
        );
        let completedDials = 0;
        try {
            return await pAny(this.addrs.map(async (addr, i)=>{
                const token = await tokenHolder.shift() // get token
                ;
                let conn;
                try {
                    const signal = dialAbortControllers[i].signal;
                    conn = await this.dialAction(addr, {
                        ...options,
                        signal: options.signal ? anySignal([
                            signal,
                            options.signal
                        ]) : signal
                    });
                    // Remove the successful AbortController so it is not aborted
                    dialAbortControllers.splice(i, 1);
                } finally{
                    completedDials++;
                    // If we have more or equal dials remaining than tokens, recycle the token, otherwise release it
                    if (this.addrs.length - completedDials >= tokens.length) tokenHolder.push(token);
                    else this.dialer.releaseToken(tokens.splice(tokens.indexOf(token), 1)[0]);
                }
                return conn;
            }));
        } finally{
            dialAbortControllers.map((c)=>c.abort()
            ) // success/failure happened, abort everything else
            ;
            tokens.forEach((token)=>this.dialer.releaseToken(token)
            ) // release tokens back to the dialer
            ;
        }
    }
}
module.exports = DialRequest;

},{"err-code":"eQvyh","abort-controller":"hVuZx","any-signal":"1586s","p-fifo":"cr99m","p-any":"cDR1A"}],"cr99m":[function(require,module,exports) {
const Fifo = require('fast-fifo');
const defer = require('p-defer');
module.exports = class PFifo {
    constructor(){
        this._buffer = new Fifo();
        this._waitingConsumers = new Fifo();
    }
    push(chunk) {
        const { promise , resolve  } = defer();
        this._buffer.push({
            chunk,
            resolve
        });
        this._consume();
        return promise;
    }
    _consume() {
        while(!this._waitingConsumers.isEmpty() && !this._buffer.isEmpty()){
            const nextConsumer = this._waitingConsumers.shift();
            const nextChunk = this._buffer.shift();
            nextConsumer.resolve(nextChunk.chunk);
            nextChunk.resolve();
        }
    }
    shift() {
        const { promise , resolve  } = defer();
        this._waitingConsumers.push({
            resolve
        });
        this._consume();
        return promise;
    }
    isEmpty() {
        return this._buffer.isEmpty();
    }
};

},{"fast-fifo":"21SLI","p-defer":"gZqcC"}],"cDR1A":[function(require,module,exports) {
'use strict';
const pSome = require('p-some');
const PCancelable = require('p-cancelable');
module.exports = (iterable, options)=>{
    const anyCancelable = pSome(iterable, {
        ...options,
        count: 1
    });
    return PCancelable.fn(async (onCancel)=>{
        onCancel(()=>{
            anyCancelable.cancel();
        });
        const [value] = await anyCancelable;
        return value;
    })();
};
module.exports.AggregateError = pSome.AggregateError;

},{"p-some":"8ykPv","p-cancelable":"3jxeo"}],"8ykPv":[function(require,module,exports) {
'use strict';
const AggregateError = require('aggregate-error');
const PCancelable = require('p-cancelable');
class FilterError extends Error {
}
const pSome = (iterable, options)=>new PCancelable((resolve, reject, onCancel)=>{
        const { count , filter =()=>true
          } = options;
        if (!Number.isFinite(count)) {
            reject(new TypeError(`Expected a finite number, got ${typeof options.count}`));
            return;
        }
        const values = [];
        const errors = [];
        let elementCount = 0;
        let isSettled = false;
        const completed = new Set();
        const maybeSettle = ()=>{
            if (values.length === count) {
                resolve(values);
                isSettled = true;
            }
            if (elementCount - errors.length < count) {
                reject(new AggregateError(errors));
                isSettled = true;
            }
            return isSettled;
        };
        const cancelPending = ()=>{
            for (const promise of iterable)if (!completed.has(promise) && typeof promise.cancel === 'function') promise.cancel();
        };
        onCancel(cancelPending);
        for (const element of iterable){
            elementCount++;
            (async ()=>{
                try {
                    const value = await element;
                    if (isSettled) return;
                    if (!filter(value)) throw new FilterError('Value does not satisfy filter');
                    values.push(value);
                } catch (error) {
                    errors.push(error);
                } finally{
                    completed.add(element);
                    if (!isSettled && maybeSettle()) cancelPending();
                }
            })();
        }
        if (count > elementCount) {
            reject(new RangeError(`Expected input to contain at least ${options.count} items, but contains ${elementCount} items`));
            cancelPending();
        }
    })
;
module.exports = pSome;
module.exports.AggregateError = AggregateError;
module.exports.FilterError = FilterError;

},{"aggregate-error":"1BWsO","p-cancelable":"3jxeo"}],"3jxeo":[function(require,module,exports) {
'use strict';
class CancelError extends Error {
    constructor(reason){
        super(reason || 'Promise was canceled');
        this.name = 'CancelError';
    }
    get isCanceled() {
        return true;
    }
}
class PCancelable {
    static fn(userFn) {
        return (...arguments_)=>{
            return new PCancelable((resolve, reject, onCancel)=>{
                arguments_.push(onCancel);
                // eslint-disable-next-line promise/prefer-await-to-then
                userFn(...arguments_).then(resolve, reject);
            });
        };
    }
    constructor(executor){
        this._cancelHandlers = [];
        this._isPending = true;
        this._isCanceled = false;
        this._rejectOnCancel = true;
        this._promise = new Promise((resolve, reject)=>{
            this._reject = reject;
            const onResolve = (value)=>{
                if (!this._isCanceled || !onCancel.shouldReject) {
                    this._isPending = false;
                    resolve(value);
                }
            };
            const onReject = (error)=>{
                this._isPending = false;
                reject(error);
            };
            const onCancel = (handler)=>{
                if (!this._isPending) throw new Error('The `onCancel` handler was attached after the promise settled.');
                this._cancelHandlers.push(handler);
            };
            Object.defineProperties(onCancel, {
                shouldReject: {
                    get: ()=>this._rejectOnCancel
                    ,
                    set: (boolean)=>{
                        this._rejectOnCancel = boolean;
                    }
                }
            });
            return executor(onResolve, onReject, onCancel);
        });
    }
    then(onFulfilled, onRejected) {
        // eslint-disable-next-line promise/prefer-await-to-then
        return this._promise.then(onFulfilled, onRejected);
    }
    catch(onRejected1) {
        return this._promise.catch(onRejected1);
    }
    finally(onFinally) {
        return this._promise.finally(onFinally);
    }
    cancel(reason1) {
        if (!this._isPending || this._isCanceled) return;
        this._isCanceled = true;
        if (this._cancelHandlers.length > 0) try {
            for (const handler of this._cancelHandlers)handler();
        } catch (error) {
            this._reject(error);
            return;
        }
        if (this._rejectOnCancel) this._reject(new CancelError(reason1));
    }
    get isCanceled() {
        return this._isCanceled;
    }
}
Object.setPrototypeOf(PCancelable.prototype, Promise.prototype);
module.exports = PCancelable;
module.exports.CancelError = CancelError;

},{}],"qJaG4":[function(require,module,exports) {
/* eslint max-nested-callbacks: ["error", 5] */ 'use strict';
const debug = require('debug');
const log = Object.assign(debug('libp2p:keychain'), {
    error: debug('libp2p:keychain:err')
});
const sanitize = require('sanitize-filename');
const mergeOptions = require('merge-options');
const crypto = require('libp2p-crypto');
const { Key  } = require('interface-datastore/key');
const CMS = require('./cms');
const errcode = require('err-code');
const { toString: uint8ArrayToString  } = require('uint8arrays/to-string');
const { fromString: uint8ArrayFromString  } = require('uint8arrays/from-string');
// @ts-ignore node-forge sha512 types not exported
require('node-forge/lib/sha512');
/**
 * @typedef {import('peer-id')} PeerId
 * @typedef {import('interface-datastore').Datastore} Datastore
 */ /**
 * @typedef {Object} DekOptions
 * @property {string} hash
 * @property {string} salt
 * @property {number} iterationCount
 * @property {number} keyLength
 *
 * @typedef {Object} KeychainOptions
 * @property {string} [pass]
 * @property {DekOptions} [dek]
 */ /**
 * Information about a key.
 *
 * @typedef {Object} KeyInfo
 * @property {string} id - The universally unique key id.
 * @property {string} name - The local key name.
 */ const keyPrefix = '/pkcs8/';
const infoPrefix = '/info/';
const privates = new WeakMap();
// NIST SP 800-132
const NIST = {
    minKeyLength: 14,
    minSaltLength: 16,
    minIterationCount: 1000
};
const defaultOptions = {
    // See https://cryptosense.com/parametesr-choice-for-pbkdf2/
    dek: {
        keyLength: 64,
        iterationCount: 10000,
        salt: 'you should override this value with a crypto secure random number',
        hash: 'sha2-512'
    }
};
/**
 * @param {string} name
 */ function validateKeyName(name) {
    if (!name) return false;
    if (typeof name !== 'string') return false;
    return name === sanitize(name.trim());
}
/**
 * Throws an error after a delay
 *
 * This assumes than an error indicates that the keychain is under attack. Delay returning an
 * error to make brute force attacks harder.
 *
 * @param {string|Error} err - The error
 * @returns {Promise<never>}
 * @private
 */ async function throwDelayed(err) {
    const min = 200;
    const max = 1000;
    const delay = Math.random() * (max - min) + min;
    await new Promise((resolve)=>setTimeout(resolve, delay)
    );
    throw err;
}
/**
 * Converts a key name into a datastore name.
 *
 * @param {string} name
 * @returns {Key}
 * @private
 */ function DsName(name) {
    return new Key(keyPrefix + name);
}
/**
 * Converts a key name into a datastore info name.
 *
 * @param {string} name
 * @returns {Key}
 * @private
 */ function DsInfoName(name) {
    return new Key(infoPrefix + name);
}
/**
 * Manages the lifecycle of a key. Keys are encrypted at rest using PKCS #8.
 *
 * A key in the store has two entries
 * - '/info/*key-name*', contains the KeyInfo for the key
 * - '/pkcs8/*key-name*', contains the PKCS #8 for the key
 *
 */ class Keychain {
    /**
   * Creates a new instance of a key chain.
   *
   * @param {Datastore} store - where the key are.
   * @param {KeychainOptions} options
   * @class
   */ constructor(store, options){
        if (!store) throw new Error('store is required');
        this.store = store;
        this.opts = mergeOptions(defaultOptions, options);
        // Enforce NIST SP 800-132
        if (this.opts.pass && this.opts.pass.length < 20) throw new Error('pass must be least 20 characters');
        if (this.opts.dek.keyLength < NIST.minKeyLength) throw new Error(`dek.keyLength must be least ${NIST.minKeyLength} bytes`);
        if (this.opts.dek.salt.length < NIST.minSaltLength) throw new Error(`dek.saltLength must be least ${NIST.minSaltLength} bytes`);
        if (this.opts.dek.iterationCount < NIST.minIterationCount) throw new Error(`dek.iterationCount must be least ${NIST.minIterationCount}`);
        const dek = this.opts.pass ? crypto.pbkdf2(this.opts.pass, this.opts.dek.salt, this.opts.dek.iterationCount, this.opts.dek.keyLength, this.opts.dek.hash) : '';
        privates.set(this, {
            dek
        });
    }
    /**
   * Gets an object that can encrypt/decrypt protected data
   * using the Cryptographic Message Syntax (CMS).
   *
   * CMS describes an encapsulation syntax for data protection. It
   * is used to digitally sign, digest, authenticate, or encrypt
   * arbitrary message content.
   *
   * @returns {CMS}
   */ get cms() {
        return new CMS(this, privates.get(this).dek);
    }
    /**
   * Generates the options for a keychain.  A random salt is produced.
   *
   * @returns {Object}
   */ static generateOptions() {
        const options = Object.assign({
        }, defaultOptions);
        const saltLength = Math.ceil(NIST.minSaltLength / 3) * 3 // no base64 padding
        ;
        options.dek.salt = uint8ArrayToString(crypto.randomBytes(saltLength), 'base64');
        return options;
    }
    /**
   * Gets an object that can encrypt/decrypt protected data.
   * The default options for a keychain.
   *
   * @returns {Object}
   */ static get options() {
        return defaultOptions;
    }
    /**
   * Create a new key.
   *
   * @param {string} name - The local key name; cannot already exist.
   * @param {string} type - One of the key types; 'rsa'.
   * @param {number} [size = 2048] - The key size in bits. Used for rsa keys only.
   * @returns {Promise<KeyInfo>}
   */ async createKey(name, type, size = 2048) {
        const self = this;
        if (!validateKeyName(name) || name === 'self') return throwDelayed(errcode(new Error(`Invalid key name '${name}'`), 'ERR_INVALID_KEY_NAME'));
        if (typeof type !== 'string') return throwDelayed(errcode(new Error(`Invalid key type '${type}'`), 'ERR_INVALID_KEY_TYPE'));
        const dsname = DsName(name);
        const exists = await self.store.has(dsname);
        if (exists) return throwDelayed(errcode(new Error(`Key '${name}' already exists`), 'ERR_KEY_ALREADY_EXISTS'));
        switch(type.toLowerCase()){
            case 'rsa':
                if (!Number.isSafeInteger(size) || size < 2048) return throwDelayed(errcode(new Error(`Invalid RSA key size ${size}`), 'ERR_INVALID_KEY_SIZE'));
                break;
            default:
                break;
        }
        let keyInfo;
        try {
            // @ts-ignore Differences between several crypto return types need to be fixed in libp2p-crypto
            const keypair = await crypto.keys.generateKeyPair(type, size);
            const kid = await keypair.id();
            /** @type {string} */ const dek = privates.get(this).dek;
            const pem = await keypair.export(dek);
            keyInfo = {
                name: name,
                id: kid
            };
            const batch = self.store.batch();
            batch.put(dsname, uint8ArrayFromString(pem));
            batch.put(DsInfoName(name), uint8ArrayFromString(JSON.stringify(keyInfo)));
            await batch.commit();
        } catch (err) {
            return throwDelayed(err);
        }
        return keyInfo;
    }
    /**
   * List all the keys.
   *
   * @returns {Promise<KeyInfo[]>}
   */ async listKeys() {
        const self = this;
        const query = {
            prefix: infoPrefix
        };
        const info = [];
        for await (const value of self.store.query(query))info.push(JSON.parse(uint8ArrayToString(value.value)));
        return info;
    }
    /**
   * Find a key by it's id.
   *
   * @param {string} id - The universally unique key identifier.
   * @returns {Promise<KeyInfo|undefined>}
   */ async findKeyById(id) {
        try {
            const keys = await this.listKeys();
            return keys.find((k)=>k.id === id
            );
        } catch (err) {
            return throwDelayed(err);
        }
    }
    /**
   * Find a key by it's name.
   *
   * @param {string} name - The local key name.
   * @returns {Promise<KeyInfo>}
   */ async findKeyByName(name1) {
        if (!validateKeyName(name1)) return throwDelayed(errcode(new Error(`Invalid key name '${name1}'`), 'ERR_INVALID_KEY_NAME'));
        const dsname = DsInfoName(name1);
        try {
            const res = await this.store.get(dsname);
            return JSON.parse(uint8ArrayToString(res));
        } catch (err) {
            return throwDelayed(errcode(new Error(`Key '${name1}' does not exist. ${err.message}`), 'ERR_KEY_NOT_FOUND'));
        }
    }
    /**
   * Remove an existing key.
   *
   * @param {string} name - The local key name; must already exist.
   * @returns {Promise<KeyInfo>}
   */ async removeKey(name2) {
        const self = this;
        if (!validateKeyName(name2) || name2 === 'self') return throwDelayed(errcode(new Error(`Invalid key name '${name2}'`), 'ERR_INVALID_KEY_NAME'));
        const dsname = DsName(name2);
        const keyInfo = await self.findKeyByName(name2);
        const batch = self.store.batch();
        batch.delete(dsname);
        batch.delete(DsInfoName(name2));
        await batch.commit();
        return keyInfo;
    }
    /**
   * Rename a key
   *
   * @param {string} oldName - The old local key name; must already exist.
   * @param {string} newName - The new local key name; must not already exist.
   * @returns {Promise<KeyInfo>}
   */ async renameKey(oldName, newName) {
        const self = this;
        if (!validateKeyName(oldName) || oldName === 'self') return throwDelayed(errcode(new Error(`Invalid old key name '${oldName}'`), 'ERR_OLD_KEY_NAME_INVALID'));
        if (!validateKeyName(newName) || newName === 'self') return throwDelayed(errcode(new Error(`Invalid new key name '${newName}'`), 'ERR_NEW_KEY_NAME_INVALID'));
        const oldDsname = DsName(oldName);
        const newDsname = DsName(newName);
        const oldInfoName = DsInfoName(oldName);
        const newInfoName = DsInfoName(newName);
        const exists = await self.store.has(newDsname);
        if (exists) return throwDelayed(errcode(new Error(`Key '${newName}' already exists`), 'ERR_KEY_ALREADY_EXISTS'));
        try {
            const pem = await self.store.get(oldDsname);
            const res = await self.store.get(oldInfoName);
            const keyInfo = JSON.parse(uint8ArrayToString(res));
            keyInfo.name = newName;
            const batch = self.store.batch();
            batch.put(newDsname, pem);
            batch.put(newInfoName, uint8ArrayFromString(JSON.stringify(keyInfo)));
            batch.delete(oldDsname);
            batch.delete(oldInfoName);
            await batch.commit();
            return keyInfo;
        } catch (err) {
            return throwDelayed(err);
        }
    }
    /**
   * Export an existing key as a PEM encrypted PKCS #8 string
   *
   * @param {string} name - The local key name; must already exist.
   * @param {string} password - The password
   * @returns {Promise<string>}
   */ async exportKey(name3, password) {
        if (!validateKeyName(name3)) return throwDelayed(errcode(new Error(`Invalid key name '${name3}'`), 'ERR_INVALID_KEY_NAME'));
        if (!password) return throwDelayed(errcode(new Error('Password is required'), 'ERR_PASSWORD_REQUIRED'));
        const dsname = DsName(name3);
        try {
            const res = await this.store.get(dsname);
            const pem = uint8ArrayToString(res);
            /** @type {string} */ const dek = privates.get(this).dek;
            const privateKey = await crypto.keys.import(pem, dek);
            return privateKey.export(password);
        } catch (err) {
            return throwDelayed(err);
        }
    }
    /**
   * Import a new key from a PEM encoded PKCS #8 string
   *
   * @param {string} name - The local key name; must not already exist.
   * @param {string} pem - The PEM encoded PKCS #8 string
   * @param {string} password - The password.
   * @returns {Promise<KeyInfo>}
   */ async importKey(name4, pem, password1) {
        const self = this;
        if (!validateKeyName(name4) || name4 === 'self') return throwDelayed(errcode(new Error(`Invalid key name '${name4}'`), 'ERR_INVALID_KEY_NAME'));
        if (!pem) return throwDelayed(errcode(new Error('PEM encoded key is required'), 'ERR_PEM_REQUIRED'));
        const dsname = DsName(name4);
        const exists = await self.store.has(dsname);
        if (exists) return throwDelayed(errcode(new Error(`Key '${name4}' already exists`), 'ERR_KEY_ALREADY_EXISTS'));
        let privateKey;
        try {
            privateKey = await crypto.keys.import(pem, password1);
        } catch (err) {
            return throwDelayed(errcode(new Error('Cannot read the key, most likely the password is wrong'), 'ERR_CANNOT_READ_KEY'));
        }
        let kid;
        try {
            kid = await privateKey.id();
            /** @type {string} */ const dek = privates.get(this).dek;
            pem = await privateKey.export(dek);
        } catch (err1) {
            return throwDelayed(err1);
        }
        const keyInfo = {
            name: name4,
            id: kid
        };
        const batch = self.store.batch();
        batch.put(dsname, uint8ArrayFromString(pem));
        batch.put(DsInfoName(name4), uint8ArrayFromString(JSON.stringify(keyInfo)));
        await batch.commit();
        return keyInfo;
    }
    /**
   * Import a peer key
   *
   * @param {string} name - The local key name; must not already exist.
   * @param {PeerId} peer - The PEM encoded PKCS #8 string
   * @returns {Promise<KeyInfo>}
   */ async importPeer(name5, peer) {
        const self = this;
        if (!validateKeyName(name5)) return throwDelayed(errcode(new Error(`Invalid key name '${name5}'`), 'ERR_INVALID_KEY_NAME'));
        if (!peer || !peer.privKey) return throwDelayed(errcode(new Error('Peer.privKey is required'), 'ERR_MISSING_PRIVATE_KEY'));
        const privateKey = peer.privKey;
        const dsname = DsName(name5);
        const exists = await self.store.has(dsname);
        if (exists) return throwDelayed(errcode(new Error(`Key '${name5}' already exists`), 'ERR_KEY_ALREADY_EXISTS'));
        try {
            const kid = await privateKey.id();
            /** @type {string} */ const dek = privates.get(this).dek;
            const pem = await privateKey.export(dek);
            const keyInfo = {
                name: name5,
                id: kid
            };
            const batch = self.store.batch();
            batch.put(dsname, uint8ArrayFromString(pem));
            batch.put(DsInfoName(name5), uint8ArrayFromString(JSON.stringify(keyInfo)));
            await batch.commit();
            return keyInfo;
        } catch (err) {
            return throwDelayed(err);
        }
    }
    /**
   * Gets the private key as PEM encoded PKCS #8 string.
   *
   * @param {string} name
   * @returns {Promise<string>}
   */ async _getPrivateKey(name6) {
        if (!validateKeyName(name6)) return throwDelayed(errcode(new Error(`Invalid key name '${name6}'`), 'ERR_INVALID_KEY_NAME'));
        try {
            const dsname = DsName(name6);
            const res = await this.store.get(dsname);
            return uint8ArrayToString(res);
        } catch (err) {
            return throwDelayed(errcode(new Error(`Key '${name6}' does not exist. ${err.message}`), 'ERR_KEY_NOT_FOUND'));
        }
    }
    /**
   * Rotate keychain password and re-encrypt all assosciated keys
   *
   * @param {string} oldPass - The old local keychain password
   * @param {string} newPass - The new local keychain password
   */ async rotateKeychainPass(oldPass, newPass) {
        if (typeof oldPass !== 'string') return throwDelayed(errcode(new Error(`Invalid old pass type '${typeof oldPass}'`), 'ERR_INVALID_OLD_PASS_TYPE'));
        if (typeof newPass !== 'string') return throwDelayed(errcode(new Error(`Invalid new pass type '${typeof newPass}'`), 'ERR_INVALID_NEW_PASS_TYPE'));
        if (newPass.length < 20) return throwDelayed(errcode(new Error(`Invalid pass length ${newPass.length}`), 'ERR_INVALID_PASS_LENGTH'));
        log('recreating keychain');
        const oldDek = privates.get(this).dek;
        this.opts.pass = newPass;
        const newDek = newPass ? crypto.pbkdf2(newPass, this.opts.dek.salt, this.opts.dek.iterationCount, this.opts.dek.keyLength, this.opts.dek.hash) : '';
        privates.set(this, {
            dek: newDek
        });
        const keys = await this.listKeys();
        for (const key of keys){
            const res = await this.store.get(DsName(key.name));
            const pem = uint8ArrayToString(res);
            const privateKey = await crypto.keys.import(pem, oldDek);
            const password = newDek.toString();
            const keyAsPEM = await privateKey.export(password);
            // Update stored key
            const batch = this.store.batch();
            const keyInfo = {
                name: key.name,
                id: key.id
            };
            batch.put(DsName(key.name), uint8ArrayFromString(keyAsPEM));
            batch.put(DsInfoName(key.name), uint8ArrayFromString(JSON.stringify(keyInfo)));
            await batch.commit();
        }
        log('keychain reconstructed');
    }
}
module.exports = Keychain;

},{"debug":"lWlU4","sanitize-filename":"1kdjf","merge-options":"8VjFj","libp2p-crypto":"hsRcr","interface-datastore/key":"ccQWS","./cms":"kv1O2","err-code":"eQvyh","uint8arrays/to-string":"g3mCQ","uint8arrays/from-string":"lo45E","node-forge/lib/sha512":"kidGB"}],"1kdjf":[function(require,module,exports) {
/*jshint node:true*/ 'use strict';
/**
 * Replaces characters in strings that are illegal/unsafe for filenames.
 * Unsafe characters are either removed or replaced by a substitute set
 * in the optional `options` object.
 *
 * Illegal Characters on Various Operating Systems
 * / ? < > \ : * | "
 * https://kb.acronis.com/content/39790
 *
 * Unicode Control codes
 * C0 0x00-0x1f & C1 (0x80-0x9f)
 * http://en.wikipedia.org/wiki/C0_and_C1_control_codes
 *
 * Reserved filenames on Unix-based systems (".", "..")
 * Reserved filenames in Windows ("CON", "PRN", "AUX", "NUL", "COM1",
 * "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9",
 * "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", and
 * "LPT9") case-insesitively and with or without filename extensions.
 *
 * Capped at 255 characters in length.
 * http://unix.stackexchange.com/questions/32795/what-is-the-maximum-allowed-filename-and-folder-size-with-ecryptfs
 *
 * @param  {String} input   Original filename
 * @param  {Object} options {replacement: String | Function }
 * @return {String}         Sanitized filename
 */ var truncate = require("truncate-utf8-bytes");
var illegalRe = /[\/\?<>\\:\*\|"]/g;
var controlRe = /[\x00-\x1f\x80-\x9f]/g;
var reservedRe = /^\.+$/;
var windowsReservedRe = /^(con|prn|aux|nul|com[0-9]|lpt[0-9])(\..*)?$/i;
var windowsTrailingRe = /[\. ]+$/;
function sanitize(input, replacement) {
    if (typeof input !== 'string') throw new Error('Input must be string');
    var sanitized = input.replace(illegalRe, replacement).replace(controlRe, replacement).replace(reservedRe, replacement).replace(windowsReservedRe, replacement).replace(windowsTrailingRe, replacement);
    return truncate(sanitized, 255);
}
module.exports = function(input, options) {
    var replacement = options && options.replacement || '';
    var output = sanitize(input, replacement);
    if (replacement === '') return output;
    return sanitize(output, '');
};

},{"truncate-utf8-bytes":"bvMRR"}],"bvMRR":[function(require,module,exports) {
'use strict';
var truncate = require("./lib/truncate");
var getLength = require("utf8-byte-length/browser");
module.exports = truncate.bind(null, getLength);

},{"./lib/truncate":"l45GT","utf8-byte-length/browser":"5Wgia"}],"l45GT":[function(require,module,exports) {
'use strict';
function isHighSurrogate(codePoint) {
    return codePoint >= 55296 && codePoint <= 56319;
}
function isLowSurrogate(codePoint) {
    return codePoint >= 56320 && codePoint <= 57343;
}
// Truncate string by size in bytes
module.exports = function truncate(getLength, string, byteLength) {
    if (typeof string !== "string") throw new Error("Input must be string");
    var charLength = string.length;
    var curByteLength = 0;
    var codePoint;
    var segment;
    for(var i = 0; i < charLength; i += 1){
        codePoint = string.charCodeAt(i);
        segment = string[i];
        if (isHighSurrogate(codePoint) && isLowSurrogate(string.charCodeAt(i + 1))) {
            i += 1;
            segment += string[i];
        }
        curByteLength += getLength(segment);
        if (curByteLength === byteLength) return string.slice(0, i + 1);
        else if (curByteLength > byteLength) return string.slice(0, i - segment.length + 1);
    }
    return string;
};

},{}],"5Wgia":[function(require,module,exports) {
'use strict';
function isHighSurrogate(codePoint) {
    return codePoint >= 55296 && codePoint <= 56319;
}
function isLowSurrogate(codePoint) {
    return codePoint >= 56320 && codePoint <= 57343;
}
// Truncate string by size in bytes
module.exports = function getByteLength(string) {
    if (typeof string !== "string") throw new Error("Input must be string");
    var charLength = string.length;
    var byteLength = 0;
    var codePoint = null;
    var prevCodePoint = null;
    for(var i = 0; i < charLength; i++){
        codePoint = string.charCodeAt(i);
        // handle 4-byte non-BMP chars
        // low surrogate
        if (isLowSurrogate(codePoint)) {
            // when parsing previous hi-surrogate, 3 is added to byteLength
            if (prevCodePoint != null && isHighSurrogate(prevCodePoint)) byteLength += 1;
            else byteLength += 3;
        } else if (codePoint <= 127) byteLength += 1;
        else if (codePoint >= 128 && codePoint <= 2047) byteLength += 2;
        else if (codePoint >= 2048 && codePoint <= 65535) byteLength += 3;
        prevCodePoint = codePoint;
    }
    return byteLength;
};

},{}],"kv1O2":[function(require,module,exports) {
'use strict';
// @ts-ignore node-forge types not exported
require('node-forge/lib/pkcs7');
// @ts-ignore node-forge types not exported
require('node-forge/lib/pbe');
// @ts-ignore node-forge types not exported
const forge = require('node-forge/lib/forge');
const { certificateForKey , findAsync  } = require('./util');
const errcode = require('err-code');
const { fromString: uint8ArrayFromString  } = require('uint8arrays/from-string');
const { toString: uint8ArrayToString  } = require('uint8arrays/to-string');
const privates = new WeakMap();
/**
 * Cryptographic Message Syntax (aka PKCS #7)
 *
 * CMS describes an encapsulation syntax for data protection. It
 * is used to digitally sign, digest, authenticate, or encrypt
 * arbitrary message content.
 *
 * See RFC 5652 for all the details.
 */ class CMS {
    /**
   * Creates a new instance with a keychain
   *
   * @param {import('./index')} keychain - the available keys
   * @param {string} dek
   */ constructor(keychain, dek){
        if (!keychain) throw errcode(new Error('keychain is required'), 'ERR_KEYCHAIN_REQUIRED');
        this.keychain = keychain;
        privates.set(this, {
            dek
        });
    }
    /**
   * Creates some protected data.
   *
   * The output Uint8Array contains the PKCS #7 message in DER.
   *
   * @param {string} name - The local key name.
   * @param {Uint8Array} plain - The data to encrypt.
   * @returns {Promise<Uint8Array>}
   */ async encrypt(name, plain) {
        if (!(plain instanceof Uint8Array)) throw errcode(new Error('Plain data must be a Uint8Array'), 'ERR_INVALID_PARAMS');
        const key = await this.keychain.findKeyByName(name);
        const pem = await this.keychain._getPrivateKey(name);
        /** @type {string} */ const dek = privates.get(this).dek;
        const privateKey = forge.pki.decryptRsaPrivateKey(pem, dek);
        const certificate = await certificateForKey(key, privateKey);
        // create a p7 enveloped message
        const p7 = forge.pkcs7.createEnvelopedData();
        p7.addRecipient(certificate);
        p7.content = forge.util.createBuffer(plain);
        p7.encrypt();
        // convert message to DER
        const der = forge.asn1.toDer(p7.toAsn1()).getBytes();
        return uint8ArrayFromString(der, 'ascii');
    }
    /**
   * Reads some protected data.
   *
   * The keychain must contain one of the keys used to encrypt the data.  If none of the keys
   * exists, an Error is returned with the property 'missingKeys'.  It is array of key ids.
   *
   * @param {Uint8Array} cmsData - The CMS encrypted data to decrypt.
   * @returns {Promise<Uint8Array>}
   */ async decrypt(cmsData) {
        if (!(cmsData instanceof Uint8Array)) throw errcode(new Error('CMS data is required'), 'ERR_INVALID_PARAMS');
        let cms;
        try {
            const buf = forge.util.createBuffer(uint8ArrayToString(cmsData, 'ascii'));
            const obj = forge.asn1.fromDer(buf);
            // @ts-ignore not defined
            cms = forge.pkcs7.messageFromAsn1(obj);
        } catch (err) {
            throw errcode(new Error('Invalid CMS: ' + err.message), 'ERR_INVALID_CMS');
        }
        // Find a recipient whose key we hold. We only deal with recipient certs
        // issued by ipfs (O=ipfs).
        const recipients = cms.recipients// @ts-ignore cms types not defined
        .filter((r)=>r.issuer.find((a)=>a.shortName === 'O' && a.value === 'ipfs'
            )
        )// @ts-ignore cms types not defined
        .filter((r)=>r.issuer.find((a)=>a.shortName === 'CN'
            )
        )// @ts-ignore cms types not defined
        .map((r)=>{
            return {
                recipient: r,
                // @ts-ignore cms types not defined
                keyId: r.issuer.find((a)=>a.shortName === 'CN'
                ).value
            };
        });
        const r1 = await findAsync(recipients, async (recipient)=>{
            try {
                const key = await this.keychain.findKeyById(recipient.keyId);
                if (key) return true;
            } catch (err) {
                return false;
            }
            return false;
        });
        if (!r1) {
            // @ts-ignore cms types not defined
            const missingKeys = recipients.map((r)=>r.keyId
            );
            throw errcode(new Error('Decryption needs one of the key(s): ' + missingKeys.join(', ')), 'ERR_MISSING_KEYS', {
                missingKeys
            });
        }
        const key1 = await this.keychain.findKeyById(r1.keyId);
        if (!key1) throw errcode(new Error('No key available to decrypto'), 'ERR_NO_KEY');
        const pem = await this.keychain._getPrivateKey(key1.name);
        const dek = privates.get(this).dek;
        const privateKey = forge.pki.decryptRsaPrivateKey(pem, dek);
        cms.decrypt(r1.recipient, privateKey);
        return uint8ArrayFromString(cms.content.getBytes(), 'ascii');
    }
}
module.exports = CMS;

},{"node-forge/lib/pkcs7":"8lWqk","node-forge/lib/pbe":"klwlu","node-forge/lib/forge":"7AnVp","./util":"fMRaI","err-code":"eQvyh","uint8arrays/from-string":"lo45E","uint8arrays/to-string":"g3mCQ"}],"8lWqk":[function(require,module,exports) {
/**
 * Javascript implementation of PKCS#7 v1.5.
 *
 * @author Stefan Siegl
 * @author Dave Longley
 *
 * Copyright (c) 2012 Stefan Siegl <stesie@brokenpipe.de>
 * Copyright (c) 2012-2015 Digital Bazaar, Inc.
 *
 * Currently this implementation only supports ContentType of EnvelopedData,
 * EncryptedData, or SignedData at the root level. The top level elements may
 * contain only a ContentInfo of ContentType Data, i.e. plain data. Further
 * nesting is not (yet) supported.
 *
 * The Forge validators for PKCS #7's ASN.1 structures are available from
 * a separate file pkcs7asn1.js, since those are referenced from other
 * PKCS standards like PKCS #12.
 */ var forge = require('./forge');
require('./aes');
require('./asn1');
require('./des');
require('./oids');
require('./pem');
require('./pkcs7asn1');
require('./random');
require('./util');
require('./x509');
// shortcut for ASN.1 API
var asn1 = forge.asn1;
// shortcut for PKCS#7 API
var p7 = module.exports = forge.pkcs7 = forge.pkcs7 || {
};
/**
 * Converts a PKCS#7 message from PEM format.
 *
 * @param pem the PEM-formatted PKCS#7 message.
 *
 * @return the PKCS#7 message.
 */ p7.messageFromPem = function(pem) {
    var msg = forge.pem.decode(pem)[0];
    if (msg.type !== 'PKCS7') {
        var error = new Error("Could not convert PKCS#7 message from PEM; PEM header type is not \"PKCS#7\".");
        error.headerType = msg.type;
        throw error;
    }
    if (msg.procType && msg.procType.type === 'ENCRYPTED') throw new Error('Could not convert PKCS#7 message from PEM; PEM is encrypted.');
    // convert DER to ASN.1 object
    var obj = asn1.fromDer(msg.body);
    return p7.messageFromAsn1(obj);
};
/**
 * Converts a PKCS#7 message to PEM format.
 *
 * @param msg The PKCS#7 message object
 * @param maxline The maximum characters per line, defaults to 64.
 *
 * @return The PEM-formatted PKCS#7 message.
 */ p7.messageToPem = function(msg, maxline) {
    // convert to ASN.1, then DER, then PEM-encode
    var pemObj = {
        type: 'PKCS7',
        body: asn1.toDer(msg.toAsn1()).getBytes()
    };
    return forge.pem.encode(pemObj, {
        maxline: maxline
    });
};
/**
 * Converts a PKCS#7 message from an ASN.1 object.
 *
 * @param obj the ASN.1 representation of a ContentInfo.
 *
 * @return the PKCS#7 message.
 */ p7.messageFromAsn1 = function(obj) {
    // validate root level ContentInfo and capture data
    var capture = {
    };
    var errors = [];
    if (!asn1.validate(obj, p7.asn1.contentInfoValidator, capture, errors)) {
        var error = new Error("Cannot read PKCS#7 message. ASN.1 object is not an PKCS#7 ContentInfo.");
        error.errors = errors;
        throw error;
    }
    var contentType = asn1.derToOid(capture.contentType);
    var msg;
    switch(contentType){
        case forge.pki.oids.envelopedData:
            msg = p7.createEnvelopedData();
            break;
        case forge.pki.oids.encryptedData:
            msg = p7.createEncryptedData();
            break;
        case forge.pki.oids.signedData:
            msg = p7.createSignedData();
            break;
        default:
            throw new Error('Cannot read PKCS#7 message. ContentType with OID ' + contentType + ' is not (yet) supported.');
    }
    msg.fromAsn1(capture.content.value[0]);
    return msg;
};
p7.createSignedData = function() {
    var msg = null;
    msg = {
        type: forge.pki.oids.signedData,
        version: 1,
        certificates: [],
        crls: [],
        // TODO: add json-formatted signer stuff here?
        signers: [],
        // populated during sign()
        digestAlgorithmIdentifiers: [],
        contentInfo: null,
        signerInfos: [],
        fromAsn1: function(obj) {
            // validate SignedData content block and capture data.
            _fromAsn1(msg, obj, p7.asn1.signedDataValidator);
            msg.certificates = [];
            msg.crls = [];
            msg.digestAlgorithmIdentifiers = [];
            msg.contentInfo = null;
            msg.signerInfos = [];
            if (msg.rawCapture.certificates) {
                var certs = msg.rawCapture.certificates.value;
                for(var i = 0; i < certs.length; ++i)msg.certificates.push(forge.pki.certificateFromAsn1(certs[i]));
            }
        // TODO: parse crls
        },
        toAsn1: function() {
            // degenerate case with no content
            if (!msg.contentInfo) msg.sign();
            var certs = [];
            for(var i = 0; i < msg.certificates.length; ++i)certs.push(forge.pki.certificateToAsn1(msg.certificates[i]));
            var crls = [];
            // TODO: implement CRLs
            // [0] SignedData
            var signedData = asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [
                asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
                    // Version
                    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, asn1.integerToDer(msg.version).getBytes()),
                    // DigestAlgorithmIdentifiers
                    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SET, true, msg.digestAlgorithmIdentifiers),
                    // ContentInfo
                    msg.contentInfo
                ])
            ]);
            if (certs.length > 0) // [0] IMPLICIT ExtendedCertificatesAndCertificates OPTIONAL
            signedData.value[0].value.push(asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, certs));
            if (crls.length > 0) // [1] IMPLICIT CertificateRevocationLists OPTIONAL
            signedData.value[0].value.push(asn1.create(asn1.Class.CONTEXT_SPECIFIC, 1, true, crls));
            // SignerInfos
            signedData.value[0].value.push(asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SET, true, msg.signerInfos));
            // ContentInfo
            return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
                // ContentType
                asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(msg.type).getBytes()),
                // [0] SignedData
                signedData
            ]);
        },
        /**
     * Add (another) entity to list of signers.
     *
     * Note: If authenticatedAttributes are provided, then, per RFC 2315,
     * they must include at least two attributes: content type and
     * message digest. The message digest attribute value will be
     * auto-calculated during signing and will be ignored if provided.
     *
     * Here's an example of providing these two attributes:
     *
     * forge.pkcs7.createSignedData();
     * p7.addSigner({
     *   issuer: cert.issuer.attributes,
     *   serialNumber: cert.serialNumber,
     *   key: privateKey,
     *   digestAlgorithm: forge.pki.oids.sha1,
     *   authenticatedAttributes: [{
     *     type: forge.pki.oids.contentType,
     *     value: forge.pki.oids.data
     *   }, {
     *     type: forge.pki.oids.messageDigest
     *   }]
     * });
     *
     * TODO: Support [subjectKeyIdentifier] as signer's ID.
     *
     * @param signer the signer information:
     *          key the signer's private key.
     *          [certificate] a certificate containing the public key
     *            associated with the signer's private key; use this option as
     *            an alternative to specifying signer.issuer and
     *            signer.serialNumber.
     *          [issuer] the issuer attributes (eg: cert.issuer.attributes).
     *          [serialNumber] the signer's certificate's serial number in
     *           hexadecimal (eg: cert.serialNumber).
     *          [digestAlgorithm] the message digest OID, as a string, to use
     *            (eg: forge.pki.oids.sha1).
     *          [authenticatedAttributes] an optional array of attributes
     *            to also sign along with the content.
     */ addSigner: function(signer) {
            var issuer = signer.issuer;
            var serialNumber = signer.serialNumber;
            if (signer.certificate) {
                var cert = signer.certificate;
                if (typeof cert === 'string') cert = forge.pki.certificateFromPem(cert);
                issuer = cert.issuer.attributes;
                serialNumber = cert.serialNumber;
            }
            var key = signer.key;
            if (!key) throw new Error('Could not add PKCS#7 signer; no private key specified.');
            if (typeof key === 'string') key = forge.pki.privateKeyFromPem(key);
            // ensure OID known for digest algorithm
            var digestAlgorithm = signer.digestAlgorithm || forge.pki.oids.sha1;
            switch(digestAlgorithm){
                case forge.pki.oids.sha1:
                case forge.pki.oids.sha256:
                case forge.pki.oids.sha384:
                case forge.pki.oids.sha512:
                case forge.pki.oids.md5:
                    break;
                default:
                    throw new Error('Could not add PKCS#7 signer; unknown message digest algorithm: ' + digestAlgorithm);
            }
            // if authenticatedAttributes is present, then the attributes
            // must contain at least PKCS #9 content-type and message-digest
            var authenticatedAttributes = signer.authenticatedAttributes || [];
            if (authenticatedAttributes.length > 0) {
                var contentType = false;
                var messageDigest = false;
                for(var i = 0; i < authenticatedAttributes.length; ++i){
                    var attr = authenticatedAttributes[i];
                    if (!contentType && attr.type === forge.pki.oids.contentType) {
                        contentType = true;
                        if (messageDigest) break;
                        continue;
                    }
                    if (!messageDigest && attr.type === forge.pki.oids.messageDigest) {
                        messageDigest = true;
                        if (contentType) break;
                        continue;
                    }
                }
                if (!contentType || !messageDigest) throw new Error("Invalid signer.authenticatedAttributes. If signer.authenticatedAttributes is specified, then it must contain at least two attributes, PKCS #9 content-type and PKCS #9 message-digest.");
            }
            msg.signers.push({
                key: key,
                version: 1,
                issuer: issuer,
                serialNumber: serialNumber,
                digestAlgorithm: digestAlgorithm,
                signatureAlgorithm: forge.pki.oids.rsaEncryption,
                signature: null,
                authenticatedAttributes: authenticatedAttributes,
                unauthenticatedAttributes: []
            });
        },
        /**
     * Signs the content.
     * @param options Options to apply when signing:
     *    [detached] boolean. If signing should be done in detached mode. Defaults to false.
     */ sign: function(options) {
            options = options || {
            };
            // auto-generate content info
            if (typeof msg.content !== 'object' || msg.contentInfo === null) {
                // use Data ContentInfo
                msg.contentInfo = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
                    // ContentType
                    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(forge.pki.oids.data).getBytes())
                ]);
                // add actual content, if present
                if ('content' in msg) {
                    var content;
                    if (msg.content instanceof forge.util.ByteBuffer) content = msg.content.bytes();
                    else if (typeof msg.content === 'string') content = forge.util.encodeUtf8(msg.content);
                    if (options.detached) msg.detachedContent = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, content);
                    else msg.contentInfo.value.push(// [0] EXPLICIT content
                    asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [
                        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, content)
                    ]));
                }
            }
            // no signers, return early (degenerate case for certificate container)
            if (msg.signers.length === 0) return;
            // generate digest algorithm identifiers
            var mds = addDigestAlgorithmIds();
            // generate signerInfos
            addSignerInfos(mds);
        },
        verify: function() {
            throw new Error('PKCS#7 signature verification not yet implemented.');
        },
        /**
     * Add a certificate.
     *
     * @param cert the certificate to add.
     */ addCertificate: function(cert) {
            // convert from PEM
            if (typeof cert === 'string') cert = forge.pki.certificateFromPem(cert);
            msg.certificates.push(cert);
        },
        /**
     * Add a certificate revokation list.
     *
     * @param crl the certificate revokation list to add.
     */ addCertificateRevokationList: function(crl) {
            throw new Error('PKCS#7 CRL support not yet implemented.');
        }
    };
    function addDigestAlgorithmIds() {
        var mds = {
        };
        for(var i = 0; i < msg.signers.length; ++i){
            var signer = msg.signers[i];
            var oid = signer.digestAlgorithm;
            if (!(oid in mds)) {
                // content digest
                mds[oid] = forge.md[forge.pki.oids[oid]].create();
            }
            if (signer.authenticatedAttributes.length === 0) {
                // no custom attributes to digest; use content message digest
                signer.md = mds[oid];
            } else {
                // custom attributes to be digested; use own message digest
                // TODO: optimize to just copy message digest state if that
                // feature is ever supported with message digests
                signer.md = forge.md[forge.pki.oids[oid]].create();
            }
        }
        // add unique digest algorithm identifiers
        msg.digestAlgorithmIdentifiers = [];
        for(var oid in mds){
            msg.digestAlgorithmIdentifiers.push(// AlgorithmIdentifier
            asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
                // algorithm
                asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(oid).getBytes()),
                // parameters (null)
                asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '')
            ]));
        }
        return mds;
    }
    function addSignerInfos(mds) {
        var content;
        if (msg.detachedContent) {
            // Signature has been made in detached mode.
            content = msg.detachedContent;
        } else {
            // Note: ContentInfo is a SEQUENCE with 2 values, second value is
            // the content field and is optional for a ContentInfo but required here
            // since signers are present
            // get ContentInfo content
            content = msg.contentInfo.value[1];
            // skip [0] EXPLICIT content wrapper
            content = content.value[0];
        }
        if (!content) {
            throw new Error('Could not sign PKCS#7 message; there is no content to sign.');
        }
        // get ContentInfo content type
        var contentType = asn1.derToOid(msg.contentInfo.value[0].value);
        // serialize content
        var bytes = asn1.toDer(content);
        // skip identifier and length per RFC 2315 9.3
        // skip identifier (1 byte)
        bytes.getByte();
        // read and discard length bytes
        asn1.getBerValueLength(bytes);
        bytes = bytes.getBytes();
        // digest content DER value bytes
        for(var oid in mds){
            mds[oid].start().update(bytes);
        }
        // sign content
        var signingTime = new Date();
        for(var i = 0; i < msg.signers.length; ++i){
            var signer = msg.signers[i];
            if (signer.authenticatedAttributes.length === 0) {
                // if ContentInfo content type is not "Data", then
                // authenticatedAttributes must be present per RFC 2315
                if (contentType !== forge.pki.oids.data) {
                    throw new Error("Invalid signer; authenticatedAttributes must be present when the ContentInfo content type is not PKCS#7 Data.");
                }
            } else {
                // process authenticated attributes
                // [0] IMPLICIT
                signer.authenticatedAttributesAsn1 = asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, []);
                // per RFC 2315, attributes are to be digested using a SET container
                // not the above [0] IMPLICIT container
                var attrsAsn1 = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SET, true, []);
                for(var ai = 0; ai < signer.authenticatedAttributes.length; ++ai){
                    var attr = signer.authenticatedAttributes[ai];
                    if (attr.type === forge.pki.oids.messageDigest) {
                        // use content message digest as value
                        attr.value = mds[signer.digestAlgorithm].digest();
                    } else if (attr.type === forge.pki.oids.signingTime) {
                        // auto-populate signing time if not already set
                        if (!attr.value) {
                            attr.value = signingTime;
                        }
                    }
                    // convert to ASN.1 and push onto Attributes SET (for signing) and
                    // onto authenticatedAttributesAsn1 to complete SignedData ASN.1
                    // TODO: optimize away duplication
                    attrsAsn1.value.push(_attributeToAsn1(attr));
                    signer.authenticatedAttributesAsn1.value.push(_attributeToAsn1(attr));
                }
                // DER-serialize and digest SET OF attributes only
                bytes = asn1.toDer(attrsAsn1).getBytes();
                signer.md.start().update(bytes);
            }
            // sign digest
            signer.signature = signer.key.sign(signer.md, 'RSASSA-PKCS1-V1_5');
        }
        // add signer info
        msg.signerInfos = _signersToAsn1(msg.signers);
    }
    return msg;
};
/**
 * Creates an empty PKCS#7 message of type EncryptedData.
 *
 * @return the message.
 */ p7.createEncryptedData = function() {
    var msg = null;
    msg = {
        type: forge.pki.oids.encryptedData,
        version: 0,
        encryptedContent: {
            algorithm: forge.pki.oids['aes256-CBC']
        },
        /**
     * Reads an EncryptedData content block (in ASN.1 format)
     *
     * @param obj The ASN.1 representation of the EncryptedData content block
     */ fromAsn1: function(obj) {
            // Validate EncryptedData content block and capture data.
            _fromAsn1(msg, obj, p7.asn1.encryptedDataValidator);
        },
        /**
     * Decrypt encrypted content
     *
     * @param key The (symmetric) key as a byte buffer
     */ decrypt: function(key) {
            if (key !== undefined) msg.encryptedContent.key = key;
            _decryptContent(msg);
        }
    };
    return msg;
};
/**
 * Creates an empty PKCS#7 message of type EnvelopedData.
 *
 * @return the message.
 */ p7.createEnvelopedData = function() {
    var msg = null;
    msg = {
        type: forge.pki.oids.envelopedData,
        version: 0,
        recipients: [],
        encryptedContent: {
            algorithm: forge.pki.oids['aes256-CBC']
        },
        /**
     * Reads an EnvelopedData content block (in ASN.1 format)
     *
     * @param obj the ASN.1 representation of the EnvelopedData content block.
     */ fromAsn1: function(obj) {
            // validate EnvelopedData content block and capture data
            var capture = _fromAsn1(msg, obj, p7.asn1.envelopedDataValidator);
            msg.recipients = _recipientsFromAsn1(capture.recipientInfos.value);
        },
        toAsn1: function() {
            // ContentInfo
            return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
                // ContentType
                asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(msg.type).getBytes()),
                // [0] EnvelopedData
                asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [
                    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
                        // Version
                        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, asn1.integerToDer(msg.version).getBytes()),
                        // RecipientInfos
                        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SET, true, _recipientsToAsn1(msg.recipients)),
                        // EncryptedContentInfo
                        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, _encryptedContentToAsn1(msg.encryptedContent))
                    ])
                ])
            ]);
        },
        /**
     * Find recipient by X.509 certificate's issuer.
     *
     * @param cert the certificate with the issuer to look for.
     *
     * @return the recipient object.
     */ findRecipient: function(cert) {
            var sAttr = cert.issuer.attributes;
            for(var i = 0; i < msg.recipients.length; ++i){
                var r = msg.recipients[i];
                var rAttr = r.issuer;
                if (r.serialNumber !== cert.serialNumber) continue;
                if (rAttr.length !== sAttr.length) continue;
                var match = true;
                for(var j = 0; j < sAttr.length; ++j)if (rAttr[j].type !== sAttr[j].type || rAttr[j].value !== sAttr[j].value) {
                    match = false;
                    break;
                }
                if (match) return r;
            }
            return null;
        },
        /**
     * Decrypt enveloped content
     *
     * @param recipient The recipient object related to the private key
     * @param privKey The (RSA) private key object
     */ decrypt: function(recipient, privKey) {
            if (msg.encryptedContent.key === undefined && recipient !== undefined && privKey !== undefined) switch(recipient.encryptedContent.algorithm){
                case forge.pki.oids.rsaEncryption:
                case forge.pki.oids.desCBC:
                    var key = privKey.decrypt(recipient.encryptedContent.content);
                    msg.encryptedContent.key = forge.util.createBuffer(key);
                    break;
                default:
                    throw new Error("Unsupported asymmetric cipher, OID " + recipient.encryptedContent.algorithm);
            }
            _decryptContent(msg);
        },
        /**
     * Add (another) entity to list of recipients.
     *
     * @param cert The certificate of the entity to add.
     */ addRecipient: function(cert) {
            msg.recipients.push({
                version: 0,
                issuer: cert.issuer.attributes,
                serialNumber: cert.serialNumber,
                encryptedContent: {
                    // We simply assume rsaEncryption here, since forge.pki only
                    // supports RSA so far.  If the PKI module supports other
                    // ciphers one day, we need to modify this one as well.
                    algorithm: forge.pki.oids.rsaEncryption,
                    key: cert.publicKey
                }
            });
        },
        /**
     * Encrypt enveloped content.
     *
     * This function supports two optional arguments, cipher and key, which
     * can be used to influence symmetric encryption.  Unless cipher is
     * provided, the cipher specified in encryptedContent.algorithm is used
     * (defaults to AES-256-CBC).  If no key is provided, encryptedContent.key
     * is (re-)used.  If that one's not set, a random key will be generated
     * automatically.
     *
     * @param [key] The key to be used for symmetric encryption.
     * @param [cipher] The OID of the symmetric cipher to use.
     */ encrypt: function(key, cipher) {
            // Part 1: Symmetric encryption
            if (msg.encryptedContent.content === undefined) {
                cipher = cipher || msg.encryptedContent.algorithm;
                key = key || msg.encryptedContent.key;
                var keyLen, ivLen, ciphFn;
                switch(cipher){
                    case forge.pki.oids['aes128-CBC']:
                        keyLen = 16;
                        ivLen = 16;
                        ciphFn = forge.aes.createEncryptionCipher;
                        break;
                    case forge.pki.oids['aes192-CBC']:
                        keyLen = 24;
                        ivLen = 16;
                        ciphFn = forge.aes.createEncryptionCipher;
                        break;
                    case forge.pki.oids['aes256-CBC']:
                        keyLen = 32;
                        ivLen = 16;
                        ciphFn = forge.aes.createEncryptionCipher;
                        break;
                    case forge.pki.oids['des-EDE3-CBC']:
                        keyLen = 24;
                        ivLen = 8;
                        ciphFn = forge.des.createEncryptionCipher;
                        break;
                    default:
                        throw new Error('Unsupported symmetric cipher, OID ' + cipher);
                }
                if (key === undefined) key = forge.util.createBuffer(forge.random.getBytes(keyLen));
                else if (key.length() != keyLen) throw new Error("Symmetric key has wrong length; got " + key.length() + ' bytes, expected ' + keyLen + '.');
                // Keep a copy of the key & IV in the object, so the caller can
                // use it for whatever reason.
                msg.encryptedContent.algorithm = cipher;
                msg.encryptedContent.key = key;
                msg.encryptedContent.parameter = forge.util.createBuffer(forge.random.getBytes(ivLen));
                var ciph = ciphFn(key);
                ciph.start(msg.encryptedContent.parameter.copy());
                ciph.update(msg.content);
                // The finish function does PKCS#7 padding by default, therefore
                // no action required by us.
                if (!ciph.finish()) throw new Error('Symmetric encryption failed.');
                msg.encryptedContent.content = ciph.output;
            }
            // Part 2: asymmetric encryption for each recipient
            for(var i = 0; i < msg.recipients.length; ++i){
                var recipient = msg.recipients[i];
                // Nothing to do, encryption already done.
                if (recipient.encryptedContent.content !== undefined) continue;
                switch(recipient.encryptedContent.algorithm){
                    case forge.pki.oids.rsaEncryption:
                        recipient.encryptedContent.content = recipient.encryptedContent.key.encrypt(msg.encryptedContent.key.data);
                        break;
                    default:
                        throw new Error('Unsupported asymmetric cipher, OID ' + recipient.encryptedContent.algorithm);
                }
            }
        }
    };
    return msg;
};
/**
 * Converts a single recipient from an ASN.1 object.
 *
 * @param obj the ASN.1 RecipientInfo.
 *
 * @return the recipient object.
 */ function _recipientFromAsn1(obj) {
    // validate EnvelopedData content block and capture data
    var capture = {
    };
    var errors = [];
    if (!asn1.validate(obj, p7.asn1.recipientInfoValidator, capture, errors)) {
        var error = new Error("Cannot read PKCS#7 RecipientInfo. ASN.1 object is not an PKCS#7 RecipientInfo.");
        error.errors = errors;
        throw error;
    }
    return {
        version: capture.version.charCodeAt(0),
        issuer: forge.pki.RDNAttributesAsArray(capture.issuer),
        serialNumber: forge.util.createBuffer(capture.serial).toHex(),
        encryptedContent: {
            algorithm: asn1.derToOid(capture.encAlgorithm),
            parameter: capture.encParameter.value,
            content: capture.encKey
        }
    };
}
/**
 * Converts a single recipient object to an ASN.1 object.
 *
 * @param obj the recipient object.
 *
 * @return the ASN.1 RecipientInfo.
 */ function _recipientToAsn1(obj) {
    return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
        // Version
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, asn1.integerToDer(obj.version).getBytes()),
        // IssuerAndSerialNumber
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
            // Name
            forge.pki.distinguishedNameToAsn1({
                attributes: obj.issuer
            }),
            // Serial
            asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, forge.util.hexToBytes(obj.serialNumber))
        ]),
        // KeyEncryptionAlgorithmIdentifier
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
            // Algorithm
            asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(obj.encryptedContent.algorithm).getBytes()),
            // Parameter, force NULL, only RSA supported for now.
            asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '')
        ]),
        // EncryptedKey
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, obj.encryptedContent.content)
    ]);
}
/**
 * Map a set of RecipientInfo ASN.1 objects to recipient objects.
 *
 * @param infos an array of ASN.1 representations RecipientInfo (i.e. SET OF).
 *
 * @return an array of recipient objects.
 */ function _recipientsFromAsn1(infos) {
    var ret = [];
    for(var i = 0; i < infos.length; ++i)ret.push(_recipientFromAsn1(infos[i]));
    return ret;
}
/**
 * Map an array of recipient objects to ASN.1 RecipientInfo objects.
 *
 * @param recipients an array of recipientInfo objects.
 *
 * @return an array of ASN.1 RecipientInfos.
 */ function _recipientsToAsn1(recipients) {
    var ret = [];
    for(var i = 0; i < recipients.length; ++i)ret.push(_recipientToAsn1(recipients[i]));
    return ret;
}
/**
 * Converts a single signer from an ASN.1 object.
 *
 * @param obj the ASN.1 representation of a SignerInfo.
 *
 * @return the signer object.
 */ function _signerFromAsn1(obj) {
    // validate EnvelopedData content block and capture data
    var capture = {
    };
    var errors = [];
    if (!asn1.validate(obj, p7.asn1.signerInfoValidator, capture, errors)) {
        var error = new Error("Cannot read PKCS#7 SignerInfo. ASN.1 object is not an PKCS#7 SignerInfo.");
        error.errors = errors;
        throw error;
    }
    var rval = {
        version: capture.version.charCodeAt(0),
        issuer: forge.pki.RDNAttributesAsArray(capture.issuer),
        serialNumber: forge.util.createBuffer(capture.serial).toHex(),
        digestAlgorithm: asn1.derToOid(capture.digestAlgorithm),
        signatureAlgorithm: asn1.derToOid(capture.signatureAlgorithm),
        signature: capture.signature,
        authenticatedAttributes: [],
        unauthenticatedAttributes: []
    };
    // TODO: convert attributes
    var authenticatedAttributes = capture.authenticatedAttributes || [];
    var unauthenticatedAttributes = capture.unauthenticatedAttributes || [];
    return rval;
}
/**
 * Converts a single signerInfo object to an ASN.1 object.
 *
 * @param obj the signerInfo object.
 *
 * @return the ASN.1 representation of a SignerInfo.
 */ function _signerToAsn1(obj) {
    // SignerInfo
    var rval = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
        // version
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, asn1.integerToDer(obj.version).getBytes()),
        // issuerAndSerialNumber
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
            // name
            forge.pki.distinguishedNameToAsn1({
                attributes: obj.issuer
            }),
            // serial
            asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, forge.util.hexToBytes(obj.serialNumber))
        ]),
        // digestAlgorithm
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
            // algorithm
            asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(obj.digestAlgorithm).getBytes()),
            // parameters (null)
            asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '')
        ])
    ]);
    // authenticatedAttributes (OPTIONAL)
    if (obj.authenticatedAttributesAsn1) // add ASN.1 previously generated during signing
    rval.value.push(obj.authenticatedAttributesAsn1);
    // digestEncryptionAlgorithm
    rval.value.push(asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
        // algorithm
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(obj.signatureAlgorithm).getBytes()),
        // parameters (null)
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '')
    ]));
    // encryptedDigest
    rval.value.push(asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, obj.signature));
    // unauthenticatedAttributes (OPTIONAL)
    if (obj.unauthenticatedAttributes.length > 0) {
        // [1] IMPLICIT
        var attrsAsn1 = asn1.create(asn1.Class.CONTEXT_SPECIFIC, 1, true, []);
        for(var i = 0; i < obj.unauthenticatedAttributes.length; ++i){
            var attr = obj.unauthenticatedAttributes[i];
            attrsAsn1.values.push(_attributeToAsn1(attr));
        }
        rval.value.push(attrsAsn1);
    }
    return rval;
}
/**
 * Map a set of SignerInfo ASN.1 objects to an array of signer objects.
 *
 * @param signerInfoAsn1s an array of ASN.1 SignerInfos (i.e. SET OF).
 *
 * @return an array of signers objects.
 */ function _signersFromAsn1(signerInfoAsn1s) {
    var ret = [];
    for(var i = 0; i < signerInfoAsn1s.length; ++i)ret.push(_signerFromAsn1(signerInfoAsn1s[i]));
    return ret;
}
/**
 * Map an array of signer objects to ASN.1 objects.
 *
 * @param signers an array of signer objects.
 *
 * @return an array of ASN.1 SignerInfos.
 */ function _signersToAsn1(signers) {
    var ret = [];
    for(var i = 0; i < signers.length; ++i)ret.push(_signerToAsn1(signers[i]));
    return ret;
}
/**
 * Convert an attribute object to an ASN.1 Attribute.
 *
 * @param attr the attribute object.
 *
 * @return the ASN.1 Attribute.
 */ function _attributeToAsn1(attr) {
    var value;
    // TODO: generalize to support more attributes
    if (attr.type === forge.pki.oids.contentType) value = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(attr.value).getBytes());
    else if (attr.type === forge.pki.oids.messageDigest) value = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, attr.value.bytes());
    else if (attr.type === forge.pki.oids.signingTime) {
        /* Note per RFC 2985: Dates between 1 January 1950 and 31 December 2049
      (inclusive) MUST be encoded as UTCTime. Any dates with year values
      before 1950 or after 2049 MUST be encoded as GeneralizedTime. [Further,]
      UTCTime values MUST be expressed in Greenwich Mean Time (Zulu) and MUST
      include seconds (i.e., times are YYMMDDHHMMSSZ), even where the
      number of seconds is zero.  Midnight (GMT) must be represented as
      "YYMMDD000000Z". */ // TODO: make these module-level constants
        var jan_1_1950 = new Date('1950-01-01T00:00:00Z');
        var jan_1_2050 = new Date('2050-01-01T00:00:00Z');
        var date = attr.value;
        if (typeof date === 'string') {
            // try to parse date
            var timestamp = Date.parse(date);
            if (!isNaN(timestamp)) date = new Date(timestamp);
            else if (date.length === 13) // YYMMDDHHMMSSZ (13 chars for UTCTime)
            date = asn1.utcTimeToDate(date);
            else // assume generalized time
            date = asn1.generalizedTimeToDate(date);
        }
        if (date >= jan_1_1950 && date < jan_1_2050) value = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.UTCTIME, false, asn1.dateToUtcTime(date));
        else value = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.GENERALIZEDTIME, false, asn1.dateToGeneralizedTime(date));
    }
    // TODO: expose as common API call
    // create a RelativeDistinguishedName set
    // each value in the set is an AttributeTypeAndValue first
    // containing the type (an OID) and second the value
    return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
        // AttributeType
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(attr.type).getBytes()),
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SET, true, [
            // AttributeValue
            value
        ])
    ]);
}
/**
 * Map messages encrypted content to ASN.1 objects.
 *
 * @param ec The encryptedContent object of the message.
 *
 * @return ASN.1 representation of the encryptedContent object (SEQUENCE).
 */ function _encryptedContentToAsn1(ec) {
    return [
        // ContentType, always Data for the moment
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(forge.pki.oids.data).getBytes()),
        // ContentEncryptionAlgorithmIdentifier
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
            // Algorithm
            asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(ec.algorithm).getBytes()),
            // Parameters (IV)
            asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, ec.parameter.getBytes())
        ]),
        // [0] EncryptedContent
        asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [
            asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, ec.content.getBytes())
        ])
    ];
}
/**
 * Reads the "common part" of an PKCS#7 content block (in ASN.1 format)
 *
 * This function reads the "common part" of the PKCS#7 content blocks
 * EncryptedData and EnvelopedData, i.e. version number and symmetrically
 * encrypted content block.
 *
 * The result of the ASN.1 validate and capture process is returned
 * to allow the caller to extract further data, e.g. the list of recipients
 * in case of a EnvelopedData object.
 *
 * @param msg the PKCS#7 object to read the data to.
 * @param obj the ASN.1 representation of the content block.
 * @param validator the ASN.1 structure validator object to use.
 *
 * @return the value map captured by validator object.
 */ function _fromAsn1(msg, obj, validator) {
    var capture = {
    };
    var errors = [];
    if (!asn1.validate(obj, validator, capture, errors)) {
        var error = new Error("Cannot read PKCS#7 message. ASN.1 object is not a supported PKCS#7 message.");
        error.errors = error;
        throw error;
    }
    // Check contentType, so far we only support (raw) Data.
    var contentType = asn1.derToOid(capture.contentType);
    if (contentType !== forge.pki.oids.data) throw new Error("Unsupported PKCS#7 message. Only wrapped ContentType Data supported.");
    if (capture.encryptedContent) {
        var content = '';
        if (forge.util.isArray(capture.encryptedContent)) for(var i = 0; i < capture.encryptedContent.length; ++i){
            if (capture.encryptedContent[i].type !== asn1.Type.OCTETSTRING) throw new Error("Malformed PKCS#7 message, expecting encrypted content constructed of only OCTET STRING objects.");
            content += capture.encryptedContent[i].value;
        }
        else content = capture.encryptedContent;
        msg.encryptedContent = {
            algorithm: asn1.derToOid(capture.encAlgorithm),
            parameter: forge.util.createBuffer(capture.encParameter.value),
            content: forge.util.createBuffer(content)
        };
    }
    if (capture.content) {
        var content = '';
        if (forge.util.isArray(capture.content)) for(var i = 0; i < capture.content.length; ++i){
            if (capture.content[i].type !== asn1.Type.OCTETSTRING) throw new Error("Malformed PKCS#7 message, expecting content constructed of only OCTET STRING objects.");
            content += capture.content[i].value;
        }
        else content = capture.content;
        msg.content = forge.util.createBuffer(content);
    }
    msg.version = capture.version.charCodeAt(0);
    msg.rawCapture = capture;
    return capture;
}
/**
 * Decrypt the symmetrically encrypted content block of the PKCS#7 message.
 *
 * Decryption is skipped in case the PKCS#7 message object already has a
 * (decrypted) content attribute.  The algorithm, key and cipher parameters
 * (probably the iv) are taken from the encryptedContent attribute of the
 * message object.
 *
 * @param The PKCS#7 message object.
 */ function _decryptContent(msg) {
    if (msg.encryptedContent.key === undefined) throw new Error('Symmetric key not available.');
    if (msg.content === undefined) {
        var ciph;
        switch(msg.encryptedContent.algorithm){
            case forge.pki.oids['aes128-CBC']:
            case forge.pki.oids['aes192-CBC']:
            case forge.pki.oids['aes256-CBC']:
                ciph = forge.aes.createDecryptionCipher(msg.encryptedContent.key);
                break;
            case forge.pki.oids['desCBC']:
            case forge.pki.oids['des-EDE3-CBC']:
                ciph = forge.des.createDecryptionCipher(msg.encryptedContent.key);
                break;
            default:
                throw new Error('Unsupported symmetric cipher, OID ' + msg.encryptedContent.algorithm);
        }
        ciph.start(msg.encryptedContent.parameter);
        ciph.update(msg.encryptedContent.content);
        if (!ciph.finish()) throw new Error('Symmetric decryption failed.');
        msg.content = ciph.output;
    }
}

},{"./forge":"7AnVp","./aes":"jgIby","./asn1":"fLyrX","./des":"6QyDg","./oids":"iymJu","./pem":"axmYn","./pkcs7asn1":"2Rpty","./random":"7GrCn","./util":"cHj6b","./x509":"hEiGM"}],"2Rpty":[function(require,module,exports) {
/**
 * Javascript implementation of ASN.1 validators for PKCS#7 v1.5.
 *
 * @author Dave Longley
 * @author Stefan Siegl
 *
 * Copyright (c) 2012-2015 Digital Bazaar, Inc.
 * Copyright (c) 2012 Stefan Siegl <stesie@brokenpipe.de>
 *
 * The ASN.1 representation of PKCS#7 is as follows
 * (see RFC #2315 for details, http://www.ietf.org/rfc/rfc2315.txt):
 *
 * A PKCS#7 message consists of a ContentInfo on root level, which may
 * contain any number of further ContentInfo nested into it.
 *
 * ContentInfo ::= SEQUENCE {
 *   contentType                ContentType,
 *   content               [0]  EXPLICIT ANY DEFINED BY contentType OPTIONAL
 * }
 *
 * ContentType ::= OBJECT IDENTIFIER
 *
 * EnvelopedData ::= SEQUENCE {
 *   version                    Version,
 *   recipientInfos             RecipientInfos,
 *   encryptedContentInfo       EncryptedContentInfo
 * }
 *
 * EncryptedData ::= SEQUENCE {
 *   version                    Version,
 *   encryptedContentInfo       EncryptedContentInfo
 * }
 *
 * id-signedData OBJECT IDENTIFIER ::= { iso(1) member-body(2)
 *   us(840) rsadsi(113549) pkcs(1) pkcs7(7) 2 }
 *
 * SignedData ::= SEQUENCE {
 *   version           INTEGER,
 *   digestAlgorithms  DigestAlgorithmIdentifiers,
 *   contentInfo       ContentInfo,
 *   certificates      [0] IMPLICIT Certificates OPTIONAL,
 *   crls              [1] IMPLICIT CertificateRevocationLists OPTIONAL,
 *   signerInfos       SignerInfos
 * }
 *
 * SignerInfos ::= SET OF SignerInfo
 *
 * SignerInfo ::= SEQUENCE {
 *   version                    Version,
 *   issuerAndSerialNumber      IssuerAndSerialNumber,
 *   digestAlgorithm            DigestAlgorithmIdentifier,
 *   authenticatedAttributes    [0] IMPLICIT Attributes OPTIONAL,
 *   digestEncryptionAlgorithm  DigestEncryptionAlgorithmIdentifier,
 *   encryptedDigest            EncryptedDigest,
 *   unauthenticatedAttributes  [1] IMPLICIT Attributes OPTIONAL
 * }
 *
 * EncryptedDigest ::= OCTET STRING
 *
 * Attributes ::= SET OF Attribute
 *
 * Attribute ::= SEQUENCE {
 *   attrType    OBJECT IDENTIFIER,
 *   attrValues  SET OF AttributeValue
 * }
 *
 * AttributeValue ::= ANY
 *
 * Version ::= INTEGER
 *
 * RecipientInfos ::= SET OF RecipientInfo
 *
 * EncryptedContentInfo ::= SEQUENCE {
 *   contentType                 ContentType,
 *   contentEncryptionAlgorithm  ContentEncryptionAlgorithmIdentifier,
 *   encryptedContent       [0]  IMPLICIT EncryptedContent OPTIONAL
 * }
 *
 * ContentEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
 *
 * The AlgorithmIdentifier contains an Object Identifier (OID) and parameters
 * for the algorithm, if any. In the case of AES and DES3, there is only one,
 * the IV.
 *
 * AlgorithmIdentifer ::= SEQUENCE {
 *    algorithm OBJECT IDENTIFIER,
 *    parameters ANY DEFINED BY algorithm OPTIONAL
 * }
 *
 * EncryptedContent ::= OCTET STRING
 *
 * RecipientInfo ::= SEQUENCE {
 *   version                     Version,
 *   issuerAndSerialNumber       IssuerAndSerialNumber,
 *   keyEncryptionAlgorithm      KeyEncryptionAlgorithmIdentifier,
 *   encryptedKey                EncryptedKey
 * }
 *
 * IssuerAndSerialNumber ::= SEQUENCE {
 *   issuer                      Name,
 *   serialNumber                CertificateSerialNumber
 * }
 *
 * CertificateSerialNumber ::= INTEGER
 *
 * KeyEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
 *
 * EncryptedKey ::= OCTET STRING
 */ var forge = require('./forge');
require('./asn1');
require('./util');
// shortcut for ASN.1 API
var asn1 = forge.asn1;
// shortcut for PKCS#7 API
var p7v = module.exports = forge.pkcs7asn1 = forge.pkcs7asn1 || {
};
forge.pkcs7 = forge.pkcs7 || {
};
forge.pkcs7.asn1 = p7v;
var contentInfoValidator = {
    name: 'ContentInfo',
    tagClass: asn1.Class.UNIVERSAL,
    type: asn1.Type.SEQUENCE,
    constructed: true,
    value: [
        {
            name: 'ContentInfo.ContentType',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.OID,
            constructed: false,
            capture: 'contentType'
        },
        {
            name: 'ContentInfo.content',
            tagClass: asn1.Class.CONTEXT_SPECIFIC,
            type: 0,
            constructed: true,
            optional: true,
            captureAsn1: 'content'
        }
    ]
};
p7v.contentInfoValidator = contentInfoValidator;
var encryptedContentInfoValidator = {
    name: 'EncryptedContentInfo',
    tagClass: asn1.Class.UNIVERSAL,
    type: asn1.Type.SEQUENCE,
    constructed: true,
    value: [
        {
            name: 'EncryptedContentInfo.contentType',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.OID,
            constructed: false,
            capture: 'contentType'
        },
        {
            name: 'EncryptedContentInfo.contentEncryptionAlgorithm',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.SEQUENCE,
            constructed: true,
            value: [
                {
                    name: 'EncryptedContentInfo.contentEncryptionAlgorithm.algorithm',
                    tagClass: asn1.Class.UNIVERSAL,
                    type: asn1.Type.OID,
                    constructed: false,
                    capture: 'encAlgorithm'
                },
                {
                    name: 'EncryptedContentInfo.contentEncryptionAlgorithm.parameter',
                    tagClass: asn1.Class.UNIVERSAL,
                    captureAsn1: 'encParameter'
                }
            ]
        },
        {
            name: 'EncryptedContentInfo.encryptedContent',
            tagClass: asn1.Class.CONTEXT_SPECIFIC,
            type: 0,
            /* The PKCS#7 structure output by OpenSSL somewhat differs from what
     * other implementations do generate.
     *
     * OpenSSL generates a structure like this:
     * SEQUENCE {
     *    ...
     *    [0]
     *       26 DA 67 D2 17 9C 45 3C B1 2A A8 59 2F 29 33 38
     *       C3 C3 DF 86 71 74 7A 19 9F 40 D0 29 BE 85 90 45
     *       ...
     * }
     *
     * Whereas other implementations (and this PKCS#7 module) generate:
     * SEQUENCE {
     *    ...
     *    [0] {
     *       OCTET STRING
     *          26 DA 67 D2 17 9C 45 3C B1 2A A8 59 2F 29 33 38
     *          C3 C3 DF 86 71 74 7A 19 9F 40 D0 29 BE 85 90 45
     *          ...
     *    }
     * }
     *
     * In order to support both, we just capture the context specific
     * field here.  The OCTET STRING bit is removed below.
     */ capture: 'encryptedContent',
            captureAsn1: 'encryptedContentAsn1'
        }
    ]
};
p7v.envelopedDataValidator = {
    name: 'EnvelopedData',
    tagClass: asn1.Class.UNIVERSAL,
    type: asn1.Type.SEQUENCE,
    constructed: true,
    value: [
        {
            name: 'EnvelopedData.Version',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.INTEGER,
            constructed: false,
            capture: 'version'
        },
        {
            name: 'EnvelopedData.RecipientInfos',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.SET,
            constructed: true,
            captureAsn1: 'recipientInfos'
        }
    ].concat(encryptedContentInfoValidator)
};
p7v.encryptedDataValidator = {
    name: 'EncryptedData',
    tagClass: asn1.Class.UNIVERSAL,
    type: asn1.Type.SEQUENCE,
    constructed: true,
    value: [
        {
            name: 'EncryptedData.Version',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.INTEGER,
            constructed: false,
            capture: 'version'
        }
    ].concat(encryptedContentInfoValidator)
};
var signerValidator = {
    name: 'SignerInfo',
    tagClass: asn1.Class.UNIVERSAL,
    type: asn1.Type.SEQUENCE,
    constructed: true,
    value: [
        {
            name: 'SignerInfo.version',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.INTEGER,
            constructed: false
        },
        {
            name: 'SignerInfo.issuerAndSerialNumber',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.SEQUENCE,
            constructed: true,
            value: [
                {
                    name: 'SignerInfo.issuerAndSerialNumber.issuer',
                    tagClass: asn1.Class.UNIVERSAL,
                    type: asn1.Type.SEQUENCE,
                    constructed: true,
                    captureAsn1: 'issuer'
                },
                {
                    name: 'SignerInfo.issuerAndSerialNumber.serialNumber',
                    tagClass: asn1.Class.UNIVERSAL,
                    type: asn1.Type.INTEGER,
                    constructed: false,
                    capture: 'serial'
                }
            ]
        },
        {
            name: 'SignerInfo.digestAlgorithm',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.SEQUENCE,
            constructed: true,
            value: [
                {
                    name: 'SignerInfo.digestAlgorithm.algorithm',
                    tagClass: asn1.Class.UNIVERSAL,
                    type: asn1.Type.OID,
                    constructed: false,
                    capture: 'digestAlgorithm'
                },
                {
                    name: 'SignerInfo.digestAlgorithm.parameter',
                    tagClass: asn1.Class.UNIVERSAL,
                    constructed: false,
                    captureAsn1: 'digestParameter',
                    optional: true
                }
            ]
        },
        {
            name: 'SignerInfo.authenticatedAttributes',
            tagClass: asn1.Class.CONTEXT_SPECIFIC,
            type: 0,
            constructed: true,
            optional: true,
            capture: 'authenticatedAttributes'
        },
        {
            name: 'SignerInfo.digestEncryptionAlgorithm',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.SEQUENCE,
            constructed: true,
            capture: 'signatureAlgorithm'
        },
        {
            name: 'SignerInfo.encryptedDigest',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.OCTETSTRING,
            constructed: false,
            capture: 'signature'
        },
        {
            name: 'SignerInfo.unauthenticatedAttributes',
            tagClass: asn1.Class.CONTEXT_SPECIFIC,
            type: 1,
            constructed: true,
            optional: true,
            capture: 'unauthenticatedAttributes'
        }
    ]
};
p7v.signedDataValidator = {
    name: 'SignedData',
    tagClass: asn1.Class.UNIVERSAL,
    type: asn1.Type.SEQUENCE,
    constructed: true,
    value: [
        {
            name: 'SignedData.Version',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.INTEGER,
            constructed: false,
            capture: 'version'
        },
        {
            name: 'SignedData.DigestAlgorithms',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.SET,
            constructed: true,
            captureAsn1: 'digestAlgorithms'
        },
        contentInfoValidator,
        {
            name: 'SignedData.Certificates',
            tagClass: asn1.Class.CONTEXT_SPECIFIC,
            type: 0,
            optional: true,
            captureAsn1: 'certificates'
        },
        {
            name: 'SignedData.CertificateRevocationLists',
            tagClass: asn1.Class.CONTEXT_SPECIFIC,
            type: 1,
            optional: true,
            captureAsn1: 'crls'
        },
        {
            name: 'SignedData.SignerInfos',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.SET,
            capture: 'signerInfos',
            optional: true,
            value: [
                signerValidator
            ]
        }
    ]
};
p7v.recipientInfoValidator = {
    name: 'RecipientInfo',
    tagClass: asn1.Class.UNIVERSAL,
    type: asn1.Type.SEQUENCE,
    constructed: true,
    value: [
        {
            name: 'RecipientInfo.version',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.INTEGER,
            constructed: false,
            capture: 'version'
        },
        {
            name: 'RecipientInfo.issuerAndSerial',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.SEQUENCE,
            constructed: true,
            value: [
                {
                    name: 'RecipientInfo.issuerAndSerial.issuer',
                    tagClass: asn1.Class.UNIVERSAL,
                    type: asn1.Type.SEQUENCE,
                    constructed: true,
                    captureAsn1: 'issuer'
                },
                {
                    name: 'RecipientInfo.issuerAndSerial.serialNumber',
                    tagClass: asn1.Class.UNIVERSAL,
                    type: asn1.Type.INTEGER,
                    constructed: false,
                    capture: 'serial'
                }
            ]
        },
        {
            name: 'RecipientInfo.keyEncryptionAlgorithm',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.SEQUENCE,
            constructed: true,
            value: [
                {
                    name: 'RecipientInfo.keyEncryptionAlgorithm.algorithm',
                    tagClass: asn1.Class.UNIVERSAL,
                    type: asn1.Type.OID,
                    constructed: false,
                    capture: 'encAlgorithm'
                },
                {
                    name: 'RecipientInfo.keyEncryptionAlgorithm.parameter',
                    tagClass: asn1.Class.UNIVERSAL,
                    constructed: false,
                    captureAsn1: 'encParameter'
                }
            ]
        },
        {
            name: 'RecipientInfo.encryptedKey',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.OCTETSTRING,
            constructed: false,
            capture: 'encKey'
        }
    ]
};

},{"./forge":"7AnVp","./asn1":"fLyrX","./util":"cHj6b"}],"hEiGM":[function(require,module,exports) {
/**
 * Javascript implementation of X.509 and related components (such as
 * Certification Signing Requests) of a Public Key Infrastructure.
 *
 * @author Dave Longley
 *
 * Copyright (c) 2010-2014 Digital Bazaar, Inc.
 *
 * The ASN.1 representation of an X.509v3 certificate is as follows
 * (see RFC 2459):
 *
 * Certificate ::= SEQUENCE {
 *   tbsCertificate       TBSCertificate,
 *   signatureAlgorithm   AlgorithmIdentifier,
 *   signatureValue       BIT STRING
 * }
 *
 * TBSCertificate ::= SEQUENCE {
 *   version         [0]  EXPLICIT Version DEFAULT v1,
 *   serialNumber         CertificateSerialNumber,
 *   signature            AlgorithmIdentifier,
 *   issuer               Name,
 *   validity             Validity,
 *   subject              Name,
 *   subjectPublicKeyInfo SubjectPublicKeyInfo,
 *   issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
 *                        -- If present, version shall be v2 or v3
 *   subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
 *                        -- If present, version shall be v2 or v3
 *   extensions      [3]  EXPLICIT Extensions OPTIONAL
 *                        -- If present, version shall be v3
 * }
 *
 * Version ::= INTEGER  { v1(0), v2(1), v3(2) }
 *
 * CertificateSerialNumber ::= INTEGER
 *
 * Name ::= CHOICE {
 *   // only one possible choice for now
 *   RDNSequence
 * }
 *
 * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
 *
 * RelativeDistinguishedName ::= SET OF AttributeTypeAndValue
 *
 * AttributeTypeAndValue ::= SEQUENCE {
 *   type     AttributeType,
 *   value    AttributeValue
 * }
 * AttributeType ::= OBJECT IDENTIFIER
 * AttributeValue ::= ANY DEFINED BY AttributeType
 *
 * Validity ::= SEQUENCE {
 *   notBefore      Time,
 *   notAfter       Time
 * }
 *
 * Time ::= CHOICE {
 *   utcTime        UTCTime,
 *   generalTime    GeneralizedTime
 * }
 *
 * UniqueIdentifier ::= BIT STRING
 *
 * SubjectPublicKeyInfo ::= SEQUENCE {
 *   algorithm            AlgorithmIdentifier,
 *   subjectPublicKey     BIT STRING
 * }
 *
 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
 *
 * Extension ::= SEQUENCE {
 *   extnID      OBJECT IDENTIFIER,
 *   critical    BOOLEAN DEFAULT FALSE,
 *   extnValue   OCTET STRING
 * }
 *
 * The only key algorithm currently supported for PKI is RSA.
 *
 * RSASSA-PSS signatures are described in RFC 3447 and RFC 4055.
 *
 * PKCS#10 v1.7 describes certificate signing requests:
 *
 * CertificationRequestInfo:
 *
 * CertificationRequestInfo ::= SEQUENCE {
 *   version       INTEGER { v1(0) } (v1,...),
 *   subject       Name,
 *   subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }},
 *   attributes    [0] Attributes{{ CRIAttributes }}
 * }
 *
 * Attributes { ATTRIBUTE:IOSet } ::= SET OF Attribute{{ IOSet }}
 *
 * CRIAttributes  ATTRIBUTE  ::= {
 *   ... -- add any locally defined attributes here -- }
 *
 * Attribute { ATTRIBUTE:IOSet } ::= SEQUENCE {
 *   type   ATTRIBUTE.&id({IOSet}),
 *   values SET SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{@type})
 * }
 *
 * CertificationRequest ::= SEQUENCE {
 *   certificationRequestInfo CertificationRequestInfo,
 *   signatureAlgorithm AlgorithmIdentifier{{ SignatureAlgorithms }},
 *   signature          BIT STRING
 * }
 */ var forge = require('./forge');
require('./aes');
require('./asn1');
require('./des');
require('./md');
require('./mgf');
require('./oids');
require('./pem');
require('./pss');
require('./rsa');
require('./util');
// shortcut for asn.1 API
var asn1 = forge.asn1;
/* Public Key Infrastructure (PKI) implementation. */ var pki = module.exports = forge.pki = forge.pki || {
};
var oids = pki.oids;
// short name OID mappings
var _shortNames = {
};
_shortNames['CN'] = oids['commonName'];
_shortNames['commonName'] = 'CN';
_shortNames['C'] = oids['countryName'];
_shortNames['countryName'] = 'C';
_shortNames['L'] = oids['localityName'];
_shortNames['localityName'] = 'L';
_shortNames['ST'] = oids['stateOrProvinceName'];
_shortNames['stateOrProvinceName'] = 'ST';
_shortNames['O'] = oids['organizationName'];
_shortNames['organizationName'] = 'O';
_shortNames['OU'] = oids['organizationalUnitName'];
_shortNames['organizationalUnitName'] = 'OU';
_shortNames['E'] = oids['emailAddress'];
_shortNames['emailAddress'] = 'E';
// validator for an SubjectPublicKeyInfo structure
// Note: Currently only works with an RSA public key
var publicKeyValidator = forge.pki.rsa.publicKeyValidator;
// validator for an X.509v3 certificate
var x509CertificateValidator = {
    name: 'Certificate',
    tagClass: asn1.Class.UNIVERSAL,
    type: asn1.Type.SEQUENCE,
    constructed: true,
    value: [
        {
            name: 'Certificate.TBSCertificate',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.SEQUENCE,
            constructed: true,
            captureAsn1: 'tbsCertificate',
            value: [
                {
                    name: 'Certificate.TBSCertificate.version',
                    tagClass: asn1.Class.CONTEXT_SPECIFIC,
                    type: 0,
                    constructed: true,
                    optional: true,
                    value: [
                        {
                            name: 'Certificate.TBSCertificate.version.integer',
                            tagClass: asn1.Class.UNIVERSAL,
                            type: asn1.Type.INTEGER,
                            constructed: false,
                            capture: 'certVersion'
                        }
                    ]
                },
                {
                    name: 'Certificate.TBSCertificate.serialNumber',
                    tagClass: asn1.Class.UNIVERSAL,
                    type: asn1.Type.INTEGER,
                    constructed: false,
                    capture: 'certSerialNumber'
                },
                {
                    name: 'Certificate.TBSCertificate.signature',
                    tagClass: asn1.Class.UNIVERSAL,
                    type: asn1.Type.SEQUENCE,
                    constructed: true,
                    value: [
                        {
                            name: 'Certificate.TBSCertificate.signature.algorithm',
                            tagClass: asn1.Class.UNIVERSAL,
                            type: asn1.Type.OID,
                            constructed: false,
                            capture: 'certinfoSignatureOid'
                        },
                        {
                            name: 'Certificate.TBSCertificate.signature.parameters',
                            tagClass: asn1.Class.UNIVERSAL,
                            optional: true,
                            captureAsn1: 'certinfoSignatureParams'
                        }
                    ]
                },
                {
                    name: 'Certificate.TBSCertificate.issuer',
                    tagClass: asn1.Class.UNIVERSAL,
                    type: asn1.Type.SEQUENCE,
                    constructed: true,
                    captureAsn1: 'certIssuer'
                },
                {
                    name: 'Certificate.TBSCertificate.validity',
                    tagClass: asn1.Class.UNIVERSAL,
                    type: asn1.Type.SEQUENCE,
                    constructed: true,
                    // Note: UTC and generalized times may both appear so the capture
                    // names are based on their detected order, the names used below
                    // are only for the common case, which validity time really means
                    // "notBefore" and which means "notAfter" will be determined by order
                    value: [
                        {
                            // notBefore (Time) (UTC time case)
                            name: 'Certificate.TBSCertificate.validity.notBefore (utc)',
                            tagClass: asn1.Class.UNIVERSAL,
                            type: asn1.Type.UTCTIME,
                            constructed: false,
                            optional: true,
                            capture: 'certValidity1UTCTime'
                        },
                        {
                            // notBefore (Time) (generalized time case)
                            name: 'Certificate.TBSCertificate.validity.notBefore (generalized)',
                            tagClass: asn1.Class.UNIVERSAL,
                            type: asn1.Type.GENERALIZEDTIME,
                            constructed: false,
                            optional: true,
                            capture: 'certValidity2GeneralizedTime'
                        },
                        {
                            // notAfter (Time) (only UTC time is supported)
                            name: 'Certificate.TBSCertificate.validity.notAfter (utc)',
                            tagClass: asn1.Class.UNIVERSAL,
                            type: asn1.Type.UTCTIME,
                            constructed: false,
                            optional: true,
                            capture: 'certValidity3UTCTime'
                        },
                        {
                            // notAfter (Time) (only UTC time is supported)
                            name: 'Certificate.TBSCertificate.validity.notAfter (generalized)',
                            tagClass: asn1.Class.UNIVERSAL,
                            type: asn1.Type.GENERALIZEDTIME,
                            constructed: false,
                            optional: true,
                            capture: 'certValidity4GeneralizedTime'
                        }
                    ]
                },
                {
                    // Name (subject) (RDNSequence)
                    name: 'Certificate.TBSCertificate.subject',
                    tagClass: asn1.Class.UNIVERSAL,
                    type: asn1.Type.SEQUENCE,
                    constructed: true,
                    captureAsn1: 'certSubject'
                },
                // SubjectPublicKeyInfo
                publicKeyValidator,
                {
                    // issuerUniqueID (optional)
                    name: 'Certificate.TBSCertificate.issuerUniqueID',
                    tagClass: asn1.Class.CONTEXT_SPECIFIC,
                    type: 1,
                    constructed: true,
                    optional: true,
                    value: [
                        {
                            name: 'Certificate.TBSCertificate.issuerUniqueID.id',
                            tagClass: asn1.Class.UNIVERSAL,
                            type: asn1.Type.BITSTRING,
                            constructed: false,
                            // TODO: support arbitrary bit length ids
                            captureBitStringValue: 'certIssuerUniqueId'
                        }
                    ]
                },
                {
                    // subjectUniqueID (optional)
                    name: 'Certificate.TBSCertificate.subjectUniqueID',
                    tagClass: asn1.Class.CONTEXT_SPECIFIC,
                    type: 2,
                    constructed: true,
                    optional: true,
                    value: [
                        {
                            name: 'Certificate.TBSCertificate.subjectUniqueID.id',
                            tagClass: asn1.Class.UNIVERSAL,
                            type: asn1.Type.BITSTRING,
                            constructed: false,
                            // TODO: support arbitrary bit length ids
                            captureBitStringValue: 'certSubjectUniqueId'
                        }
                    ]
                },
                {
                    // Extensions (optional)
                    name: 'Certificate.TBSCertificate.extensions',
                    tagClass: asn1.Class.CONTEXT_SPECIFIC,
                    type: 3,
                    constructed: true,
                    captureAsn1: 'certExtensions',
                    optional: true
                }
            ]
        },
        {
            // AlgorithmIdentifier (signature algorithm)
            name: 'Certificate.signatureAlgorithm',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.SEQUENCE,
            constructed: true,
            value: [
                {
                    // algorithm
                    name: 'Certificate.signatureAlgorithm.algorithm',
                    tagClass: asn1.Class.UNIVERSAL,
                    type: asn1.Type.OID,
                    constructed: false,
                    capture: 'certSignatureOid'
                },
                {
                    name: 'Certificate.TBSCertificate.signature.parameters',
                    tagClass: asn1.Class.UNIVERSAL,
                    optional: true,
                    captureAsn1: 'certSignatureParams'
                }
            ]
        },
        {
            // SignatureValue
            name: 'Certificate.signatureValue',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.BITSTRING,
            constructed: false,
            captureBitStringValue: 'certSignature'
        }
    ]
};
var rsassaPssParameterValidator = {
    name: 'rsapss',
    tagClass: asn1.Class.UNIVERSAL,
    type: asn1.Type.SEQUENCE,
    constructed: true,
    value: [
        {
            name: 'rsapss.hashAlgorithm',
            tagClass: asn1.Class.CONTEXT_SPECIFIC,
            type: 0,
            constructed: true,
            value: [
                {
                    name: 'rsapss.hashAlgorithm.AlgorithmIdentifier',
                    tagClass: asn1.Class.UNIVERSAL,
                    type: asn1.Class.SEQUENCE,
                    constructed: true,
                    optional: true,
                    value: [
                        {
                            name: 'rsapss.hashAlgorithm.AlgorithmIdentifier.algorithm',
                            tagClass: asn1.Class.UNIVERSAL,
                            type: asn1.Type.OID,
                            constructed: false,
                            capture: 'hashOid'
                        }
                    ]
                }
            ]
        },
        {
            name: 'rsapss.maskGenAlgorithm',
            tagClass: asn1.Class.CONTEXT_SPECIFIC,
            type: 1,
            constructed: true,
            value: [
                {
                    name: 'rsapss.maskGenAlgorithm.AlgorithmIdentifier',
                    tagClass: asn1.Class.UNIVERSAL,
                    type: asn1.Class.SEQUENCE,
                    constructed: true,
                    optional: true,
                    value: [
                        {
                            name: 'rsapss.maskGenAlgorithm.AlgorithmIdentifier.algorithm',
                            tagClass: asn1.Class.UNIVERSAL,
                            type: asn1.Type.OID,
                            constructed: false,
                            capture: 'maskGenOid'
                        },
                        {
                            name: 'rsapss.maskGenAlgorithm.AlgorithmIdentifier.params',
                            tagClass: asn1.Class.UNIVERSAL,
                            type: asn1.Type.SEQUENCE,
                            constructed: true,
                            value: [
                                {
                                    name: 'rsapss.maskGenAlgorithm.AlgorithmIdentifier.params.algorithm',
                                    tagClass: asn1.Class.UNIVERSAL,
                                    type: asn1.Type.OID,
                                    constructed: false,
                                    capture: 'maskGenHashOid'
                                }
                            ]
                        }
                    ]
                }
            ]
        },
        {
            name: 'rsapss.saltLength',
            tagClass: asn1.Class.CONTEXT_SPECIFIC,
            type: 2,
            optional: true,
            value: [
                {
                    name: 'rsapss.saltLength.saltLength',
                    tagClass: asn1.Class.UNIVERSAL,
                    type: asn1.Class.INTEGER,
                    constructed: false,
                    capture: 'saltLength'
                }
            ]
        },
        {
            name: 'rsapss.trailerField',
            tagClass: asn1.Class.CONTEXT_SPECIFIC,
            type: 3,
            optional: true,
            value: [
                {
                    name: 'rsapss.trailer.trailer',
                    tagClass: asn1.Class.UNIVERSAL,
                    type: asn1.Class.INTEGER,
                    constructed: false,
                    capture: 'trailer'
                }
            ]
        }
    ]
};
// validator for a CertificationRequestInfo structure
var certificationRequestInfoValidator = {
    name: 'CertificationRequestInfo',
    tagClass: asn1.Class.UNIVERSAL,
    type: asn1.Type.SEQUENCE,
    constructed: true,
    captureAsn1: 'certificationRequestInfo',
    value: [
        {
            name: 'CertificationRequestInfo.integer',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.INTEGER,
            constructed: false,
            capture: 'certificationRequestInfoVersion'
        },
        {
            // Name (subject) (RDNSequence)
            name: 'CertificationRequestInfo.subject',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.SEQUENCE,
            constructed: true,
            captureAsn1: 'certificationRequestInfoSubject'
        },
        // SubjectPublicKeyInfo
        publicKeyValidator,
        {
            name: 'CertificationRequestInfo.attributes',
            tagClass: asn1.Class.CONTEXT_SPECIFIC,
            type: 0,
            constructed: true,
            optional: true,
            capture: 'certificationRequestInfoAttributes',
            value: [
                {
                    name: 'CertificationRequestInfo.attributes',
                    tagClass: asn1.Class.UNIVERSAL,
                    type: asn1.Type.SEQUENCE,
                    constructed: true,
                    value: [
                        {
                            name: 'CertificationRequestInfo.attributes.type',
                            tagClass: asn1.Class.UNIVERSAL,
                            type: asn1.Type.OID,
                            constructed: false
                        },
                        {
                            name: 'CertificationRequestInfo.attributes.value',
                            tagClass: asn1.Class.UNIVERSAL,
                            type: asn1.Type.SET,
                            constructed: true
                        }
                    ]
                }
            ]
        }
    ]
};
// validator for a CertificationRequest structure
var certificationRequestValidator = {
    name: 'CertificationRequest',
    tagClass: asn1.Class.UNIVERSAL,
    type: asn1.Type.SEQUENCE,
    constructed: true,
    captureAsn1: 'csr',
    value: [
        certificationRequestInfoValidator,
        {
            // AlgorithmIdentifier (signature algorithm)
            name: 'CertificationRequest.signatureAlgorithm',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.SEQUENCE,
            constructed: true,
            value: [
                {
                    // algorithm
                    name: 'CertificationRequest.signatureAlgorithm.algorithm',
                    tagClass: asn1.Class.UNIVERSAL,
                    type: asn1.Type.OID,
                    constructed: false,
                    capture: 'csrSignatureOid'
                },
                {
                    name: 'CertificationRequest.signatureAlgorithm.parameters',
                    tagClass: asn1.Class.UNIVERSAL,
                    optional: true,
                    captureAsn1: 'csrSignatureParams'
                }
            ]
        },
        {
            // signature
            name: 'CertificationRequest.signature',
            tagClass: asn1.Class.UNIVERSAL,
            type: asn1.Type.BITSTRING,
            constructed: false,
            captureBitStringValue: 'csrSignature'
        }
    ]
};
/**
 * Converts an RDNSequence of ASN.1 DER-encoded RelativeDistinguishedName
 * sets into an array with objects that have type and value properties.
 *
 * @param rdn the RDNSequence to convert.
 * @param md a message digest to append type and value to if provided.
 */ pki.RDNAttributesAsArray = function(rdn, md) {
    var rval = [];
    // each value in 'rdn' in is a SET of RelativeDistinguishedName
    var set, attr, obj;
    for(var si = 0; si < rdn.value.length; ++si){
        // get the RelativeDistinguishedName set
        set = rdn.value[si];
        // each value in the SET is an AttributeTypeAndValue sequence
        // containing first a type (an OID) and second a value (defined by
        // the OID)
        for(var i = 0; i < set.value.length; ++i){
            obj = {
            };
            attr = set.value[i];
            obj.type = asn1.derToOid(attr.value[0].value);
            obj.value = attr.value[1].value;
            obj.valueTagClass = attr.value[1].type;
            // if the OID is known, get its name and short name
            if (obj.type in oids) {
                obj.name = oids[obj.type];
                if (obj.name in _shortNames) obj.shortName = _shortNames[obj.name];
            }
            if (md) {
                md.update(obj.type);
                md.update(obj.value);
            }
            rval.push(obj);
        }
    }
    return rval;
};
/**
 * Converts ASN.1 CRIAttributes into an array with objects that have type and
 * value properties.
 *
 * @param attributes the CRIAttributes to convert.
 */ pki.CRIAttributesAsArray = function(attributes) {
    var rval = [];
    // each value in 'attributes' in is a SEQUENCE with an OID and a SET
    for(var si = 0; si < attributes.length; ++si){
        // get the attribute sequence
        var seq = attributes[si];
        // each value in the SEQUENCE containing first a type (an OID) and
        // second a set of values (defined by the OID)
        var type = asn1.derToOid(seq.value[0].value);
        var values = seq.value[1].value;
        for(var vi = 0; vi < values.length; ++vi){
            var obj = {
            };
            obj.type = type;
            obj.value = values[vi].value;
            obj.valueTagClass = values[vi].type;
            // if the OID is known, get its name and short name
            if (obj.type in oids) {
                obj.name = oids[obj.type];
                if (obj.name in _shortNames) obj.shortName = _shortNames[obj.name];
            }
            // parse extensions
            if (obj.type === oids.extensionRequest) {
                obj.extensions = [];
                for(var ei = 0; ei < obj.value.length; ++ei)obj.extensions.push(pki.certificateExtensionFromAsn1(obj.value[ei]));
            }
            rval.push(obj);
        }
    }
    return rval;
};
/**
 * Gets an issuer or subject attribute from its name, type, or short name.
 *
 * @param obj the issuer or subject object.
 * @param options a short name string or an object with:
 *          shortName the short name for the attribute.
 *          name the name for the attribute.
 *          type the type for the attribute.
 *
 * @return the attribute.
 */ function _getAttribute(obj, options) {
    if (typeof options === 'string') options = {
        shortName: options
    };
    var rval = null;
    var attr;
    for(var i = 0; rval === null && i < obj.attributes.length; ++i){
        attr = obj.attributes[i];
        if (options.type && options.type === attr.type) rval = attr;
        else if (options.name && options.name === attr.name) rval = attr;
        else if (options.shortName && options.shortName === attr.shortName) rval = attr;
    }
    return rval;
}
/**
 * Converts signature parameters from ASN.1 structure.
 *
 * Currently only RSASSA-PSS supported.  The PKCS#1 v1.5 signature scheme had
 * no parameters.
 *
 * RSASSA-PSS-params  ::=  SEQUENCE  {
 *   hashAlgorithm      [0] HashAlgorithm DEFAULT
 *                             sha1Identifier,
 *   maskGenAlgorithm   [1] MaskGenAlgorithm DEFAULT
 *                             mgf1SHA1Identifier,
 *   saltLength         [2] INTEGER DEFAULT 20,
 *   trailerField       [3] INTEGER DEFAULT 1
 * }
 *
 * HashAlgorithm  ::=  AlgorithmIdentifier
 *
 * MaskGenAlgorithm  ::=  AlgorithmIdentifier
 *
 * AlgorithmIdentifer ::= SEQUENCE {
 *   algorithm OBJECT IDENTIFIER,
 *   parameters ANY DEFINED BY algorithm OPTIONAL
 * }
 *
 * @param oid The OID specifying the signature algorithm
 * @param obj The ASN.1 structure holding the parameters
 * @param fillDefaults Whether to use return default values where omitted
 * @return signature parameter object
 */ var _readSignatureParameters = function(oid, obj, fillDefaults) {
    var params = {
    };
    if (oid !== oids['RSASSA-PSS']) return params;
    if (fillDefaults) params = {
        hash: {
            algorithmOid: oids['sha1']
        },
        mgf: {
            algorithmOid: oids['mgf1'],
            hash: {
                algorithmOid: oids['sha1']
            }
        },
        saltLength: 20
    };
    var capture = {
    };
    var errors = [];
    if (!asn1.validate(obj, rsassaPssParameterValidator, capture, errors)) {
        var error = new Error('Cannot read RSASSA-PSS parameter block.');
        error.errors = errors;
        throw error;
    }
    if (capture.hashOid !== undefined) {
        params.hash = params.hash || {
        };
        params.hash.algorithmOid = asn1.derToOid(capture.hashOid);
    }
    if (capture.maskGenOid !== undefined) {
        params.mgf = params.mgf || {
        };
        params.mgf.algorithmOid = asn1.derToOid(capture.maskGenOid);
        params.mgf.hash = params.mgf.hash || {
        };
        params.mgf.hash.algorithmOid = asn1.derToOid(capture.maskGenHashOid);
    }
    if (capture.saltLength !== undefined) params.saltLength = capture.saltLength.charCodeAt(0);
    return params;
};
/**
 * Converts an X.509 certificate from PEM format.
 *
 * Note: If the certificate is to be verified then compute hash should
 * be set to true. This will scan the TBSCertificate part of the ASN.1
 * object while it is converted so it doesn't need to be converted back
 * to ASN.1-DER-encoding later.
 *
 * @param pem the PEM-formatted certificate.
 * @param computeHash true to compute the hash for verification.
 * @param strict true to be strict when checking ASN.1 value lengths, false to
 *          allow truncated values (default: true).
 *
 * @return the certificate.
 */ pki.certificateFromPem = function(pem, computeHash, strict) {
    var msg = forge.pem.decode(pem)[0];
    if (msg.type !== 'CERTIFICATE' && msg.type !== 'X509 CERTIFICATE' && msg.type !== 'TRUSTED CERTIFICATE') {
        var error = new Error("Could not convert certificate from PEM; PEM header type is not \"CERTIFICATE\", \"X509 CERTIFICATE\", or \"TRUSTED CERTIFICATE\".");
        error.headerType = msg.type;
        throw error;
    }
    if (msg.procType && msg.procType.type === 'ENCRYPTED') throw new Error('Could not convert certificate from PEM; PEM is encrypted.');
    // convert DER to ASN.1 object
    var obj = asn1.fromDer(msg.body, strict);
    return pki.certificateFromAsn1(obj, computeHash);
};
/**
 * Converts an X.509 certificate to PEM format.
 *
 * @param cert the certificate.
 * @param maxline the maximum characters per line, defaults to 64.
 *
 * @return the PEM-formatted certificate.
 */ pki.certificateToPem = function(cert, maxline) {
    // convert to ASN.1, then DER, then PEM-encode
    var msg = {
        type: 'CERTIFICATE',
        body: asn1.toDer(pki.certificateToAsn1(cert)).getBytes()
    };
    return forge.pem.encode(msg, {
        maxline: maxline
    });
};
/**
 * Converts an RSA public key from PEM format.
 *
 * @param pem the PEM-formatted public key.
 *
 * @return the public key.
 */ pki.publicKeyFromPem = function(pem) {
    var msg = forge.pem.decode(pem)[0];
    if (msg.type !== 'PUBLIC KEY' && msg.type !== 'RSA PUBLIC KEY') {
        var error = new Error("Could not convert public key from PEM; PEM header type is not \"PUBLIC KEY\" or \"RSA PUBLIC KEY\".");
        error.headerType = msg.type;
        throw error;
    }
    if (msg.procType && msg.procType.type === 'ENCRYPTED') throw new Error('Could not convert public key from PEM; PEM is encrypted.');
    // convert DER to ASN.1 object
    var obj = asn1.fromDer(msg.body);
    return pki.publicKeyFromAsn1(obj);
};
/**
 * Converts an RSA public key to PEM format (using a SubjectPublicKeyInfo).
 *
 * @param key the public key.
 * @param maxline the maximum characters per line, defaults to 64.
 *
 * @return the PEM-formatted public key.
 */ pki.publicKeyToPem = function(key, maxline) {
    // convert to ASN.1, then DER, then PEM-encode
    var msg = {
        type: 'PUBLIC KEY',
        body: asn1.toDer(pki.publicKeyToAsn1(key)).getBytes()
    };
    return forge.pem.encode(msg, {
        maxline: maxline
    });
};
/**
 * Converts an RSA public key to PEM format (using an RSAPublicKey).
 *
 * @param key the public key.
 * @param maxline the maximum characters per line, defaults to 64.
 *
 * @return the PEM-formatted public key.
 */ pki.publicKeyToRSAPublicKeyPem = function(key, maxline) {
    // convert to ASN.1, then DER, then PEM-encode
    var msg = {
        type: 'RSA PUBLIC KEY',
        body: asn1.toDer(pki.publicKeyToRSAPublicKey(key)).getBytes()
    };
    return forge.pem.encode(msg, {
        maxline: maxline
    });
};
/**
 * Gets a fingerprint for the given public key.
 *
 * @param options the options to use.
 *          [md] the message digest object to use (defaults to forge.md.sha1).
 *          [type] the type of fingerprint, such as 'RSAPublicKey',
 *            'SubjectPublicKeyInfo' (defaults to 'RSAPublicKey').
 *          [encoding] an alternative output encoding, such as 'hex'
 *            (defaults to none, outputs a byte buffer).
 *          [delimiter] the delimiter to use between bytes for 'hex' encoded
 *            output, eg: ':' (defaults to none).
 *
 * @return the fingerprint as a byte buffer or other encoding based on options.
 */ pki.getPublicKeyFingerprint = function(key, options) {
    options = options || {
    };
    var md = options.md || forge.md.sha1.create();
    var type = options.type || 'RSAPublicKey';
    var bytes;
    switch(type){
        case 'RSAPublicKey':
            bytes = asn1.toDer(pki.publicKeyToRSAPublicKey(key)).getBytes();
            break;
        case 'SubjectPublicKeyInfo':
            bytes = asn1.toDer(pki.publicKeyToAsn1(key)).getBytes();
            break;
        default:
            throw new Error('Unknown fingerprint type "' + options.type + '".');
    }
    // hash public key bytes
    md.start();
    md.update(bytes);
    var digest = md.digest();
    if (options.encoding === 'hex') {
        var hex = digest.toHex();
        if (options.delimiter) return hex.match(/.{2}/g).join(options.delimiter);
        return hex;
    } else if (options.encoding === 'binary') return digest.getBytes();
    else if (options.encoding) throw new Error('Unknown encoding "' + options.encoding + '".');
    return digest;
};
/**
 * Converts a PKCS#10 certification request (CSR) from PEM format.
 *
 * Note: If the certification request is to be verified then compute hash
 * should be set to true. This will scan the CertificationRequestInfo part of
 * the ASN.1 object while it is converted so it doesn't need to be converted
 * back to ASN.1-DER-encoding later.
 *
 * @param pem the PEM-formatted certificate.
 * @param computeHash true to compute the hash for verification.
 * @param strict true to be strict when checking ASN.1 value lengths, false to
 *          allow truncated values (default: true).
 *
 * @return the certification request (CSR).
 */ pki.certificationRequestFromPem = function(pem, computeHash, strict) {
    var msg = forge.pem.decode(pem)[0];
    if (msg.type !== 'CERTIFICATE REQUEST') {
        var error = new Error("Could not convert certification request from PEM; PEM header type is not \"CERTIFICATE REQUEST\".");
        error.headerType = msg.type;
        throw error;
    }
    if (msg.procType && msg.procType.type === 'ENCRYPTED') throw new Error("Could not convert certification request from PEM; PEM is encrypted.");
    // convert DER to ASN.1 object
    var obj = asn1.fromDer(msg.body, strict);
    return pki.certificationRequestFromAsn1(obj, computeHash);
};
/**
 * Converts a PKCS#10 certification request (CSR) to PEM format.
 *
 * @param csr the certification request.
 * @param maxline the maximum characters per line, defaults to 64.
 *
 * @return the PEM-formatted certification request.
 */ pki.certificationRequestToPem = function(csr, maxline) {
    // convert to ASN.1, then DER, then PEM-encode
    var msg = {
        type: 'CERTIFICATE REQUEST',
        body: asn1.toDer(pki.certificationRequestToAsn1(csr)).getBytes()
    };
    return forge.pem.encode(msg, {
        maxline: maxline
    });
};
/**
 * Creates an empty X.509v3 RSA certificate.
 *
 * @return the certificate.
 */ pki.createCertificate = function() {
    var cert = {
    };
    cert.version = 2;
    cert.serialNumber = '00';
    cert.signatureOid = null;
    cert.signature = null;
    cert.siginfo = {
    };
    cert.siginfo.algorithmOid = null;
    cert.validity = {
    };
    cert.validity.notBefore = new Date();
    cert.validity.notAfter = new Date();
    cert.issuer = {
    };
    cert.issuer.getField = function(sn) {
        return _getAttribute(cert.issuer, sn);
    };
    cert.issuer.addField = function(attr) {
        _fillMissingFields([
            attr
        ]);
        cert.issuer.attributes.push(attr);
    };
    cert.issuer.attributes = [];
    cert.issuer.hash = null;
    cert.subject = {
    };
    cert.subject.getField = function(sn) {
        return _getAttribute(cert.subject, sn);
    };
    cert.subject.addField = function(attr) {
        _fillMissingFields([
            attr
        ]);
        cert.subject.attributes.push(attr);
    };
    cert.subject.attributes = [];
    cert.subject.hash = null;
    cert.extensions = [];
    cert.publicKey = null;
    cert.md = null;
    /**
   * Sets the subject of this certificate.
   *
   * @param attrs the array of subject attributes to use.
   * @param uniqueId an optional a unique ID to use.
   */ cert.setSubject = function(attrs, uniqueId) {
        // set new attributes, clear hash
        _fillMissingFields(attrs);
        cert.subject.attributes = attrs;
        delete cert.subject.uniqueId;
        if (uniqueId) // TODO: support arbitrary bit length ids
        cert.subject.uniqueId = uniqueId;
        cert.subject.hash = null;
    };
    /**
   * Sets the issuer of this certificate.
   *
   * @param attrs the array of issuer attributes to use.
   * @param uniqueId an optional a unique ID to use.
   */ cert.setIssuer = function(attrs, uniqueId) {
        // set new attributes, clear hash
        _fillMissingFields(attrs);
        cert.issuer.attributes = attrs;
        delete cert.issuer.uniqueId;
        if (uniqueId) // TODO: support arbitrary bit length ids
        cert.issuer.uniqueId = uniqueId;
        cert.issuer.hash = null;
    };
    /**
   * Sets the extensions of this certificate.
   *
   * @param exts the array of extensions to use.
   */ cert.setExtensions = function(exts) {
        for(var i = 0; i < exts.length; ++i)_fillMissingExtensionFields(exts[i], {
            cert: cert
        });
        // set new extensions
        cert.extensions = exts;
    };
    /**
   * Gets an extension by its name or id.
   *
   * @param options the name to use or an object with:
   *          name the name to use.
   *          id the id to use.
   *
   * @return the extension or null if not found.
   */ cert.getExtension = function(options) {
        if (typeof options === 'string') options = {
            name: options
        };
        var rval = null;
        var ext;
        for(var i = 0; rval === null && i < cert.extensions.length; ++i){
            ext = cert.extensions[i];
            if (options.id && ext.id === options.id) rval = ext;
            else if (options.name && ext.name === options.name) rval = ext;
        }
        return rval;
    };
    /**
   * Signs this certificate using the given private key.
   *
   * @param key the private key to sign with.
   * @param md the message digest object to use (defaults to forge.md.sha1).
   */ cert.sign = function(key, md) {
        // TODO: get signature OID from private key
        cert.md = md || forge.md.sha1.create();
        var algorithmOid = oids[cert.md.algorithm + 'WithRSAEncryption'];
        if (!algorithmOid) {
            var error = new Error("Could not compute certificate digest. Unknown message digest algorithm OID.");
            error.algorithm = cert.md.algorithm;
            throw error;
        }
        cert.signatureOid = cert.siginfo.algorithmOid = algorithmOid;
        // get TBSCertificate, convert to DER
        cert.tbsCertificate = pki.getTBSCertificate(cert);
        var bytes = asn1.toDer(cert.tbsCertificate);
        // digest and sign
        cert.md.update(bytes.getBytes());
        cert.signature = key.sign(cert.md);
    };
    /**
   * Attempts verify the signature on the passed certificate using this
   * certificate's public key.
   *
   * @param child the certificate to verify.
   *
   * @return true if verified, false if not.
   */ cert.verify = function(child) {
        var rval = false;
        if (!cert.issued(child)) {
            var issuer = child.issuer;
            var subject = cert.subject;
            var error = new Error("The parent certificate did not issue the given child certificate; the child certificate's issuer does not match the parent's subject.");
            error.expectedIssuer = issuer.attributes;
            error.actualIssuer = subject.attributes;
            throw error;
        }
        var md = child.md;
        if (md === null) {
            // check signature OID for supported signature types
            if (child.signatureOid in oids) {
                var oid = oids[child.signatureOid];
                switch(oid){
                    case 'sha1WithRSAEncryption':
                        md = forge.md.sha1.create();
                        break;
                    case 'md5WithRSAEncryption':
                        md = forge.md.md5.create();
                        break;
                    case 'sha256WithRSAEncryption':
                        md = forge.md.sha256.create();
                        break;
                    case 'sha384WithRSAEncryption':
                        md = forge.md.sha384.create();
                        break;
                    case 'sha512WithRSAEncryption':
                        md = forge.md.sha512.create();
                        break;
                    case 'RSASSA-PSS':
                        md = forge.md.sha256.create();
                        break;
                }
            }
            if (md === null) {
                var error = new Error("Could not compute certificate digest. Unknown signature OID.");
                error.signatureOid = child.signatureOid;
                throw error;
            }
            // produce DER formatted TBSCertificate and digest it
            var tbsCertificate = child.tbsCertificate || pki.getTBSCertificate(child);
            var bytes = asn1.toDer(tbsCertificate);
            md.update(bytes.getBytes());
        }
        if (md !== null) {
            var scheme;
            switch(child.signatureOid){
                case oids.sha1WithRSAEncryption:
                    scheme = undefined; /* use PKCS#1 v1.5 padding scheme */ 
                    break;
                case oids['RSASSA-PSS']:
                    var hash, mgf;
                    /* initialize mgf */ hash = oids[child.signatureParameters.mgf.hash.algorithmOid];
                    if (hash === undefined || forge.md[hash] === undefined) {
                        var error = new Error('Unsupported MGF hash function.');
                        error.oid = child.signatureParameters.mgf.hash.algorithmOid;
                        error.name = hash;
                        throw error;
                    }
                    mgf = oids[child.signatureParameters.mgf.algorithmOid];
                    if (mgf === undefined || forge.mgf[mgf] === undefined) {
                        var error = new Error('Unsupported MGF function.');
                        error.oid = child.signatureParameters.mgf.algorithmOid;
                        error.name = mgf;
                        throw error;
                    }
                    mgf = forge.mgf[mgf].create(forge.md[hash].create());
                    /* initialize hash function */ hash = oids[child.signatureParameters.hash.algorithmOid];
                    if (hash === undefined || forge.md[hash] === undefined) throw {
                        message: 'Unsupported RSASSA-PSS hash function.',
                        oid: child.signatureParameters.hash.algorithmOid,
                        name: hash
                    };
                    scheme = forge.pss.create(forge.md[hash].create(), mgf, child.signatureParameters.saltLength);
                    break;
            }
            // verify signature on cert using public key
            rval = cert.publicKey.verify(md.digest().getBytes(), child.signature, scheme);
        }
        return rval;
    };
    /**
   * Returns true if this certificate's issuer matches the passed
   * certificate's subject. Note that no signature check is performed.
   *
   * @param parent the certificate to check.
   *
   * @return true if this certificate's issuer matches the passed certificate's
   *         subject.
   */ cert.isIssuer = function(parent) {
        var rval = false;
        var i = cert.issuer;
        var s = parent.subject;
        // compare hashes if present
        if (i.hash && s.hash) rval = i.hash === s.hash;
        else if (i.attributes.length === s.attributes.length) {
            // all attributes are the same so issuer matches subject
            rval = true;
            var iattr, sattr;
            for(var n = 0; rval && n < i.attributes.length; ++n){
                iattr = i.attributes[n];
                sattr = s.attributes[n];
                if (iattr.type !== sattr.type || iattr.value !== sattr.value) // attribute mismatch
                rval = false;
            }
        }
        return rval;
    };
    /**
   * Returns true if this certificate's subject matches the issuer of the
   * given certificate). Note that not signature check is performed.
   *
   * @param child the certificate to check.
   *
   * @return true if this certificate's subject matches the passed
   *         certificate's issuer.
   */ cert.issued = function(child) {
        return child.isIssuer(cert);
    };
    /**
   * Generates the subjectKeyIdentifier for this certificate as byte buffer.
   *
   * @return the subjectKeyIdentifier for this certificate as byte buffer.
   */ cert.generateSubjectKeyIdentifier = function() {
        /* See: 4.2.1.2 section of the the RFC3280, keyIdentifier is either:

      (1) The keyIdentifier is composed of the 160-bit SHA-1 hash of the
        value of the BIT STRING subjectPublicKey (excluding the tag,
        length, and number of unused bits).

      (2) The keyIdentifier is composed of a four bit type field with
        the value 0100 followed by the least significant 60 bits of the
        SHA-1 hash of the value of the BIT STRING subjectPublicKey
        (excluding the tag, length, and number of unused bit string bits).
    */ // skipping the tag, length, and number of unused bits is the same
        // as just using the RSAPublicKey (for RSA keys, which are the
        // only ones supported)
        return pki.getPublicKeyFingerprint(cert.publicKey, {
            type: 'RSAPublicKey'
        });
    };
    /**
   * Verifies the subjectKeyIdentifier extension value for this certificate
   * against its public key. If no extension is found, false will be
   * returned.
   *
   * @return true if verified, false if not.
   */ cert.verifySubjectKeyIdentifier = function() {
        var oid = oids['subjectKeyIdentifier'];
        for(var i = 0; i < cert.extensions.length; ++i){
            var ext = cert.extensions[i];
            if (ext.id === oid) {
                var ski = cert.generateSubjectKeyIdentifier().getBytes();
                return forge.util.hexToBytes(ext.subjectKeyIdentifier) === ski;
            }
        }
        return false;
    };
    return cert;
};
/**
 * Converts an X.509v3 RSA certificate from an ASN.1 object.
 *
 * Note: If the certificate is to be verified then compute hash should
 * be set to true. There is currently no implementation for converting
 * a certificate back to ASN.1 so the TBSCertificate part of the ASN.1
 * object needs to be scanned before the cert object is created.
 *
 * @param obj the asn1 representation of an X.509v3 RSA certificate.
 * @param computeHash true to compute the hash for verification.
 *
 * @return the certificate.
 */ pki.certificateFromAsn1 = function(obj, computeHash) {
    // validate certificate and capture data
    var capture = {
    };
    var errors = [];
    if (!asn1.validate(obj, x509CertificateValidator, capture, errors)) {
        var error = new Error("Cannot read X.509 certificate. ASN.1 object is not an X509v3 Certificate.");
        error.errors = errors;
        throw error;
    }
    // get oid
    var oid = asn1.derToOid(capture.publicKeyOid);
    if (oid !== pki.oids.rsaEncryption) throw new Error('Cannot read public key. OID is not RSA.');
    // create certificate
    var cert = pki.createCertificate();
    cert.version = capture.certVersion ? capture.certVersion.charCodeAt(0) : 0;
    var serial = forge.util.createBuffer(capture.certSerialNumber);
    cert.serialNumber = serial.toHex();
    cert.signatureOid = forge.asn1.derToOid(capture.certSignatureOid);
    cert.signatureParameters = _readSignatureParameters(cert.signatureOid, capture.certSignatureParams, true);
    cert.siginfo.algorithmOid = forge.asn1.derToOid(capture.certinfoSignatureOid);
    cert.siginfo.parameters = _readSignatureParameters(cert.siginfo.algorithmOid, capture.certinfoSignatureParams, false);
    cert.signature = capture.certSignature;
    var validity = [];
    if (capture.certValidity1UTCTime !== undefined) validity.push(asn1.utcTimeToDate(capture.certValidity1UTCTime));
    if (capture.certValidity2GeneralizedTime !== undefined) validity.push(asn1.generalizedTimeToDate(capture.certValidity2GeneralizedTime));
    if (capture.certValidity3UTCTime !== undefined) validity.push(asn1.utcTimeToDate(capture.certValidity3UTCTime));
    if (capture.certValidity4GeneralizedTime !== undefined) validity.push(asn1.generalizedTimeToDate(capture.certValidity4GeneralizedTime));
    if (validity.length > 2) throw new Error("Cannot read notBefore/notAfter validity times; more than two times were provided in the certificate.");
    if (validity.length < 2) throw new Error("Cannot read notBefore/notAfter validity times; they were not provided as either UTCTime or GeneralizedTime.");
    cert.validity.notBefore = validity[0];
    cert.validity.notAfter = validity[1];
    // keep TBSCertificate to preserve signature when exporting
    cert.tbsCertificate = capture.tbsCertificate;
    if (computeHash) {
        // check signature OID for supported signature types
        cert.md = null;
        if (cert.signatureOid in oids) {
            var oid = oids[cert.signatureOid];
            switch(oid){
                case 'sha1WithRSAEncryption':
                    cert.md = forge.md.sha1.create();
                    break;
                case 'md5WithRSAEncryption':
                    cert.md = forge.md.md5.create();
                    break;
                case 'sha256WithRSAEncryption':
                    cert.md = forge.md.sha256.create();
                    break;
                case 'sha384WithRSAEncryption':
                    cert.md = forge.md.sha384.create();
                    break;
                case 'sha512WithRSAEncryption':
                    cert.md = forge.md.sha512.create();
                    break;
                case 'RSASSA-PSS':
                    cert.md = forge.md.sha256.create();
                    break;
            }
        }
        if (cert.md === null) {
            var error = new Error("Could not compute certificate digest. Unknown signature OID.");
            error.signatureOid = cert.signatureOid;
            throw error;
        }
        // produce DER formatted TBSCertificate and digest it
        var bytes = asn1.toDer(cert.tbsCertificate);
        cert.md.update(bytes.getBytes());
    }
    // handle issuer, build issuer message digest
    var imd = forge.md.sha1.create();
    cert.issuer.getField = function(sn) {
        return _getAttribute(cert.issuer, sn);
    };
    cert.issuer.addField = function(attr) {
        _fillMissingFields([
            attr
        ]);
        cert.issuer.attributes.push(attr);
    };
    cert.issuer.attributes = pki.RDNAttributesAsArray(capture.certIssuer, imd);
    if (capture.certIssuerUniqueId) cert.issuer.uniqueId = capture.certIssuerUniqueId;
    cert.issuer.hash = imd.digest().toHex();
    // handle subject, build subject message digest
    var smd = forge.md.sha1.create();
    cert.subject.getField = function(sn) {
        return _getAttribute(cert.subject, sn);
    };
    cert.subject.addField = function(attr) {
        _fillMissingFields([
            attr
        ]);
        cert.subject.attributes.push(attr);
    };
    cert.subject.attributes = pki.RDNAttributesAsArray(capture.certSubject, smd);
    if (capture.certSubjectUniqueId) cert.subject.uniqueId = capture.certSubjectUniqueId;
    cert.subject.hash = smd.digest().toHex();
    // handle extensions
    if (capture.certExtensions) cert.extensions = pki.certificateExtensionsFromAsn1(capture.certExtensions);
    else cert.extensions = [];
    // convert RSA public key from ASN.1
    cert.publicKey = pki.publicKeyFromAsn1(capture.subjectPublicKeyInfo);
    return cert;
};
/**
 * Converts an ASN.1 extensions object (with extension sequences as its
 * values) into an array of extension objects with types and values.
 *
 * Supported extensions:
 *
 * id-ce-keyUsage OBJECT IDENTIFIER ::=  { id-ce 15 }
 * KeyUsage ::= BIT STRING {
 *   digitalSignature        (0),
 *   nonRepudiation          (1),
 *   keyEncipherment         (2),
 *   dataEncipherment        (3),
 *   keyAgreement            (4),
 *   keyCertSign             (5),
 *   cRLSign                 (6),
 *   encipherOnly            (7),
 *   decipherOnly            (8)
 * }
 *
 * id-ce-basicConstraints OBJECT IDENTIFIER ::=  { id-ce 19 }
 * BasicConstraints ::= SEQUENCE {
 *   cA                      BOOLEAN DEFAULT FALSE,
 *   pathLenConstraint       INTEGER (0..MAX) OPTIONAL
 * }
 *
 * subjectAltName EXTENSION ::= {
 *   SYNTAX GeneralNames
 *   IDENTIFIED BY id-ce-subjectAltName
 * }
 *
 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
 *
 * GeneralName ::= CHOICE {
 *   otherName      [0] INSTANCE OF OTHER-NAME,
 *   rfc822Name     [1] IA5String,
 *   dNSName        [2] IA5String,
 *   x400Address    [3] ORAddress,
 *   directoryName  [4] Name,
 *   ediPartyName   [5] EDIPartyName,
 *   uniformResourceIdentifier [6] IA5String,
 *   IPAddress      [7] OCTET STRING,
 *   registeredID   [8] OBJECT IDENTIFIER
 * }
 *
 * OTHER-NAME ::= TYPE-IDENTIFIER
 *
 * EDIPartyName ::= SEQUENCE {
 *   nameAssigner [0] DirectoryString {ub-name} OPTIONAL,
 *   partyName    [1] DirectoryString {ub-name}
 * }
 *
 * @param exts the extensions ASN.1 with extension sequences to parse.
 *
 * @return the array.
 */ pki.certificateExtensionsFromAsn1 = function(exts) {
    var rval = [];
    for(var i = 0; i < exts.value.length; ++i){
        // get extension sequence
        var extseq = exts.value[i];
        for(var ei = 0; ei < extseq.value.length; ++ei)rval.push(pki.certificateExtensionFromAsn1(extseq.value[ei]));
    }
    return rval;
};
/**
 * Parses a single certificate extension from ASN.1.
 *
 * @param ext the extension in ASN.1 format.
 *
 * @return the parsed extension as an object.
 */ pki.certificateExtensionFromAsn1 = function(ext) {
    // an extension has:
    // [0] extnID      OBJECT IDENTIFIER
    // [1] critical    BOOLEAN DEFAULT FALSE
    // [2] extnValue   OCTET STRING
    var e = {
    };
    e.id = asn1.derToOid(ext.value[0].value);
    e.critical = false;
    if (ext.value[1].type === asn1.Type.BOOLEAN) {
        e.critical = ext.value[1].value.charCodeAt(0) !== 0;
        e.value = ext.value[2].value;
    } else e.value = ext.value[1].value;
    // if the oid is known, get its name
    if (e.id in oids) {
        e.name = oids[e.id];
        // handle key usage
        if (e.name === 'keyUsage') {
            // get value as BIT STRING
            var ev = asn1.fromDer(e.value);
            var b2 = 0;
            var b3 = 0;
            if (ev.value.length > 1) {
                // skip first byte, just indicates unused bits which
                // will be padded with 0s anyway
                // get bytes with flag bits
                b2 = ev.value.charCodeAt(1);
                b3 = ev.value.length > 2 ? ev.value.charCodeAt(2) : 0;
            }
            // set flags
            e.digitalSignature = (b2 & 128) === 128;
            e.nonRepudiation = (b2 & 64) === 64;
            e.keyEncipherment = (b2 & 32) === 32;
            e.dataEncipherment = (b2 & 16) === 16;
            e.keyAgreement = (b2 & 8) === 8;
            e.keyCertSign = (b2 & 4) === 4;
            e.cRLSign = (b2 & 2) === 2;
            e.encipherOnly = (b2 & 1) === 1;
            e.decipherOnly = (b3 & 128) === 128;
        } else if (e.name === 'basicConstraints') {
            // handle basic constraints
            // get value as SEQUENCE
            var ev = asn1.fromDer(e.value);
            // get cA BOOLEAN flag (defaults to false)
            if (ev.value.length > 0 && ev.value[0].type === asn1.Type.BOOLEAN) e.cA = ev.value[0].value.charCodeAt(0) !== 0;
            else e.cA = false;
            // get path length constraint
            var value = null;
            if (ev.value.length > 0 && ev.value[0].type === asn1.Type.INTEGER) value = ev.value[0].value;
            else if (ev.value.length > 1) value = ev.value[1].value;
            if (value !== null) e.pathLenConstraint = asn1.derToInteger(value);
        } else if (e.name === 'extKeyUsage') {
            // handle extKeyUsage
            // value is a SEQUENCE of OIDs
            var ev = asn1.fromDer(e.value);
            for(var vi = 0; vi < ev.value.length; ++vi){
                var oid = asn1.derToOid(ev.value[vi].value);
                if (oid in oids) e[oids[oid]] = true;
                else e[oid] = true;
            }
        } else if (e.name === 'nsCertType') {
            // handle nsCertType
            // get value as BIT STRING
            var ev = asn1.fromDer(e.value);
            var b2 = 0;
            if (ev.value.length > 1) // skip first byte, just indicates unused bits which
            // will be padded with 0s anyway
            // get bytes with flag bits
            b2 = ev.value.charCodeAt(1);
            // set flags
            e.client = (b2 & 128) === 128;
            e.server = (b2 & 64) === 64;
            e.email = (b2 & 32) === 32;
            e.objsign = (b2 & 16) === 16;
            e.reserved = (b2 & 8) === 8;
            e.sslCA = (b2 & 4) === 4;
            e.emailCA = (b2 & 2) === 2;
            e.objCA = (b2 & 1) === 1;
        } else if (e.name === 'subjectAltName' || e.name === 'issuerAltName') {
            // handle subjectAltName/issuerAltName
            e.altNames = [];
            // ev is a SYNTAX SEQUENCE
            var gn;
            var ev = asn1.fromDer(e.value);
            for(var n = 0; n < ev.value.length; ++n){
                // get GeneralName
                gn = ev.value[n];
                var altName = {
                    type: gn.type,
                    value: gn.value
                };
                e.altNames.push(altName);
                // Note: Support for types 1,2,6,7,8
                switch(gn.type){
                    // rfc822Name
                    case 1:
                    // dNSName
                    case 2:
                    // uniformResourceIdentifier (URI)
                    case 6:
                        break;
                    // IPAddress
                    case 7:
                        // convert to IPv4/IPv6 string representation
                        altName.ip = forge.util.bytesToIP(gn.value);
                        break;
                    // registeredID
                    case 8:
                        altName.oid = asn1.derToOid(gn.value);
                        break;
                    default:
                }
            }
        } else if (e.name === 'subjectKeyIdentifier') {
            // value is an OCTETSTRING w/the hash of the key-type specific
            // public key structure (eg: RSAPublicKey)
            var ev = asn1.fromDer(e.value);
            e.subjectKeyIdentifier = forge.util.bytesToHex(ev.value);
        }
    }
    return e;
};
/**
 * Converts a PKCS#10 certification request (CSR) from an ASN.1 object.
 *
 * Note: If the certification request is to be verified then compute hash
 * should be set to true. There is currently no implementation for converting
 * a certificate back to ASN.1 so the CertificationRequestInfo part of the
 * ASN.1 object needs to be scanned before the csr object is created.
 *
 * @param obj the asn1 representation of a PKCS#10 certification request (CSR).
 * @param computeHash true to compute the hash for verification.
 *
 * @return the certification request (CSR).
 */ pki.certificationRequestFromAsn1 = function(obj, computeHash) {
    // validate certification request and capture data
    var capture = {
    };
    var errors = [];
    if (!asn1.validate(obj, certificationRequestValidator, capture, errors)) {
        var error = new Error("Cannot read PKCS#10 certificate request. ASN.1 object is not a PKCS#10 CertificationRequest.");
        error.errors = errors;
        throw error;
    }
    // get oid
    var oid = asn1.derToOid(capture.publicKeyOid);
    if (oid !== pki.oids.rsaEncryption) throw new Error('Cannot read public key. OID is not RSA.');
    // create certification request
    var csr = pki.createCertificationRequest();
    csr.version = capture.csrVersion ? capture.csrVersion.charCodeAt(0) : 0;
    csr.signatureOid = forge.asn1.derToOid(capture.csrSignatureOid);
    csr.signatureParameters = _readSignatureParameters(csr.signatureOid, capture.csrSignatureParams, true);
    csr.siginfo.algorithmOid = forge.asn1.derToOid(capture.csrSignatureOid);
    csr.siginfo.parameters = _readSignatureParameters(csr.siginfo.algorithmOid, capture.csrSignatureParams, false);
    csr.signature = capture.csrSignature;
    // keep CertificationRequestInfo to preserve signature when exporting
    csr.certificationRequestInfo = capture.certificationRequestInfo;
    if (computeHash) {
        // check signature OID for supported signature types
        csr.md = null;
        if (csr.signatureOid in oids) {
            var oid = oids[csr.signatureOid];
            switch(oid){
                case 'sha1WithRSAEncryption':
                    csr.md = forge.md.sha1.create();
                    break;
                case 'md5WithRSAEncryption':
                    csr.md = forge.md.md5.create();
                    break;
                case 'sha256WithRSAEncryption':
                    csr.md = forge.md.sha256.create();
                    break;
                case 'sha384WithRSAEncryption':
                    csr.md = forge.md.sha384.create();
                    break;
                case 'sha512WithRSAEncryption':
                    csr.md = forge.md.sha512.create();
                    break;
                case 'RSASSA-PSS':
                    csr.md = forge.md.sha256.create();
                    break;
            }
        }
        if (csr.md === null) {
            var error = new Error("Could not compute certification request digest. Unknown signature OID.");
            error.signatureOid = csr.signatureOid;
            throw error;
        }
        // produce DER formatted CertificationRequestInfo and digest it
        var bytes = asn1.toDer(csr.certificationRequestInfo);
        csr.md.update(bytes.getBytes());
    }
    // handle subject, build subject message digest
    var smd = forge.md.sha1.create();
    csr.subject.getField = function(sn) {
        return _getAttribute(csr.subject, sn);
    };
    csr.subject.addField = function(attr) {
        _fillMissingFields([
            attr
        ]);
        csr.subject.attributes.push(attr);
    };
    csr.subject.attributes = pki.RDNAttributesAsArray(capture.certificationRequestInfoSubject, smd);
    csr.subject.hash = smd.digest().toHex();
    // convert RSA public key from ASN.1
    csr.publicKey = pki.publicKeyFromAsn1(capture.subjectPublicKeyInfo);
    // convert attributes from ASN.1
    csr.getAttribute = function(sn) {
        return _getAttribute(csr, sn);
    };
    csr.addAttribute = function(attr) {
        _fillMissingFields([
            attr
        ]);
        csr.attributes.push(attr);
    };
    csr.attributes = pki.CRIAttributesAsArray(capture.certificationRequestInfoAttributes || []);
    return csr;
};
/**
 * Creates an empty certification request (a CSR or certificate signing
 * request). Once created, its public key and attributes can be set and then
 * it can be signed.
 *
 * @return the empty certification request.
 */ pki.createCertificationRequest = function() {
    var csr = {
    };
    csr.version = 0;
    csr.signatureOid = null;
    csr.signature = null;
    csr.siginfo = {
    };
    csr.siginfo.algorithmOid = null;
    csr.subject = {
    };
    csr.subject.getField = function(sn) {
        return _getAttribute(csr.subject, sn);
    };
    csr.subject.addField = function(attr) {
        _fillMissingFields([
            attr
        ]);
        csr.subject.attributes.push(attr);
    };
    csr.subject.attributes = [];
    csr.subject.hash = null;
    csr.publicKey = null;
    csr.attributes = [];
    csr.getAttribute = function(sn) {
        return _getAttribute(csr, sn);
    };
    csr.addAttribute = function(attr) {
        _fillMissingFields([
            attr
        ]);
        csr.attributes.push(attr);
    };
    csr.md = null;
    /**
   * Sets the subject of this certification request.
   *
   * @param attrs the array of subject attributes to use.
   */ csr.setSubject = function(attrs) {
        // set new attributes
        _fillMissingFields(attrs);
        csr.subject.attributes = attrs;
        csr.subject.hash = null;
    };
    /**
   * Sets the attributes of this certification request.
   *
   * @param attrs the array of attributes to use.
   */ csr.setAttributes = function(attrs) {
        // set new attributes
        _fillMissingFields(attrs);
        csr.attributes = attrs;
    };
    /**
   * Signs this certification request using the given private key.
   *
   * @param key the private key to sign with.
   * @param md the message digest object to use (defaults to forge.md.sha1).
   */ csr.sign = function(key, md) {
        // TODO: get signature OID from private key
        csr.md = md || forge.md.sha1.create();
        var algorithmOid = oids[csr.md.algorithm + 'WithRSAEncryption'];
        if (!algorithmOid) {
            var error = new Error("Could not compute certification request digest. Unknown message digest algorithm OID.");
            error.algorithm = csr.md.algorithm;
            throw error;
        }
        csr.signatureOid = csr.siginfo.algorithmOid = algorithmOid;
        // get CertificationRequestInfo, convert to DER
        csr.certificationRequestInfo = pki.getCertificationRequestInfo(csr);
        var bytes = asn1.toDer(csr.certificationRequestInfo);
        // digest and sign
        csr.md.update(bytes.getBytes());
        csr.signature = key.sign(csr.md);
    };
    /**
   * Attempts verify the signature on the passed certification request using
   * its public key.
   *
   * A CSR that has been exported to a file in PEM format can be verified using
   * OpenSSL using this command:
   *
   * openssl req -in <the-csr-pem-file> -verify -noout -text
   *
   * @return true if verified, false if not.
   */ csr.verify = function() {
        var rval = false;
        var md = csr.md;
        if (md === null) {
            // check signature OID for supported signature types
            if (csr.signatureOid in oids) {
                // TODO: create DRY `OID to md` function
                var oid = oids[csr.signatureOid];
                switch(oid){
                    case 'sha1WithRSAEncryption':
                        md = forge.md.sha1.create();
                        break;
                    case 'md5WithRSAEncryption':
                        md = forge.md.md5.create();
                        break;
                    case 'sha256WithRSAEncryption':
                        md = forge.md.sha256.create();
                        break;
                    case 'sha384WithRSAEncryption':
                        md = forge.md.sha384.create();
                        break;
                    case 'sha512WithRSAEncryption':
                        md = forge.md.sha512.create();
                        break;
                    case 'RSASSA-PSS':
                        md = forge.md.sha256.create();
                        break;
                }
            }
            if (md === null) {
                var error = new Error("Could not compute certification request digest. Unknown signature OID.");
                error.signatureOid = csr.signatureOid;
                throw error;
            }
            // produce DER formatted CertificationRequestInfo and digest it
            var cri = csr.certificationRequestInfo || pki.getCertificationRequestInfo(csr);
            var bytes = asn1.toDer(cri);
            md.update(bytes.getBytes());
        }
        if (md !== null) {
            var scheme;
            switch(csr.signatureOid){
                case oids.sha1WithRSAEncryption:
                    break;
                case oids['RSASSA-PSS']:
                    var hash, mgf;
                    /* initialize mgf */ hash = oids[csr.signatureParameters.mgf.hash.algorithmOid];
                    if (hash === undefined || forge.md[hash] === undefined) {
                        var error = new Error('Unsupported MGF hash function.');
                        error.oid = csr.signatureParameters.mgf.hash.algorithmOid;
                        error.name = hash;
                        throw error;
                    }
                    mgf = oids[csr.signatureParameters.mgf.algorithmOid];
                    if (mgf === undefined || forge.mgf[mgf] === undefined) {
                        var error = new Error('Unsupported MGF function.');
                        error.oid = csr.signatureParameters.mgf.algorithmOid;
                        error.name = mgf;
                        throw error;
                    }
                    mgf = forge.mgf[mgf].create(forge.md[hash].create());
                    /* initialize hash function */ hash = oids[csr.signatureParameters.hash.algorithmOid];
                    if (hash === undefined || forge.md[hash] === undefined) {
                        var error = new Error('Unsupported RSASSA-PSS hash function.');
                        error.oid = csr.signatureParameters.hash.algorithmOid;
                        error.name = hash;
                        throw error;
                    }
                    scheme = forge.pss.create(forge.md[hash].create(), mgf, csr.signatureParameters.saltLength);
                    break;
            }
            // verify signature on csr using its public key
            rval = csr.publicKey.verify(md.digest().getBytes(), csr.signature, scheme);
        }
        return rval;
    };
    return csr;
};
/**
 * Converts an X.509 subject or issuer to an ASN.1 RDNSequence.
 *
 * @param obj the subject or issuer (distinguished name).
 *
 * @return the ASN.1 RDNSequence.
 */ function _dnToAsn1(obj) {
    // create an empty RDNSequence
    var rval = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []);
    // iterate over attributes
    var attr, set;
    var attrs = obj.attributes;
    for(var i = 0; i < attrs.length; ++i){
        attr = attrs[i];
        var value = attr.value;
        // reuse tag class for attribute value if available
        var valueTagClass = asn1.Type.PRINTABLESTRING;
        if ('valueTagClass' in attr) {
            valueTagClass = attr.valueTagClass;
            if (valueTagClass === asn1.Type.UTF8) value = forge.util.encodeUtf8(value);
        // FIXME: handle more encodings
        }
        // create a RelativeDistinguishedName set
        // each value in the set is an AttributeTypeAndValue first
        // containing the type (an OID) and second the value
        set = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SET, true, [
            asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
                // AttributeType
                asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(attr.type).getBytes()),
                // AttributeValue
                asn1.create(asn1.Class.UNIVERSAL, valueTagClass, false, value)
            ])
        ]);
        rval.value.push(set);
    }
    return rval;
}
/**
 * Gets all printable attributes (typically of an issuer or subject) in a
 * simplified JSON format for display.
 *
 * @param attrs the attributes.
 *
 * @return the JSON for display.
 */ function _getAttributesAsJson(attrs) {
    var rval = {
    };
    for(var i = 0; i < attrs.length; ++i){
        var attr = attrs[i];
        if (attr.shortName && (attr.valueTagClass === asn1.Type.UTF8 || attr.valueTagClass === asn1.Type.PRINTABLESTRING || attr.valueTagClass === asn1.Type.IA5STRING)) {
            var value = attr.value;
            if (attr.valueTagClass === asn1.Type.UTF8) value = forge.util.encodeUtf8(attr.value);
            if (!(attr.shortName in rval)) rval[attr.shortName] = value;
            else if (forge.util.isArray(rval[attr.shortName])) rval[attr.shortName].push(value);
            else rval[attr.shortName] = [
                rval[attr.shortName],
                value
            ];
        }
    }
    return rval;
}
/**
 * Fills in missing fields in attributes.
 *
 * @param attrs the attributes to fill missing fields in.
 */ function _fillMissingFields(attrs) {
    var attr;
    for(var i = 0; i < attrs.length; ++i){
        attr = attrs[i];
        // populate missing name
        if (typeof attr.name === 'undefined') {
            if (attr.type && attr.type in pki.oids) attr.name = pki.oids[attr.type];
            else if (attr.shortName && attr.shortName in _shortNames) attr.name = pki.oids[_shortNames[attr.shortName]];
        }
        // populate missing type (OID)
        if (typeof attr.type === 'undefined') {
            if (attr.name && attr.name in pki.oids) attr.type = pki.oids[attr.name];
            else {
                var error = new Error('Attribute type not specified.');
                error.attribute = attr;
                throw error;
            }
        }
        // populate missing shortname
        if (typeof attr.shortName === 'undefined') {
            if (attr.name && attr.name in _shortNames) attr.shortName = _shortNames[attr.name];
        }
        // convert extensions to value
        if (attr.type === oids.extensionRequest) {
            attr.valueConstructed = true;
            attr.valueTagClass = asn1.Type.SEQUENCE;
            if (!attr.value && attr.extensions) {
                attr.value = [];
                for(var ei = 0; ei < attr.extensions.length; ++ei)attr.value.push(pki.certificateExtensionToAsn1(_fillMissingExtensionFields(attr.extensions[ei])));
            }
        }
        if (typeof attr.value === 'undefined') {
            var error = new Error('Attribute value not specified.');
            error.attribute = attr;
            throw error;
        }
    }
}
/**
 * Fills in missing fields in certificate extensions.
 *
 * @param e the extension.
 * @param [options] the options to use.
 *          [cert] the certificate the extensions are for.
 *
 * @return the extension.
 */ function _fillMissingExtensionFields(e, options) {
    options = options || {
    };
    // populate missing name
    if (typeof e.name === 'undefined') {
        if (e.id && e.id in pki.oids) e.name = pki.oids[e.id];
    }
    // populate missing id
    if (typeof e.id === 'undefined') {
        if (e.name && e.name in pki.oids) e.id = pki.oids[e.name];
        else {
            var error = new Error('Extension ID not specified.');
            error.extension = e;
            throw error;
        }
    }
    if (typeof e.value !== 'undefined') return e;
    // handle missing value:
    // value is a BIT STRING
    if (e.name === 'keyUsage') {
        // build flags
        var unused = 0;
        var b2 = 0;
        var b3 = 0;
        if (e.digitalSignature) {
            b2 |= 128;
            unused = 7;
        }
        if (e.nonRepudiation) {
            b2 |= 64;
            unused = 6;
        }
        if (e.keyEncipherment) {
            b2 |= 32;
            unused = 5;
        }
        if (e.dataEncipherment) {
            b2 |= 16;
            unused = 4;
        }
        if (e.keyAgreement) {
            b2 |= 8;
            unused = 3;
        }
        if (e.keyCertSign) {
            b2 |= 4;
            unused = 2;
        }
        if (e.cRLSign) {
            b2 |= 2;
            unused = 1;
        }
        if (e.encipherOnly) {
            b2 |= 1;
            unused = 0;
        }
        if (e.decipherOnly) {
            b3 |= 128;
            unused = 7;
        }
        // create bit string
        var value = String.fromCharCode(unused);
        if (b3 !== 0) value += String.fromCharCode(b2) + String.fromCharCode(b3);
        else if (b2 !== 0) value += String.fromCharCode(b2);
        e.value = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.BITSTRING, false, value);
    } else if (e.name === 'basicConstraints') {
        // basicConstraints is a SEQUENCE
        e.value = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []);
        // cA BOOLEAN flag defaults to false
        if (e.cA) e.value.value.push(asn1.create(asn1.Class.UNIVERSAL, asn1.Type.BOOLEAN, false, String.fromCharCode(255)));
        if ('pathLenConstraint' in e) e.value.value.push(asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, asn1.integerToDer(e.pathLenConstraint).getBytes()));
    } else if (e.name === 'extKeyUsage') {
        // extKeyUsage is a SEQUENCE of OIDs
        e.value = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []);
        var seq = e.value.value;
        for(var key in e){
            if (e[key] !== true) continue;
            // key is name in OID map
            if (key in oids) seq.push(asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(oids[key]).getBytes()));
            else if (key.indexOf('.') !== -1) // assume key is an OID
            seq.push(asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(key).getBytes()));
        }
    } else if (e.name === 'nsCertType') {
        // nsCertType is a BIT STRING
        // build flags
        var unused = 0;
        var b2 = 0;
        if (e.client) {
            b2 |= 128;
            unused = 7;
        }
        if (e.server) {
            b2 |= 64;
            unused = 6;
        }
        if (e.email) {
            b2 |= 32;
            unused = 5;
        }
        if (e.objsign) {
            b2 |= 16;
            unused = 4;
        }
        if (e.reserved) {
            b2 |= 8;
            unused = 3;
        }
        if (e.sslCA) {
            b2 |= 4;
            unused = 2;
        }
        if (e.emailCA) {
            b2 |= 2;
            unused = 1;
        }
        if (e.objCA) {
            b2 |= 1;
            unused = 0;
        }
        // create bit string
        var value = String.fromCharCode(unused);
        if (b2 !== 0) value += String.fromCharCode(b2);
        e.value = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.BITSTRING, false, value);
    } else if (e.name === 'subjectAltName' || e.name === 'issuerAltName') {
        // SYNTAX SEQUENCE
        e.value = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []);
        var altName;
        for(var n = 0; n < e.altNames.length; ++n){
            altName = e.altNames[n];
            var value = altName.value;
            // handle IP
            if (altName.type === 7 && altName.ip) {
                value = forge.util.bytesFromIP(altName.ip);
                if (value === null) {
                    var error = new Error('Extension "ip" value is not a valid IPv4 or IPv6 address.');
                    error.extension = e;
                    throw error;
                }
            } else if (altName.type === 8) {
                // handle OID
                if (altName.oid) value = asn1.oidToDer(asn1.oidToDer(altName.oid));
                else // deprecated ... convert value to OID
                value = asn1.oidToDer(value);
            }
            e.value.value.push(asn1.create(asn1.Class.CONTEXT_SPECIFIC, altName.type, false, value));
        }
    } else if (e.name === 'nsComment' && options.cert) {
        // sanity check value is ASCII (req'd) and not too big
        if (!/^[\x00-\x7F]*$/.test(e.comment) || e.comment.length < 1 || e.comment.length > 128) throw new Error('Invalid "nsComment" content.');
        // IA5STRING opaque comment
        e.value = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.IA5STRING, false, e.comment);
    } else if (e.name === 'subjectKeyIdentifier' && options.cert) {
        var ski = options.cert.generateSubjectKeyIdentifier();
        e.subjectKeyIdentifier = ski.toHex();
        // OCTETSTRING w/digest
        e.value = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, ski.getBytes());
    } else if (e.name === 'authorityKeyIdentifier' && options.cert) {
        // SYNTAX SEQUENCE
        e.value = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []);
        var seq = e.value.value;
        if (e.keyIdentifier) {
            var keyIdentifier = e.keyIdentifier === true ? options.cert.generateSubjectKeyIdentifier().getBytes() : e.keyIdentifier;
            seq.push(asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, false, keyIdentifier));
        }
        if (e.authorityCertIssuer) {
            var authorityCertIssuer = [
                asn1.create(asn1.Class.CONTEXT_SPECIFIC, 4, true, [
                    _dnToAsn1(e.authorityCertIssuer === true ? options.cert.issuer : e.authorityCertIssuer)
                ])
            ];
            seq.push(asn1.create(asn1.Class.CONTEXT_SPECIFIC, 1, true, authorityCertIssuer));
        }
        if (e.serialNumber) {
            var serialNumber = forge.util.hexToBytes(e.serialNumber === true ? options.cert.serialNumber : e.serialNumber);
            seq.push(asn1.create(asn1.Class.CONTEXT_SPECIFIC, 2, false, serialNumber));
        }
    } else if (e.name === 'cRLDistributionPoints') {
        e.value = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []);
        var seq = e.value.value;
        // Create sub SEQUENCE of DistributionPointName
        var subSeq = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []);
        // Create fullName CHOICE
        var fullNameGeneralNames = asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, []);
        var altName;
        for(var n = 0; n < e.altNames.length; ++n){
            altName = e.altNames[n];
            var value = altName.value;
            // handle IP
            if (altName.type === 7 && altName.ip) {
                value = forge.util.bytesFromIP(altName.ip);
                if (value === null) {
                    var error = new Error('Extension "ip" value is not a valid IPv4 or IPv6 address.');
                    error.extension = e;
                    throw error;
                }
            } else if (altName.type === 8) {
                // handle OID
                if (altName.oid) value = asn1.oidToDer(asn1.oidToDer(altName.oid));
                else // deprecated ... convert value to OID
                value = asn1.oidToDer(value);
            }
            fullNameGeneralNames.value.push(asn1.create(asn1.Class.CONTEXT_SPECIFIC, altName.type, false, value));
        }
        // Add to the parent SEQUENCE
        subSeq.value.push(asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [
            fullNameGeneralNames
        ]));
        seq.push(subSeq);
    }
    // ensure value has been defined by now
    if (typeof e.value === 'undefined') {
        var error = new Error('Extension value not specified.');
        error.extension = e;
        throw error;
    }
    return e;
}
/**
 * Convert signature parameters object to ASN.1
 *
 * @param {String} oid Signature algorithm OID
 * @param params The signature parametrs object
 * @return ASN.1 object representing signature parameters
 */ function _signatureParametersToAsn1(oid, params) {
    switch(oid){
        case oids['RSASSA-PSS']:
            var parts = [];
            if (params.hash.algorithmOid !== undefined) parts.push(asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [
                asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
                    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(params.hash.algorithmOid).getBytes()),
                    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '')
                ])
            ]));
            if (params.mgf.algorithmOid !== undefined) parts.push(asn1.create(asn1.Class.CONTEXT_SPECIFIC, 1, true, [
                asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
                    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(params.mgf.algorithmOid).getBytes()),
                    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
                        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(params.mgf.hash.algorithmOid).getBytes()),
                        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '')
                    ])
                ])
            ]));
            if (params.saltLength !== undefined) parts.push(asn1.create(asn1.Class.CONTEXT_SPECIFIC, 2, true, [
                asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, asn1.integerToDer(params.saltLength).getBytes())
            ]));
            return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, parts);
        default:
            return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '');
    }
}
/**
 * Converts a certification request's attributes to an ASN.1 set of
 * CRIAttributes.
 *
 * @param csr certification request.
 *
 * @return the ASN.1 set of CRIAttributes.
 */ function _CRIAttributesToAsn1(csr) {
    // create an empty context-specific container
    var rval = asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, []);
    // no attributes, return empty container
    if (csr.attributes.length === 0) return rval;
    // each attribute has a sequence with a type and a set of values
    var attrs = csr.attributes;
    for(var i = 0; i < attrs.length; ++i){
        var attr = attrs[i];
        var value = attr.value;
        // reuse tag class for attribute value if available
        var valueTagClass = asn1.Type.UTF8;
        if ('valueTagClass' in attr) valueTagClass = attr.valueTagClass;
        if (valueTagClass === asn1.Type.UTF8) value = forge.util.encodeUtf8(value);
        var valueConstructed = false;
        if ('valueConstructed' in attr) valueConstructed = attr.valueConstructed;
        // FIXME: handle more encodings
        // create a RelativeDistinguishedName set
        // each value in the set is an AttributeTypeAndValue first
        // containing the type (an OID) and second the value
        var seq = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
            // AttributeType
            asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(attr.type).getBytes()),
            asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SET, true, [
                // AttributeValue
                asn1.create(asn1.Class.UNIVERSAL, valueTagClass, valueConstructed, value)
            ])
        ]);
        rval.value.push(seq);
    }
    return rval;
}
var jan_1_1950 = new Date('1950-01-01T00:00:00Z');
var jan_1_2050 = new Date('2050-01-01T00:00:00Z');
/**
 * Converts a Date object to ASN.1
 * Handles the different format before and after 1st January 2050
 *
 * @param date date object.
 *
 * @return the ASN.1 object representing the date.
 */ function _dateToAsn1(date) {
    if (date >= jan_1_1950 && date < jan_1_2050) return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.UTCTIME, false, asn1.dateToUtcTime(date));
    else return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.GENERALIZEDTIME, false, asn1.dateToGeneralizedTime(date));
}
/**
 * Gets the ASN.1 TBSCertificate part of an X.509v3 certificate.
 *
 * @param cert the certificate.
 *
 * @return the asn1 TBSCertificate.
 */ pki.getTBSCertificate = function(cert) {
    // TBSCertificate
    var notBefore = _dateToAsn1(cert.validity.notBefore);
    var notAfter = _dateToAsn1(cert.validity.notAfter);
    var tbs = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
        // version
        asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [
            // integer
            asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, asn1.integerToDer(cert.version).getBytes())
        ]),
        // serialNumber
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, forge.util.hexToBytes(cert.serialNumber)),
        // signature
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
            // algorithm
            asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(cert.siginfo.algorithmOid).getBytes()),
            // parameters
            _signatureParametersToAsn1(cert.siginfo.algorithmOid, cert.siginfo.parameters)
        ]),
        // issuer
        _dnToAsn1(cert.issuer),
        // validity
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
            notBefore,
            notAfter
        ]),
        // subject
        _dnToAsn1(cert.subject),
        // SubjectPublicKeyInfo
        pki.publicKeyToAsn1(cert.publicKey)
    ]);
    if (cert.issuer.uniqueId) // issuerUniqueID (optional)
    tbs.value.push(asn1.create(asn1.Class.CONTEXT_SPECIFIC, 1, true, [
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.BITSTRING, false, // TODO: support arbitrary bit length ids
        String.fromCharCode(0) + cert.issuer.uniqueId)
    ]));
    if (cert.subject.uniqueId) // subjectUniqueID (optional)
    tbs.value.push(asn1.create(asn1.Class.CONTEXT_SPECIFIC, 2, true, [
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.BITSTRING, false, // TODO: support arbitrary bit length ids
        String.fromCharCode(0) + cert.subject.uniqueId)
    ]));
    if (cert.extensions.length > 0) // extensions (optional)
    tbs.value.push(pki.certificateExtensionsToAsn1(cert.extensions));
    return tbs;
};
/**
 * Gets the ASN.1 CertificationRequestInfo part of a
 * PKCS#10 CertificationRequest.
 *
 * @param csr the certification request.
 *
 * @return the asn1 CertificationRequestInfo.
 */ pki.getCertificationRequestInfo = function(csr) {
    // CertificationRequestInfo
    var cri = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
        // version
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, asn1.integerToDer(csr.version).getBytes()),
        // subject
        _dnToAsn1(csr.subject),
        // SubjectPublicKeyInfo
        pki.publicKeyToAsn1(csr.publicKey),
        // attributes
        _CRIAttributesToAsn1(csr)
    ]);
    return cri;
};
/**
 * Converts a DistinguishedName (subject or issuer) to an ASN.1 object.
 *
 * @param dn the DistinguishedName.
 *
 * @return the asn1 representation of a DistinguishedName.
 */ pki.distinguishedNameToAsn1 = function(dn) {
    return _dnToAsn1(dn);
};
/**
 * Converts an X.509v3 RSA certificate to an ASN.1 object.
 *
 * @param cert the certificate.
 *
 * @return the asn1 representation of an X.509v3 RSA certificate.
 */ pki.certificateToAsn1 = function(cert) {
    // prefer cached TBSCertificate over generating one
    var tbsCertificate = cert.tbsCertificate || pki.getTBSCertificate(cert);
    // Certificate
    return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
        // TBSCertificate
        tbsCertificate,
        // AlgorithmIdentifier (signature algorithm)
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
            // algorithm
            asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(cert.signatureOid).getBytes()),
            // parameters
            _signatureParametersToAsn1(cert.signatureOid, cert.signatureParameters)
        ]),
        // SignatureValue
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.BITSTRING, false, String.fromCharCode(0) + cert.signature)
    ]);
};
/**
 * Converts X.509v3 certificate extensions to ASN.1.
 *
 * @param exts the extensions to convert.
 *
 * @return the extensions in ASN.1 format.
 */ pki.certificateExtensionsToAsn1 = function(exts) {
    // create top-level extension container
    var rval = asn1.create(asn1.Class.CONTEXT_SPECIFIC, 3, true, []);
    // create extension sequence (stores a sequence for each extension)
    var seq = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []);
    rval.value.push(seq);
    for(var i = 0; i < exts.length; ++i)seq.value.push(pki.certificateExtensionToAsn1(exts[i]));
    return rval;
};
/**
 * Converts a single certificate extension to ASN.1.
 *
 * @param ext the extension to convert.
 *
 * @return the extension in ASN.1 format.
 */ pki.certificateExtensionToAsn1 = function(ext) {
    // create a sequence for each extension
    var extseq = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []);
    // extnID (OID)
    extseq.value.push(asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(ext.id).getBytes()));
    // critical defaults to false
    if (ext.critical) // critical BOOLEAN DEFAULT FALSE
    extseq.value.push(asn1.create(asn1.Class.UNIVERSAL, asn1.Type.BOOLEAN, false, String.fromCharCode(255)));
    var value = ext.value;
    if (typeof ext.value !== 'string') // value is asn.1
    value = asn1.toDer(value).getBytes();
    // extnValue (OCTET STRING)
    extseq.value.push(asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, value));
    return extseq;
};
/**
 * Converts a PKCS#10 certification request to an ASN.1 object.
 *
 * @param csr the certification request.
 *
 * @return the asn1 representation of a certification request.
 */ pki.certificationRequestToAsn1 = function(csr) {
    // prefer cached CertificationRequestInfo over generating one
    var cri = csr.certificationRequestInfo || pki.getCertificationRequestInfo(csr);
    // Certificate
    return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
        // CertificationRequestInfo
        cri,
        // AlgorithmIdentifier (signature algorithm)
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
            // algorithm
            asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer(csr.signatureOid).getBytes()),
            // parameters
            _signatureParametersToAsn1(csr.signatureOid, csr.signatureParameters)
        ]),
        // signature
        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.BITSTRING, false, String.fromCharCode(0) + csr.signature)
    ]);
};
/**
 * Creates a CA store.
 *
 * @param certs an optional array of certificate objects or PEM-formatted
 *          certificate strings to add to the CA store.
 *
 * @return the CA store.
 */ pki.createCaStore = function(certs) {
    // create CA store
    var caStore = {
        // stored certificates
        certs: {
        }
    };
    /**
   * Gets the certificate that issued the passed certificate or its
   * 'parent'.
   *
   * @param cert the certificate to get the parent for.
   *
   * @return the parent certificate or null if none was found.
   */ caStore.getIssuer = function(cert) {
        var rval = getBySubject(cert.issuer);
        // see if there are multiple matches
        /*if(forge.util.isArray(rval)) {
      // TODO: resolve multiple matches by checking
      // authorityKey/subjectKey/issuerUniqueID/other identifiers, etc.
      // FIXME: or alternatively do authority key mapping
      // if possible (X.509v1 certs can't work?)
      throw new Error('Resolving multiple issuer matches not implemented yet.');
    }*/ return rval;
    };
    /**
   * Adds a trusted certificate to the store.
   *
   * @param cert the certificate to add as a trusted certificate (either a
   *          pki.certificate object or a PEM-formatted certificate).
   */ caStore.addCertificate = function(cert) {
        // convert from pem if necessary
        if (typeof cert === 'string') cert = forge.pki.certificateFromPem(cert);
        ensureSubjectHasHash(cert.subject);
        if (!caStore.hasCertificate(cert)) {
            if (cert.subject.hash in caStore.certs) {
                // subject hash already exists, append to array
                var tmp = caStore.certs[cert.subject.hash];
                if (!forge.util.isArray(tmp)) tmp = [
                    tmp
                ];
                tmp.push(cert);
                caStore.certs[cert.subject.hash] = tmp;
            } else caStore.certs[cert.subject.hash] = cert;
        }
    };
    /**
   * Checks to see if the given certificate is in the store.
   *
   * @param cert the certificate to check (either a pki.certificate or a
   *          PEM-formatted certificate).
   *
   * @return true if the certificate is in the store, false if not.
   */ caStore.hasCertificate = function(cert) {
        // convert from pem if necessary
        if (typeof cert === 'string') cert = forge.pki.certificateFromPem(cert);
        var match = getBySubject(cert.subject);
        if (!match) return false;
        if (!forge.util.isArray(match)) match = [
            match
        ];
        // compare DER-encoding of certificates
        var der1 = asn1.toDer(pki.certificateToAsn1(cert)).getBytes();
        for(var i = 0; i < match.length; ++i){
            var der2 = asn1.toDer(pki.certificateToAsn1(match[i])).getBytes();
            if (der1 === der2) return true;
        }
        return false;
    };
    /**
   * Lists all of the certificates kept in the store.
   *
   * @return an array of all of the pki.certificate objects in the store.
   */ caStore.listAllCertificates = function() {
        var certList = [];
        for(var hash in caStore.certs)if (caStore.certs.hasOwnProperty(hash)) {
            var value = caStore.certs[hash];
            if (!forge.util.isArray(value)) certList.push(value);
            else for(var i = 0; i < value.length; ++i)certList.push(value[i]);
        }
        return certList;
    };
    /**
   * Removes a certificate from the store.
   *
   * @param cert the certificate to remove (either a pki.certificate or a
   *          PEM-formatted certificate).
   *
   * @return the certificate that was removed or null if the certificate
   *           wasn't in store.
   */ caStore.removeCertificate = function(cert) {
        var result;
        // convert from pem if necessary
        if (typeof cert === 'string') cert = forge.pki.certificateFromPem(cert);
        ensureSubjectHasHash(cert.subject);
        if (!caStore.hasCertificate(cert)) return null;
        var match = getBySubject(cert.subject);
        if (!forge.util.isArray(match)) {
            result = caStore.certs[cert.subject.hash];
            delete caStore.certs[cert.subject.hash];
            return result;
        }
        // compare DER-encoding of certificates
        var der1 = asn1.toDer(pki.certificateToAsn1(cert)).getBytes();
        for(var i = 0; i < match.length; ++i){
            var der2 = asn1.toDer(pki.certificateToAsn1(match[i])).getBytes();
            if (der1 === der2) {
                result = match[i];
                match.splice(i, 1);
            }
        }
        if (match.length === 0) delete caStore.certs[cert.subject.hash];
        return result;
    };
    function getBySubject(subject) {
        ensureSubjectHasHash(subject);
        return caStore.certs[subject.hash] || null;
    }
    function ensureSubjectHasHash(subject) {
        // produce subject hash if it doesn't exist
        if (!subject.hash) {
            var md = forge.md.sha1.create();
            subject.attributes = pki.RDNAttributesAsArray(_dnToAsn1(subject), md);
            subject.hash = md.digest().toHex();
        }
    }
    // auto-add passed in certs
    if (certs) // parse PEM-formatted certificates as necessary
    for(var i1 = 0; i1 < certs.length; ++i1){
        var cert1 = certs[i1];
        caStore.addCertificate(cert1);
    }
    return caStore;
};
/**
 * Certificate verification errors, based on TLS.
 */ pki.certificateError = {
    bad_certificate: 'forge.pki.BadCertificate',
    unsupported_certificate: 'forge.pki.UnsupportedCertificate',
    certificate_revoked: 'forge.pki.CertificateRevoked',
    certificate_expired: 'forge.pki.CertificateExpired',
    certificate_unknown: 'forge.pki.CertificateUnknown',
    unknown_ca: 'forge.pki.UnknownCertificateAuthority'
};
/**
 * Verifies a certificate chain against the given Certificate Authority store
 * with an optional custom verify callback.
 *
 * @param caStore a certificate store to verify against.
 * @param chain the certificate chain to verify, with the root or highest
 *          authority at the end (an array of certificates).
 * @param options a callback to be called for every certificate in the chain or
 *                  an object with:
 *                  verify a callback to be called for every certificate in the
 *                    chain
 *                  validityCheckDate the date against which the certificate
 *                    validity period should be checked. Pass null to not check
 *                    the validity period. By default, the current date is used.
 *
 * The verify callback has the following signature:
 *
 * verified - Set to true if certificate was verified, otherwise the
 *   pki.certificateError for why the certificate failed.
 * depth - The current index in the chain, where 0 is the end point's cert.
 * certs - The certificate chain, *NOTE* an empty chain indicates an anonymous
 *   end point.
 *
 * The function returns true on success and on failure either the appropriate
 * pki.certificateError or an object with 'error' set to the appropriate
 * pki.certificateError and 'message' set to a custom error message.
 *
 * @return true if successful, error thrown if not.
 */ pki.verifyCertificateChain = function(caStore, chain, options) {
    /* From: RFC3280 - Internet X.509 Public Key Infrastructure Certificate
    Section 6: Certification Path Validation
    See inline parentheticals related to this particular implementation.

    The primary goal of path validation is to verify the binding between
    a subject distinguished name or a subject alternative name and subject
    public key, as represented in the end entity certificate, based on the
    public key of the trust anchor. This requires obtaining a sequence of
    certificates that support that binding. That sequence should be provided
    in the passed 'chain'. The trust anchor should be in the given CA
    store. The 'end entity' certificate is the certificate provided by the
    end point (typically a server) and is the first in the chain.

    To meet this goal, the path validation process verifies, among other
    things, that a prospective certification path (a sequence of n
    certificates or a 'chain') satisfies the following conditions:

    (a) for all x in {1, ..., n-1}, the subject of certificate x is
          the issuer of certificate x+1;

    (b) certificate 1 is issued by the trust anchor;

    (c) certificate n is the certificate to be validated; and

    (d) for all x in {1, ..., n}, the certificate was valid at the
          time in question.

    Note that here 'n' is index 0 in the chain and 1 is the last certificate
    in the chain and it must be signed by a certificate in the connection's
    CA store.

    The path validation process also determines the set of certificate
    policies that are valid for this path, based on the certificate policies
    extension, policy mapping extension, policy constraints extension, and
    inhibit any-policy extension.

    Note: Policy mapping extension not supported (Not Required).

    Note: If the certificate has an unsupported critical extension, then it
    must be rejected.

    Note: A certificate is self-issued if the DNs that appear in the subject
    and issuer fields are identical and are not empty.

    The path validation algorithm assumes the following seven inputs are
    provided to the path processing logic. What this specific implementation
    will use is provided parenthetically:

    (a) a prospective certification path of length n (the 'chain')
    (b) the current date/time: ('now').
    (c) user-initial-policy-set: A set of certificate policy identifiers
          naming the policies that are acceptable to the certificate user.
          The user-initial-policy-set contains the special value any-policy
          if the user is not concerned about certificate policy
          (Not implemented. Any policy is accepted).
    (d) trust anchor information, describing a CA that serves as a trust
          anchor for the certification path. The trust anchor information
          includes:

      (1)  the trusted issuer name,
      (2)  the trusted public key algorithm,
      (3)  the trusted public key, and
      (4)  optionally, the trusted public key parameters associated
             with the public key.

      (Trust anchors are provided via certificates in the CA store).

      The trust anchor information may be provided to the path processing
      procedure in the form of a self-signed certificate. The trusted anchor
      information is trusted because it was delivered to the path processing
      procedure by some trustworthy out-of-band procedure. If the trusted
      public key algorithm requires parameters, then the parameters are
      provided along with the trusted public key (No parameters used in this
      implementation).

    (e) initial-policy-mapping-inhibit, which indicates if policy mapping is
          allowed in the certification path.
          (Not implemented, no policy checking)

    (f) initial-explicit-policy, which indicates if the path must be valid
          for at least one of the certificate policies in the user-initial-
          policy-set.
          (Not implemented, no policy checking)

    (g) initial-any-policy-inhibit, which indicates whether the
          anyPolicy OID should be processed if it is included in a
          certificate.
          (Not implemented, so any policy is valid provided that it is
          not marked as critical) */ /* Basic Path Processing:

    For each certificate in the 'chain', the following is checked:

    1. The certificate validity period includes the current time.
    2. The certificate was signed by its parent (where the parent is either
       the next in the chain or from the CA store). Allow processing to
       continue to the next step if no parent is found but the certificate is
       in the CA store.
    3. TODO: The certificate has not been revoked.
    4. The certificate issuer name matches the parent's subject name.
    5. TODO: If the certificate is self-issued and not the final certificate
       in the chain, skip this step, otherwise verify that the subject name
       is within one of the permitted subtrees of X.500 distinguished names
       and that each of the alternative names in the subjectAltName extension
       (critical or non-critical) is within one of the permitted subtrees for
       that name type.
    6. TODO: If the certificate is self-issued and not the final certificate
       in the chain, skip this step, otherwise verify that the subject name
       is not within one of the excluded subtrees for X.500 distinguished
       names and none of the subjectAltName extension names are excluded for
       that name type.
    7. The other steps in the algorithm for basic path processing involve
       handling the policy extension which is not presently supported in this
       implementation. Instead, if a critical policy extension is found, the
       certificate is rejected as not supported.
    8. If the certificate is not the first or if its the only certificate in
       the chain (having no parent from the CA store or is self-signed) and it
       has a critical key usage extension, verify that the keyCertSign bit is
       set. If the key usage extension exists, verify that the basic
       constraints extension exists. If the basic constraints extension exists,
       verify that the cA flag is set. If pathLenConstraint is set, ensure that
       the number of certificates that precede in the chain (come earlier
       in the chain as implemented below), excluding the very first in the
       chain (typically the end-entity one), isn't greater than the
       pathLenConstraint. This constraint limits the number of intermediate
       CAs that may appear below a CA before only end-entity certificates
       may be issued. */ // if a verify callback is passed as the third parameter, package it within
    // the options object. This is to support a legacy function signature that
    // expected the verify callback as the third parameter.
    if (typeof options === 'function') options = {
        verify: options
    };
    options = options || {
    };
    // copy cert chain references to another array to protect against changes
    // in verify callback
    chain = chain.slice(0);
    var certs = chain.slice(0);
    var validityCheckDate = options.validityCheckDate;
    // if no validityCheckDate is specified, default to the current date. Make
    // sure to maintain the value null because it indicates that the validity
    // period should not be checked.
    if (typeof validityCheckDate === 'undefined') validityCheckDate = new Date();
    // verify each cert in the chain using its parent, where the parent
    // is either the next in the chain or from the CA store
    var first = true;
    var error = null;
    var depth = 0;
    do {
        var cert = chain.shift();
        var parent = null;
        var selfSigned = false;
        if (validityCheckDate) // 1. check valid time
        {
            if (validityCheckDate < cert.validity.notBefore || validityCheckDate > cert.validity.notAfter) error = {
                message: 'Certificate is not valid yet or has expired.',
                error: pki.certificateError.certificate_expired,
                notBefore: cert.validity.notBefore,
                notAfter: cert.validity.notAfter,
                // TODO: we might want to reconsider renaming 'now' to
                // 'validityCheckDate' should this API be changed in the future.
                now: validityCheckDate
            };
        }
        // 2. verify with parent from chain or CA store
        if (error === null) {
            parent = chain[0] || caStore.getIssuer(cert);
            if (parent === null) // check for self-signed cert
            {
                if (cert.isIssuer(cert)) {
                    selfSigned = true;
                    parent = cert;
                }
            }
            if (parent) {
                // FIXME: current CA store implementation might have multiple
                // certificates where the issuer can't be determined from the
                // certificate (happens rarely with, eg: old certificates) so normalize
                // by always putting parents into an array
                // TODO: there's may be an extreme degenerate case currently uncovered
                // where an old intermediate certificate seems to have a matching parent
                // but none of the parents actually verify ... but the intermediate
                // is in the CA and it should pass this check; needs investigation
                var parents = parent;
                if (!forge.util.isArray(parents)) parents = [
                    parents
                ];
                // try to verify with each possible parent (typically only one)
                var verified = false;
                while(!verified && parents.length > 0){
                    parent = parents.shift();
                    try {
                        verified = parent.verify(cert);
                    } catch (ex) {
                    // failure to verify, don't care why, try next one
                    }
                }
                if (!verified) error = {
                    message: 'Certificate signature is invalid.',
                    error: pki.certificateError.bad_certificate
                };
            }
            if (error === null && (!parent || selfSigned) && !caStore.hasCertificate(cert)) // no parent issuer and certificate itself is not trusted
            error = {
                message: 'Certificate is not trusted.',
                error: pki.certificateError.unknown_ca
            };
        }
        // TODO: 3. check revoked
        // 4. check for matching issuer/subject
        if (error === null && parent && !cert.isIssuer(parent)) // parent is not issuer
        error = {
            message: 'Certificate issuer is invalid.',
            error: pki.certificateError.bad_certificate
        };
        // 5. TODO: check names with permitted names tree
        // 6. TODO: check names against excluded names tree
        // 7. check for unsupported critical extensions
        if (error === null) {
            // supported extensions
            var se = {
                keyUsage: true,
                basicConstraints: true
            };
            for(var i = 0; error === null && i < cert.extensions.length; ++i){
                var ext = cert.extensions[i];
                if (ext.critical && !(ext.name in se)) error = {
                    message: 'Certificate has an unsupported critical extension.',
                    error: pki.certificateError.unsupported_certificate
                };
            }
        }
        // 8. check for CA if cert is not first or is the only certificate
        // remaining in chain with no parent or is self-signed
        if (error === null && (!first || chain.length === 0 && (!parent || selfSigned))) {
            // first check keyUsage extension and then basic constraints
            var bcExt = cert.getExtension('basicConstraints');
            var keyUsageExt = cert.getExtension('keyUsage');
            if (keyUsageExt !== null) // keyCertSign must be true and there must be a basic
            // constraints extension
            {
                if (!keyUsageExt.keyCertSign || bcExt === null) // bad certificate
                error = {
                    message: "Certificate keyUsage or basicConstraints conflict or indicate that the certificate is not a CA. If the certificate is the only one in the chain or isn't the first then the certificate must be a valid CA.",
                    error: pki.certificateError.bad_certificate
                };
            }
            // basic constraints cA flag must be set
            if (error === null && bcExt !== null && !bcExt.cA) // bad certificate
            error = {
                message: "Certificate basicConstraints indicates the certificate is not a CA.",
                error: pki.certificateError.bad_certificate
            };
            // if error is not null and keyUsage is available, then we know it
            // has keyCertSign and there is a basic constraints extension too,
            // which means we can check pathLenConstraint (if it exists)
            if (error === null && keyUsageExt !== null && 'pathLenConstraint' in bcExt) {
                // pathLen is the maximum # of intermediate CA certs that can be
                // found between the current certificate and the end-entity (depth 0)
                // certificate; this number does not include the end-entity (depth 0,
                // last in the chain) even if it happens to be a CA certificate itself
                var pathLen = depth - 1;
                if (pathLen > bcExt.pathLenConstraint) // pathLenConstraint violated, bad certificate
                error = {
                    message: 'Certificate basicConstraints pathLenConstraint violated.',
                    error: pki.certificateError.bad_certificate
                };
            }
        }
        // call application callback
        var vfd = error === null ? true : error.error;
        var ret = options.verify ? options.verify(vfd, depth, certs) : vfd;
        if (ret === true) // clear any set error
        error = null;
        else {
            // if passed basic tests, set default message and alert
            if (vfd === true) error = {
                message: 'The application rejected the certificate.',
                error: pki.certificateError.bad_certificate
            };
            // check for custom error info
            if (ret || ret === 0) {
                // set custom message and error
                if (typeof ret === 'object' && !forge.util.isArray(ret)) {
                    if (ret.message) error.message = ret.message;
                    if (ret.error) error.error = ret.error;
                } else if (typeof ret === 'string') // set custom error
                error.error = ret;
            }
            // throw error
            throw error;
        }
        // no longer first cert in chain
        first = false;
        ++depth;
    }while (chain.length > 0)
    return true;
};

},{"./forge":"7AnVp","./aes":"jgIby","./asn1":"fLyrX","./des":"6QyDg","./md":"9dnCj","./mgf":"jU0Di","./oids":"iymJu","./pem":"axmYn","./pss":"31HTC","./rsa":"2GXRz","./util":"cHj6b"}],"jU0Di":[function(require,module,exports) {
/**
 * Node.js module for Forge mask generation functions.
 *
 * @author Stefan Siegl
 *
 * Copyright 2012 Stefan Siegl <stesie@brokenpipe.de>
 */ var forge = require('./forge');
require('./mgf1');
module.exports = forge.mgf = forge.mgf || {
};
forge.mgf.mgf1 = forge.mgf1;

},{"./forge":"7AnVp","./mgf1":"3i3Za"}],"3i3Za":[function(require,module,exports) {
/**
 * Javascript implementation of mask generation function MGF1.
 *
 * @author Stefan Siegl
 * @author Dave Longley
 *
 * Copyright (c) 2012 Stefan Siegl <stesie@brokenpipe.de>
 * Copyright (c) 2014 Digital Bazaar, Inc.
 */ var forge = require('./forge');
require('./util');
forge.mgf = forge.mgf || {
};
var mgf1 = module.exports = forge.mgf.mgf1 = forge.mgf1 = forge.mgf1 || {
};
/**
 * Creates a MGF1 mask generation function object.
 *
 * @param md the message digest API to use (eg: forge.md.sha1.create()).
 *
 * @return a mask generation function object.
 */ mgf1.create = function(md) {
    var mgf = {
        /**
     * Generate mask of specified length.
     *
     * @param {String} seed The seed for mask generation.
     * @param maskLen Number of bytes to generate.
     * @return {String} The generated mask.
     */ generate: function(seed, maskLen) {
            /* 2. Let T be the empty octet string. */ var t = new forge.util.ByteBuffer();
            /* 3. For counter from 0 to ceil(maskLen / hLen), do the following: */ var len = Math.ceil(maskLen / md.digestLength);
            for(var i = 0; i < len; i++){
                /* a. Convert counter to an octet string C of length 4 octets */ var c = new forge.util.ByteBuffer();
                c.putInt32(i);
                /* b. Concatenate the hash of the seed mgfSeed and C to the octet
         * string T: */ md.start();
                md.update(seed + c.getBytes());
                t.putBuffer(md.digest());
            }
            /* Output the leading maskLen octets of T as the octet string mask. */ t.truncate(t.length() - maskLen);
            return t.getBytes();
        }
    };
    return mgf;
};

},{"./forge":"7AnVp","./util":"cHj6b"}],"31HTC":[function(require,module,exports) {
/**
 * Javascript implementation of PKCS#1 PSS signature padding.
 *
 * @author Stefan Siegl
 *
 * Copyright (c) 2012 Stefan Siegl <stesie@brokenpipe.de>
 */ var forge = require('./forge');
require('./random');
require('./util');
// shortcut for PSS API
var pss = module.exports = forge.pss = forge.pss || {
};
/**
 * Creates a PSS signature scheme object.
 *
 * There are several ways to provide a salt for encoding:
 *
 * 1. Specify the saltLength only and the built-in PRNG will generate it.
 * 2. Specify the saltLength and a custom PRNG with 'getBytesSync' defined that
 *   will be used.
 * 3. Specify the salt itself as a forge.util.ByteBuffer.
 *
 * @param options the options to use:
 *          md the message digest object to use, a forge md instance.
 *          mgf the mask generation function to use, a forge mgf instance.
 *          [saltLength] the length of the salt in octets.
 *          [prng] the pseudo-random number generator to use to produce a salt.
 *          [salt] the salt to use when encoding.
 *
 * @return a signature scheme object.
 */ pss.create = function(options) {
    // backwards compatibility w/legacy args: hash, mgf, sLen
    if (arguments.length === 3) options = {
        md: arguments[0],
        mgf: arguments[1],
        saltLength: arguments[2]
    };
    var hash = options.md;
    var mgf = options.mgf;
    var hLen = hash.digestLength;
    var salt_ = options.salt || null;
    if (typeof salt_ === 'string') // assume binary-encoded string
    salt_ = forge.util.createBuffer(salt_);
    var sLen;
    if ('saltLength' in options) sLen = options.saltLength;
    else if (salt_ !== null) sLen = salt_.length();
    else throw new Error('Salt length not specified or specific salt not given.');
    if (salt_ !== null && salt_.length() !== sLen) throw new Error('Given salt length does not match length of given salt.');
    var prng = options.prng || forge.random;
    var pssobj = {
    };
    /**
   * Encodes a PSS signature.
   *
   * This function implements EMSA-PSS-ENCODE as per RFC 3447, section 9.1.1.
   *
   * @param md the message digest object with the hash to sign.
   * @param modsBits the length of the RSA modulus in bits.
   *
   * @return the encoded message as a binary-encoded string of length
   *           ceil((modBits - 1) / 8).
   */ pssobj.encode = function(md, modBits) {
        var i;
        var emBits = modBits - 1;
        var emLen = Math.ceil(emBits / 8);
        /* 2. Let mHash = Hash(M), an octet string of length hLen. */ var mHash = md.digest().getBytes();
        /* 3. If emLen < hLen + sLen + 2, output "encoding error" and stop. */ if (emLen < hLen + sLen + 2) throw new Error('Message is too long to encrypt.');
        /* 4. Generate a random octet string salt of length sLen; if sLen = 0,
     *    then salt is the empty string. */ var salt;
        if (salt_ === null) salt = prng.getBytesSync(sLen);
        else salt = salt_.bytes();
        /* 5. Let M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt; */ var m_ = new forge.util.ByteBuffer();
        m_.fillWithByte(0, 8);
        m_.putBytes(mHash);
        m_.putBytes(salt);
        /* 6. Let H = Hash(M'), an octet string of length hLen. */ hash.start();
        hash.update(m_.getBytes());
        var h = hash.digest().getBytes();
        /* 7. Generate an octet string PS consisting of emLen - sLen - hLen - 2
     *    zero octets.  The length of PS may be 0. */ var ps = new forge.util.ByteBuffer();
        ps.fillWithByte(0, emLen - sLen - hLen - 2);
        /* 8. Let DB = PS || 0x01 || salt; DB is an octet string of length
     *    emLen - hLen - 1. */ ps.putByte(1);
        ps.putBytes(salt);
        var db = ps.getBytes();
        /* 9. Let dbMask = MGF(H, emLen - hLen - 1). */ var maskLen = emLen - hLen - 1;
        var dbMask = mgf.generate(h, maskLen);
        /* 10. Let maskedDB = DB \xor dbMask. */ var maskedDB = '';
        for(i = 0; i < maskLen; i++)maskedDB += String.fromCharCode(db.charCodeAt(i) ^ dbMask.charCodeAt(i));
        /* 11. Set the leftmost 8emLen - emBits bits of the leftmost octet in
     *     maskedDB to zero. */ var mask = 65280 >> 8 * emLen - emBits & 255;
        maskedDB = String.fromCharCode(maskedDB.charCodeAt(0) & ~mask) + maskedDB.substr(1);
        /* 12. Let EM = maskedDB || H || 0xbc.
     * 13. Output EM. */ return maskedDB + h + String.fromCharCode(188);
    };
    /**
   * Verifies a PSS signature.
   *
   * This function implements EMSA-PSS-VERIFY as per RFC 3447, section 9.1.2.
   *
   * @param mHash the message digest hash, as a binary-encoded string, to
   *         compare against the signature.
   * @param em the encoded message, as a binary-encoded string
   *          (RSA decryption result).
   * @param modsBits the length of the RSA modulus in bits.
   *
   * @return true if the signature was verified, false if not.
   */ pssobj.verify = function(mHash, em, modBits) {
        var i;
        var emBits = modBits - 1;
        var emLen = Math.ceil(emBits / 8);
        /* c. Convert the message representative m to an encoded message EM
     *    of length emLen = ceil((modBits - 1) / 8) octets, where modBits
     *    is the length in bits of the RSA modulus n */ em = em.substr(-emLen);
        /* 3. If emLen < hLen + sLen + 2, output "inconsistent" and stop. */ if (emLen < hLen + sLen + 2) throw new Error('Inconsistent parameters to PSS signature verification.');
        /* 4. If the rightmost octet of EM does not have hexadecimal value
     *    0xbc, output "inconsistent" and stop. */ if (em.charCodeAt(emLen - 1) !== 188) throw new Error('Encoded message does not end in 0xBC.');
        /* 5. Let maskedDB be the leftmost emLen - hLen - 1 octets of EM, and
     *    let H be the next hLen octets. */ var maskLen = emLen - hLen - 1;
        var maskedDB = em.substr(0, maskLen);
        var h = em.substr(maskLen, hLen);
        /* 6. If the leftmost 8emLen - emBits bits of the leftmost octet in
     *    maskedDB are not all equal to zero, output "inconsistent" and stop. */ var mask = 65280 >> 8 * emLen - emBits & 255;
        if ((maskedDB.charCodeAt(0) & mask) !== 0) throw new Error('Bits beyond keysize not zero as expected.');
        /* 7. Let dbMask = MGF(H, emLen - hLen - 1). */ var dbMask = mgf.generate(h, maskLen);
        /* 8. Let DB = maskedDB \xor dbMask. */ var db = '';
        for(i = 0; i < maskLen; i++)db += String.fromCharCode(maskedDB.charCodeAt(i) ^ dbMask.charCodeAt(i));
        /* 9. Set the leftmost 8emLen - emBits bits of the leftmost octet
     * in DB to zero. */ db = String.fromCharCode(db.charCodeAt(0) & ~mask) + db.substr(1);
        /* 10. If the emLen - hLen - sLen - 2 leftmost octets of DB are not zero
     * or if the octet at position emLen - hLen - sLen - 1 (the leftmost
     * position is "position 1") does not have hexadecimal value 0x01,
     * output "inconsistent" and stop. */ var checkLen = emLen - hLen - sLen - 2;
        for(i = 0; i < checkLen; i++){
            if (db.charCodeAt(i) !== 0) throw new Error('Leftmost octets not zero as expected');
        }
        if (db.charCodeAt(checkLen) !== 1) throw new Error('Inconsistent PSS signature, 0x01 marker not found');
        /* 11. Let salt be the last sLen octets of DB. */ var salt = db.substr(-sLen);
        /* 12.  Let M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt */ var m_ = new forge.util.ByteBuffer();
        m_.fillWithByte(0, 8);
        m_.putBytes(mHash);
        m_.putBytes(salt);
        /* 13. Let H' = Hash(M'), an octet string of length hLen. */ hash.start();
        hash.update(m_.getBytes());
        var h_ = hash.digest().getBytes();
        /* 14. If H = H', output "consistent." Otherwise, output "inconsistent." */ return h === h_;
    };
    return pssobj;
};

},{"./forge":"7AnVp","./random":"7GrCn","./util":"cHj6b"}],"fMRaI":[function(require,module,exports) {
// @ts-nocheck
'use strict';
require('node-forge/lib/x509');
const forge = require('node-forge/lib/forge');
const pki = forge.pki;
/**
 * Gets a self-signed X.509 certificate for the key.
 *
 * The output Uint8Array contains the PKCS #7 message in DER.
 *
 * TODO: move to libp2p-crypto package
 *
 * @param {KeyInfo} key - The id and name of the key
 * @param {RsaPrivateKey} privateKey - The naked key
 * @returns {Uint8Array}
 */ const certificateForKey = (key, privateKey)=>{
    const publicKey = pki.setRsaPublicKey(privateKey.n, privateKey.e);
    const cert = pki.createCertificate();
    cert.publicKey = publicKey;
    cert.serialNumber = '01';
    cert.validity.notBefore = new Date();
    cert.validity.notAfter = new Date();
    cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 10);
    const attrs = [
        {
            name: 'organizationName',
            value: 'ipfs'
        },
        {
            shortName: 'OU',
            value: 'keystore'
        },
        {
            name: 'commonName',
            value: key.id
        }
    ];
    cert.setSubject(attrs);
    cert.setIssuer(attrs);
    cert.setExtensions([
        {
            name: 'basicConstraints',
            cA: true
        },
        {
            name: 'keyUsage',
            keyCertSign: true,
            digitalSignature: true,
            nonRepudiation: true,
            keyEncipherment: true,
            dataEncipherment: true
        },
        {
            name: 'extKeyUsage',
            serverAuth: true,
            clientAuth: true,
            codeSigning: true,
            emailProtection: true,
            timeStamping: true
        },
        {
            name: 'nsCertType',
            client: true,
            server: true,
            email: true,
            objsign: true,
            sslCA: true,
            emailCA: true,
            objCA: true
        }
    ]);
    // self-sign certificate
    cert.sign(privateKey);
    return cert;
};
/**
 * Finds the first item in a collection that is matched in the
 * `asyncCompare` function.
 *
 * `asyncCompare` is an async function that must
 * resolve to either `true` or `false`.
 *
 * @param {Array} array
 * @param {function(*)} asyncCompare - An async function that returns a boolean
 */ async function findAsync(array, asyncCompare) {
    const promises = array.map(asyncCompare);
    const results = await Promise.all(promises);
    const index = results.findIndex((result)=>result
    );
    return array[index];
}
module.exports = {
    certificateForKey,
    findAsync
};

},{"node-forge/lib/x509":"hEiGM","node-forge/lib/forge":"7AnVp"}],"iSisa":[function(require,module,exports) {
// @ts-nocheck
'use strict';
const mergeOptions = require('merge-options');
const { pipe  } = require('it-pipe');
const { tap  } = require('streaming-iterables');
const oldPeerLRU = require('./old-peers');
const { METRICS: defaultOptions  } = require('../constants');
const Stats = require('./stats');
const initialCounters = [
    'dataReceived',
    'dataSent'
];
const directionToEvent = {
    in: 'dataReceived',
    out: 'dataSent'
};
/**
 * @typedef {import('peer-id')} PeerId
 * @typedef {import('libp2p-interfaces/src/transport/types').MultiaddrConnection} MultiaddrConnection
 */ /**
 * @typedef MetricsProperties
 * @property {import('../connection-manager')} connectionManager
 *
 * @typedef MetricsOptions
 * @property {number} [computeThrottleMaxQueueSize = defaultOptions.computeThrottleMaxQueueSize]
 * @property {number} [computeThrottleTimeout = defaultOptions.computeThrottleTimeout]
 * @property {number[]} [movingAverageIntervals = defaultOptions.movingAverageIntervals]
 * @property {number} [maxOldPeersRetention = defaultOptions.maxOldPeersRetention]
 */ class Metrics {
    /**
   * @class
   * @param {MetricsProperties & MetricsOptions} options
   */ constructor(options){
        this._options = mergeOptions(defaultOptions, options);
        this._globalStats = new Stats(initialCounters, this._options);
        this._peerStats = new Map();
        this._protocolStats = new Map();
        this._oldPeers = oldPeerLRU(this._options.maxOldPeersRetention);
        this._running = false;
        this._onMessage = this._onMessage.bind(this);
        this._connectionManager = options.connectionManager;
        this._connectionManager.on('peer:disconnect', (connection)=>{
            this.onPeerDisconnected(connection.remotePeer);
        });
    }
    /**
   * Must be called for stats to saved. Any data pushed for tracking
   * will be ignored.
   */ start() {
        this._running = true;
    }
    /**
   * Stops all averages timers and prevents new data from being tracked.
   * Once `stop` is called, `start` must be called to resume stats tracking.
   */ stop() {
        this._running = false;
        this._globalStats.stop();
        for (const stats of this._peerStats.values())stats.stop();
        for (const stats1 of this._protocolStats.values())stats1.stop();
    }
    /**
   * Gets the global `Stats` object
   *
   * @returns {Stats}
   */ get global() {
        return this._globalStats;
    }
    /**
   * Returns a list of `PeerId` strings currently being tracked
   *
   * @returns {string[]}
   */ get peers() {
        return Array.from(this._peerStats.keys());
    }
    /**
   * Returns the `Stats` object for the given `PeerId` whether it
   * is a live peer, or in the disconnected peer LRU cache.
   *
   * @param {PeerId} peerId
   * @returns {Stats}
   */ forPeer(peerId) {
        const idString = peerId.toB58String();
        return this._peerStats.get(idString) || this._oldPeers.get(idString);
    }
    /**
   * Returns a list of all protocol strings currently being tracked.
   *
   * @returns {string[]}
   */ get protocols() {
        return Array.from(this._protocolStats.keys());
    }
    /**
   * Returns the `Stats` object for the given `protocol`.
   *
   * @param {string} protocol
   * @returns {Stats}
   */ forProtocol(protocol) {
        return this._protocolStats.get(protocol);
    }
    /**
   * Should be called when all connections to a given peer
   * have closed. The `Stats` collection for the peer will
   * be stopped and moved to an LRU for temporary retention.
   *
   * @param {PeerId} peerId
   */ onPeerDisconnected(peerId1) {
        const idString = peerId1.toB58String();
        const peerStats = this._peerStats.get(idString);
        if (peerStats) {
            peerStats.stop();
            this._peerStats.delete(idString);
            this._oldPeers.set(idString, peerStats);
        }
    }
    /**
   * Takes the metadata for a message and tracks it in the
   * appropriate categories. If the protocol is present, protocol
   * stats will also be tracked.
   *
   * @private
   * @param {object} params
   * @param {PeerId} params.remotePeer - Remote peer
   * @param {string} [params.protocol] - Protocol string the stream is running
   * @param {string} params.direction - One of ['in','out']
   * @param {number} params.dataLength - Size of the message
   * @returns {void}
   */ _onMessage({ remotePeer , protocol: protocol1 , direction , dataLength  }) {
        if (!this._running) return;
        const key = directionToEvent[direction];
        let peerStats = this.forPeer(remotePeer);
        if (!peerStats) {
            peerStats = new Stats(initialCounters, this._options);
            this._peerStats.set(remotePeer.toB58String(), peerStats);
        }
        // Peer and global stats
        peerStats.push(key, dataLength);
        this._globalStats.push(key, dataLength);
        // Protocol specific stats
        if (protocol1) {
            let protocolStats = this.forProtocol(protocol1);
            if (!protocolStats) {
                protocolStats = new Stats(initialCounters, this._options);
                this._protocolStats.set(protocol1, protocolStats);
            }
            protocolStats.push(key, dataLength);
        }
    }
    /**
   * Replaces the `PeerId` string with the given `peerId`.
   * If stats are already being tracked for the given `peerId`, the
   * placeholder stats will be merged with the existing stats.
   *
   * @param {PeerId} placeholder - A peerId string
   * @param {PeerId} peerId
   * @returns {void}
   */ updatePlaceholder(placeholder, peerId2) {
        if (!this._running) return;
        const placeholderStats = this.forPeer(placeholder);
        const peerIdString = peerId2.toB58String();
        const existingStats = this.forPeer(peerId2);
        let mergedStats = placeholderStats;
        // If we already have stats, merge the two
        if (existingStats) {
            // If existing, merge
            mergedStats = Metrics.mergeStats(existingStats, mergedStats);
            // Attempt to delete from the old peers list just in case it was tracked there
            this._oldPeers.delete(peerIdString);
        }
        this._peerStats.delete(placeholder.toB58String());
        this._peerStats.set(peerIdString, mergedStats);
        mergedStats.start();
    }
    /**
   * Tracks data running through a given Duplex Iterable `stream`. If
   * the `peerId` is not provided, a placeholder string will be created and
   * returned. This allows lazy tracking of a peer when the peer is not yet known.
   * When the `PeerId` is known, `Metrics.updatePlaceholder` should be called
   * with the placeholder string returned from here, and the known `PeerId`.
   *
   * @param {Object} options
   * @param {MultiaddrConnection} options.stream - A duplex iterable stream
   * @param {PeerId} [options.remotePeer] - The id of the remote peer that's connected
   * @param {string} [options.protocol] - The protocol the stream is running
   * @returns {MultiaddrConnection} The peerId string or placeholder string
   */ trackStream({ stream , remotePeer: remotePeer1 , protocol: protocol2  }) {
        const metrics = this;
        const _source = stream.source;
        stream.source = tap((chunk)=>metrics._onMessage({
                remotePeer: remotePeer1,
                protocol: protocol2,
                direction: 'in',
                dataLength: chunk.length
            })
        )(_source);
        const _sink = stream.sink;
        stream.sink = (source)=>{
            return pipe(source, tap((chunk)=>metrics._onMessage({
                    remotePeer: remotePeer1,
                    protocol: protocol2,
                    direction: 'out',
                    dataLength: chunk.length
                })
            ), _sink);
        };
        return stream;
    }
    /**
   * Merges `other` into `target`. `target` will be modified
   * and returned.
   *
   * @param {Stats} target
   * @param {Stats} other
   * @returns {Stats}
   */ static mergeStats(target, other) {
        target.stop();
        other.stop();
        // Merge queues
        target._queue = [
            ...target._queue,
            ...other._queue
        ];
        // TODO: how to merge moving averages?
        return target;
    }
}
module.exports = Metrics;

},{"merge-options":"8VjFj","it-pipe":"4jukm","streaming-iterables":"9JcGF","./old-peers":"bf8S6","../constants":"7AgPB","./stats":"cDA5H"}],"bf8S6":[function(require,module,exports) {
'use strict';
const LRU = require('hashlru');
/**
 * Creates and returns a Least Recently Used Cache
 *
 * @param {number} maxSize
 * @returns {any}
 */ module.exports = (maxSize)=>{
    // @ts-ignore LRU expression is not callable
    const patched = LRU(maxSize);
    patched.delete = patched.remove;
    return patched;
};

},{"hashlru":"fzwAb"}],"cDA5H":[function(require,module,exports) {
// @ts-nocheck
'use strict';
const { EventEmitter  } = require('events');
const { BigNumber: Big  } = require('bignumber.js');
const MovingAverage = require('@vascosantos/moving-average');
const retimer = require('retimer');
/**
 * @typedef {import('@vascosantos/moving-average').IMovingAverage} IMovingAverage
 */ class Stats extends EventEmitter {
    /**
   * A queue based manager for stat processing
   *
   * @class
   * @param {string[]} initialCounters
   * @param {any} options
   */ constructor(initialCounters, options){
        super();
        this._options = options;
        this._queue = [];
        /** @type {{ dataReceived: Big, dataSent: Big }} */ this._stats = {
            dataReceived: Big(0),
            dataSent: Big(0)
        };
        this._frequencyLastTime = Date.now();
        this._frequencyAccumulators = {
        };
        /** @type {{ dataReceived: IMovingAverage[], dataSent: IMovingAverage[] }} */ this._movingAverages = {
        };
        this._update = this._update.bind(this);
        const intervals = this._options.movingAverageIntervals;
        for(let i = 0; i < initialCounters.length; i++){
            const key = initialCounters[i];
            this._stats[key] = Big(0);
            this._movingAverages[key] = {
            };
            for(let k = 0; k < intervals.length; k++){
                const interval = intervals[k];
                const ma = this._movingAverages[key][interval] = MovingAverage(interval);
                ma.push(this._frequencyLastTime, 0);
            }
        }
    }
    /**
   * Initializes the internal timer if there are items in the queue. This
   * should only need to be called if `Stats.stop` was previously called, as
   * `Stats.push` will also start the processing.
   *
   * @returns {void}
   */ start() {
        if (this._queue.length) this._resetComputeTimeout();
    }
    /**
   * Stops processing and computing of stats by clearing the internal
   * timer.
   *
   * @returns {void}
   */ stop() {
        if (this._timeout) {
            this._timeout.clear();
            this._timeout = null;
        }
    }
    /**
   * Returns a clone of the current stats.
   */ get snapshot() {
        return Object.assign({
        }, this._stats);
    }
    /**
   * Returns a clone of the internal movingAverages
   */ get movingAverages() {
        return Object.assign({
        }, this._movingAverages);
    }
    /**
   * Returns a plain JSON object of the stats
   *
   * @returns {*}
   */ toJSON() {
        const snapshot = this.snapshot;
        const movingAverages = this.movingAverages;
        const data = {
            dataReceived: snapshot.dataReceived.toString(),
            dataSent: snapshot.dataSent.toString(),
            movingAverages: {
            }
        };
        const counters = Object.keys(movingAverages);
        for (const key of counters){
            data.movingAverages[key] = {
            };
            for (const interval of Object.keys(movingAverages[key]))data.movingAverages[key][interval] = movingAverages[key][interval].movingAverage();
        }
        return data;
    }
    /**
   * Pushes the given operation data to the queue, along with the
   * current Timestamp, then resets the update timer.
   *
   * @param {string} counter
   * @param {number} inc
   * @returns {void}
   */ push(counter, inc) {
        this._queue.push([
            counter,
            inc,
            Date.now()
        ]);
        this._resetComputeTimeout();
    }
    /**
   * Resets the timeout for triggering updates.
   *
   * @private
   * @returns {void}
   */ _resetComputeTimeout() {
        this._timeout = retimer(this._update, this._nextTimeout());
    }
    /**
   * Calculates and returns the timeout for the next update based on
   * the urgency of the update.
   *
   * @private
   * @returns {number}
   */ _nextTimeout() {
        // calculate the need for an update, depending on the queue length
        const urgency = this._queue.length / this._options.computeThrottleMaxQueueSize;
        const timeout = Math.max(this._options.computeThrottleTimeout * (1 - urgency), 0);
        return timeout;
    }
    /**
   * If there are items in the queue, they will will be processed and
   * the frequency for all items will be updated based on the Timestamp
   * of the last item in the queue. The `update` event will also be emitted
   * with the latest stats.
   *
   * If there are no items in the queue, no action is taken.
   *
   * @private
   * @returns {void}
   */ _update() {
        this._timeout = null;
        if (this._queue.length) {
            let last;
            for (last of this._queue)this._applyOp(last);
            this._queue = [];
            this._updateFrequency(last[2]) // contains timestamp of last op
            ;
            this.emit('update', this._stats);
        }
    }
    /**
   * For each key in the stats, the frequency and moving averages
   * will be updated via Stats._updateFrequencyFor based on the time
   * difference between calls to this method.
   *
   * @private
   * @param {Timestamp} latestTime
   * @returns {void}
   */ _updateFrequency(latestTime) {
        const timeDiff = latestTime - this._frequencyLastTime;
        Object.keys(this._stats).forEach((key)=>{
            this._updateFrequencyFor(key, timeDiff, latestTime);
        });
        this._frequencyLastTime = latestTime;
    }
    /**
   * Updates the `movingAverages` for the given `key` and also
   * resets the `frequencyAccumulator` for the `key`.
   *
   * @private
   * @param {string} key
   * @param {number} timeDiffMS - Time in milliseconds
   * @param {Timestamp} latestTime - Time in ticks
   * @returns {void}
   */ _updateFrequencyFor(key, timeDiffMS, latestTime1) {
        const count = this._frequencyAccumulators[key] || 0;
        this._frequencyAccumulators[key] = 0;
        // if `timeDiff` is zero, `hz` becomes Infinity, so we fallback to 1ms
        const safeTimeDiff = timeDiffMS || 1;
        const hz = count / safeTimeDiff * 1000;
        let movingAverages = this._movingAverages[key];
        if (!movingAverages) movingAverages = this._movingAverages[key] = {
        };
        const intervals = this._options.movingAverageIntervals;
        for(let i = 0; i < intervals.length; i++){
            const movingAverageInterval = intervals[i];
            let movingAverage = movingAverages[movingAverageInterval];
            if (!movingAverage) movingAverage = movingAverages[movingAverageInterval] = MovingAverage(movingAverageInterval);
            movingAverage.push(latestTime1, hz);
        }
    }
    /**
   * For the given operation, `op`, the stats and `frequencyAccumulator`
   * will be updated or initialized if they don't already exist.
   *
   * @private
   * @param {{string, number}[]} op
   * @throws {InvalidNumber}
   * @returns {void}
   */ _applyOp(op) {
        const key = op[0];
        const inc = op[1];
        if (typeof inc !== 'number') throw new Error(`invalid increment number: ${inc}`);
        let n;
        if (!Object.prototype.hasOwnProperty.call(this._stats, key)) n = this._stats[key] = Big(0);
        else n = this._stats[key];
        this._stats[key] = n.plus(inc);
        if (!this._frequencyAccumulators[key]) this._frequencyAccumulators[key] = 0;
        this._frequencyAccumulators[key] += inc;
    }
}
module.exports = Stats;

},{"events":"bHM3D","bignumber.js":"hOjlt","@vascosantos/moving-average":"fQFY3","retimer":"kYXdk"}],"hOjlt":[function(require,module,exports) {
(function(globalObject) {
    /*
 *      bignumber.js v9.0.1
 *      A JavaScript library for arbitrary-precision arithmetic.
 *      https://github.com/MikeMcl/bignumber.js
 *      Copyright (c) 2020 Michael Mclaughlin <M8ch88l@gmail.com>
 *      MIT Licensed.
 *
 *      BigNumber.prototype methods     |  BigNumber methods
 *                                      |
 *      absoluteValue            abs    |  clone
 *      comparedTo                      |  config               set
 *      decimalPlaces            dp     |      DECIMAL_PLACES
 *      dividedBy                div    |      ROUNDING_MODE
 *      dividedToIntegerBy       idiv   |      EXPONENTIAL_AT
 *      exponentiatedBy          pow    |      RANGE
 *      integerValue                    |      CRYPTO
 *      isEqualTo                eq     |      MODULO_MODE
 *      isFinite                        |      POW_PRECISION
 *      isGreaterThan            gt     |      FORMAT
 *      isGreaterThanOrEqualTo   gte    |      ALPHABET
 *      isInteger                       |  isBigNumber
 *      isLessThan               lt     |  maximum              max
 *      isLessThanOrEqualTo      lte    |  minimum              min
 *      isNaN                           |  random
 *      isNegative                      |  sum
 *      isPositive                      |
 *      isZero                          |
 *      minus                           |
 *      modulo                   mod    |
 *      multipliedBy             times  |
 *      negated                         |
 *      plus                            |
 *      precision                sd     |
 *      shiftedBy                       |
 *      squareRoot               sqrt   |
 *      toExponential                   |
 *      toFixed                         |
 *      toFormat                        |
 *      toFraction                      |
 *      toJSON                          |
 *      toNumber                        |
 *      toPrecision                     |
 *      toString                        |
 *      valueOf                         |
 *
 */ var BigNumber1, isNumeric = /^-?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/i, mathceil = Math.ceil, mathfloor = Math.floor, bignumberError = '[BigNumber Error] ', tooManyDigits = bignumberError + 'Number primitive has more than 15 significant digits: ', BASE = 100000000000000, LOG_BASE = 14, MAX_SAFE_INTEGER = 9007199254740991, // MAX_INT32 = 0x7fffffff,                   // 2^31 - 1
    POWS_TEN = [
        1,
        10,
        100,
        1000,
        10000,
        100000,
        1000000,
        10000000,
        100000000,
        1000000000,
        10000000000,
        100000000000,
        1000000000000,
        10000000000000
    ], SQRT_BASE = 10000000, // EDITABLE
    // The limit on the value of DECIMAL_PLACES, TO_EXP_NEG, TO_EXP_POS, MIN_EXP, MAX_EXP, and
    // the arguments to toExponential, toFixed, toFormat, and toPrecision.
    MAX = 1000000000; // 0 to MAX_INT32
    /*
   * Create and return a BigNumber constructor.
   */ function clone(configObject) {
        var div, convertBase, parseNumeric, P = BigNumber.prototype = {
            constructor: BigNumber,
            toString: null,
            valueOf: null
        }, ONE = new BigNumber(1), //----------------------------- EDITABLE CONFIG DEFAULTS -------------------------------
        // The default values below must be integers within the inclusive ranges stated.
        // The values can also be changed at run-time using BigNumber.set.
        // The maximum number of decimal places for operations involving division.
        DECIMAL_PLACES = 20, // The rounding mode used when rounding to the above decimal places, and when using
        // toExponential, toFixed, toFormat and toPrecision, and round (default value).
        // UP         0 Away from zero.
        // DOWN       1 Towards zero.
        // CEIL       2 Towards +Infinity.
        // FLOOR      3 Towards -Infinity.
        // HALF_UP    4 Towards nearest neighbour. If equidistant, up.
        // HALF_DOWN  5 Towards nearest neighbour. If equidistant, down.
        // HALF_EVEN  6 Towards nearest neighbour. If equidistant, towards even neighbour.
        // HALF_CEIL  7 Towards nearest neighbour. If equidistant, towards +Infinity.
        // HALF_FLOOR 8 Towards nearest neighbour. If equidistant, towards -Infinity.
        ROUNDING_MODE = 4, // EXPONENTIAL_AT : [TO_EXP_NEG , TO_EXP_POS]
        // The exponent value at and beneath which toString returns exponential notation.
        // Number type: -7
        TO_EXP_NEG = -7, // The exponent value at and above which toString returns exponential notation.
        // Number type: 21
        TO_EXP_POS = 21, // RANGE : [MIN_EXP, MAX_EXP]
        // The minimum exponent value, beneath which underflow to zero occurs.
        // Number type: -324  (5e-324)
        MIN_EXP = -10000000, // The maximum exponent value, above which overflow to Infinity occurs.
        // Number type:  308  (1.7976931348623157e+308)
        // For MAX_EXP > 1e7, e.g. new BigNumber('1e100000000').plus(1) may be slow.
        MAX_EXP = 10000000, // Whether to use cryptographically-secure random number generation, if available.
        CRYPTO = false, // The modulo mode used when calculating the modulus: a mod n.
        // The quotient (q = a / n) is calculated according to the corresponding rounding mode.
        // The remainder (r) is calculated as: r = a - n * q.
        //
        // UP        0 The remainder is positive if the dividend is negative, else is negative.
        // DOWN      1 The remainder has the same sign as the dividend.
        //             This modulo mode is commonly known as 'truncated division' and is
        //             equivalent to (a % n) in JavaScript.
        // FLOOR     3 The remainder has the same sign as the divisor (Python %).
        // HALF_EVEN 6 This modulo mode implements the IEEE 754 remainder function.
        // EUCLID    9 Euclidian division. q = sign(n) * floor(a / abs(n)).
        //             The remainder is always positive.
        //
        // The truncated division, floored division, Euclidian division and IEEE 754 remainder
        // modes are commonly used for the modulus operation.
        // Although the other rounding modes can also be used, they may not give useful results.
        MODULO_MODE = 1, // The maximum number of significant digits of the result of the exponentiatedBy operation.
        // If POW_PRECISION is 0, there will be unlimited significant digits.
        POW_PRECISION = 0, // The format specification used by the BigNumber.prototype.toFormat method.
        FORMAT = {
            prefix: '',
            groupSize: 3,
            secondaryGroupSize: 0,
            groupSeparator: ',',
            decimalSeparator: '.',
            fractionGroupSize: 0,
            fractionGroupSeparator: '\xA0',
            suffix: ''
        }, // The alphabet used for base conversion. It must be at least 2 characters long, with no '+',
        // '-', '.', whitespace, or repeated character.
        // '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_'
        ALPHABET = '0123456789abcdefghijklmnopqrstuvwxyz';
        //------------------------------------------------------------------------------------------
        // CONSTRUCTOR
        /*
     * The BigNumber constructor and exported function.
     * Create and return a new instance of a BigNumber object.
     *
     * v {number|string|BigNumber} A numeric value.
     * [b] {number} The base of v. Integer, 2 to ALPHABET.length inclusive.
     */ function BigNumber(v, b) {
            var alphabet, c, caseChanged, e, i, isNum, len, str, x = this;
            // Enable constructor call without `new`.
            if (!(x instanceof BigNumber)) return new BigNumber(v, b);
            if (b == null) {
                if (v && v._isBigNumber === true) {
                    x.s = v.s;
                    if (!v.c || v.e > MAX_EXP) x.c = x.e = null;
                    else if (v.e < MIN_EXP) x.c = [
                        x.e = 0
                    ];
                    else {
                        x.e = v.e;
                        x.c = v.c.slice();
                    }
                    return;
                }
                if ((isNum = typeof v == 'number') && v * 0 == 0) {
                    // Use `1 / n` to handle minus zero also.
                    x.s = 1 / v < 0 ? (v = -v, -1) : 1;
                    // Fast path for integers, where n < 2147483648 (2**31).
                    if (v === ~~v) {
                        for(e = 0, i = v; i >= 10; i /= 10, e++);
                        if (e > MAX_EXP) x.c = x.e = null;
                        else {
                            x.e = e;
                            x.c = [
                                v
                            ];
                        }
                        return;
                    }
                    str = String(v);
                } else {
                    if (!isNumeric.test(str = String(v))) return parseNumeric(x, str, isNum);
                    x.s = str.charCodeAt(0) == 45 ? (str = str.slice(1), -1) : 1;
                }
                // Decimal point?
                if ((e = str.indexOf('.')) > -1) str = str.replace('.', '');
                // Exponential form?
                if ((i = str.search(/e/i)) > 0) {
                    // Determine exponent.
                    if (e < 0) e = i;
                    e += +str.slice(i + 1);
                    str = str.substring(0, i);
                } else if (e < 0) // Integer.
                e = str.length;
            } else {
                // '[BigNumber Error] Base {not a primitive number|not an integer|out of range}: {b}'
                intCheck(b, 2, ALPHABET.length, 'Base');
                // Allow exponential notation to be used with base 10 argument, while
                // also rounding to DECIMAL_PLACES as with other bases.
                if (b == 10) {
                    x = new BigNumber(v);
                    return round(x, DECIMAL_PLACES + x.e + 1, ROUNDING_MODE);
                }
                str = String(v);
                if (isNum = typeof v == 'number') {
                    // Avoid potential interpretation of Infinity and NaN as base 44+ values.
                    if (v * 0 != 0) return parseNumeric(x, str, isNum, b);
                    x.s = 1 / v < 0 ? (str = str.slice(1), -1) : 1;
                    // '[BigNumber Error] Number primitive has more than 15 significant digits: {n}'
                    if (BigNumber.DEBUG && str.replace(/^0\.0*|\./, '').length > 15) throw Error(tooManyDigits + v);
                } else x.s = str.charCodeAt(0) === 45 ? (str = str.slice(1), -1) : 1;
                alphabet = ALPHABET.slice(0, b);
                e = i = 0;
                // Check that str is a valid base b number.
                // Don't use RegExp, so alphabet can contain special characters.
                for(len = str.length; i < len; i++)if (alphabet.indexOf(c = str.charAt(i)) < 0) {
                    if (c == '.') // If '.' is not the first character and it has not be found before.
                    {
                        if (i > e) {
                            e = len;
                            continue;
                        }
                    } else if (!caseChanged) // Allow e.g. hexadecimal 'FF' as well as 'ff'.
                    {
                        if (str == str.toUpperCase() && (str = str.toLowerCase()) || str == str.toLowerCase() && (str = str.toUpperCase())) {
                            caseChanged = true;
                            i = -1;
                            e = 0;
                            continue;
                        }
                    }
                    return parseNumeric(x, String(v), isNum, b);
                }
                // Prevent later check for length on converted number.
                isNum = false;
                str = convertBase(str, b, 10, x.s);
                // Decimal point?
                if ((e = str.indexOf('.')) > -1) str = str.replace('.', '');
                else e = str.length;
            }
            // Determine leading zeros.
            for(i = 0; str.charCodeAt(i) === 48; i++);
            // Determine trailing zeros.
            for(len = str.length; str.charCodeAt(--len) === 48;);
            if (str = str.slice(i, ++len)) {
                len -= i;
                // '[BigNumber Error] Number primitive has more than 15 significant digits: {n}'
                if (isNum && BigNumber.DEBUG && len > 15 && (v > MAX_SAFE_INTEGER || v !== mathfloor(v))) throw Error(tooManyDigits + x.s * v);
                // Overflow?
                if ((e = e - i - 1) > MAX_EXP) // Infinity.
                x.c = x.e = null;
                else if (e < MIN_EXP) // Zero.
                x.c = [
                    x.e = 0
                ];
                else {
                    x.e = e;
                    x.c = [];
                    // Transform base
                    // e is the base 10 exponent.
                    // i is where to slice str to get the first element of the coefficient array.
                    i = (e + 1) % LOG_BASE;
                    if (e < 0) i += LOG_BASE; // i < 1
                    if (i < len) {
                        if (i) x.c.push(+str.slice(0, i));
                        for(len -= LOG_BASE; i < len;)x.c.push(+str.slice(i, i += LOG_BASE));
                        i = LOG_BASE - (str = str.slice(i)).length;
                    } else i -= len;
                    for(; i--; str += '0');
                    x.c.push(+str);
                }
            } else // Zero.
            x.c = [
                x.e = 0
            ];
        }
        // CONSTRUCTOR PROPERTIES
        BigNumber.clone = clone;
        BigNumber.ROUND_UP = 0;
        BigNumber.ROUND_DOWN = 1;
        BigNumber.ROUND_CEIL = 2;
        BigNumber.ROUND_FLOOR = 3;
        BigNumber.ROUND_HALF_UP = 4;
        BigNumber.ROUND_HALF_DOWN = 5;
        BigNumber.ROUND_HALF_EVEN = 6;
        BigNumber.ROUND_HALF_CEIL = 7;
        BigNumber.ROUND_HALF_FLOOR = 8;
        BigNumber.EUCLID = 9;
        /*
     * Configure infrequently-changing library-wide settings.
     *
     * Accept an object with the following optional properties (if the value of a property is
     * a number, it must be an integer within the inclusive range stated):
     *
     *   DECIMAL_PLACES   {number}           0 to MAX
     *   ROUNDING_MODE    {number}           0 to 8
     *   EXPONENTIAL_AT   {number|number[]}  -MAX to MAX  or  [-MAX to 0, 0 to MAX]
     *   RANGE            {number|number[]}  -MAX to MAX (not zero)  or  [-MAX to -1, 1 to MAX]
     *   CRYPTO           {boolean}          true or false
     *   MODULO_MODE      {number}           0 to 9
     *   POW_PRECISION       {number}           0 to MAX
     *   ALPHABET         {string}           A string of two or more unique characters which does
     *                                       not contain '.'.
     *   FORMAT           {object}           An object with some of the following properties:
     *     prefix                 {string}
     *     groupSize              {number}
     *     secondaryGroupSize     {number}
     *     groupSeparator         {string}
     *     decimalSeparator       {string}
     *     fractionGroupSize      {number}
     *     fractionGroupSeparator {string}
     *     suffix                 {string}
     *
     * (The values assigned to the above FORMAT object properties are not checked for validity.)
     *
     * E.g.
     * BigNumber.config({ DECIMAL_PLACES : 20, ROUNDING_MODE : 4 })
     *
     * Ignore properties/parameters set to null or undefined, except for ALPHABET.
     *
     * Return an object with the properties current values.
     */ BigNumber.config = BigNumber.set = function(obj) {
            var p, v;
            if (obj != null) {
                if (typeof obj == 'object') {
                    // DECIMAL_PLACES {number} Integer, 0 to MAX inclusive.
                    // '[BigNumber Error] DECIMAL_PLACES {not a primitive number|not an integer|out of range}: {v}'
                    if (obj.hasOwnProperty(p = 'DECIMAL_PLACES')) {
                        v = obj[p];
                        intCheck(v, 0, MAX, p);
                        DECIMAL_PLACES = v;
                    }
                    // ROUNDING_MODE {number} Integer, 0 to 8 inclusive.
                    // '[BigNumber Error] ROUNDING_MODE {not a primitive number|not an integer|out of range}: {v}'
                    if (obj.hasOwnProperty(p = 'ROUNDING_MODE')) {
                        v = obj[p];
                        intCheck(v, 0, 8, p);
                        ROUNDING_MODE = v;
                    }
                    // EXPONENTIAL_AT {number|number[]}
                    // Integer, -MAX to MAX inclusive or
                    // [integer -MAX to 0 inclusive, 0 to MAX inclusive].
                    // '[BigNumber Error] EXPONENTIAL_AT {not a primitive number|not an integer|out of range}: {v}'
                    if (obj.hasOwnProperty(p = 'EXPONENTIAL_AT')) {
                        v = obj[p];
                        if (v && v.pop) {
                            intCheck(v[0], -MAX, 0, p);
                            intCheck(v[1], 0, MAX, p);
                            TO_EXP_NEG = v[0];
                            TO_EXP_POS = v[1];
                        } else {
                            intCheck(v, -MAX, MAX, p);
                            TO_EXP_NEG = -(TO_EXP_POS = v < 0 ? -v : v);
                        }
                    }
                    // RANGE {number|number[]} Non-zero integer, -MAX to MAX inclusive or
                    // [integer -MAX to -1 inclusive, integer 1 to MAX inclusive].
                    // '[BigNumber Error] RANGE {not a primitive number|not an integer|out of range|cannot be zero}: {v}'
                    if (obj.hasOwnProperty(p = 'RANGE')) {
                        v = obj[p];
                        if (v && v.pop) {
                            intCheck(v[0], -MAX, -1, p);
                            intCheck(v[1], 1, MAX, p);
                            MIN_EXP = v[0];
                            MAX_EXP = v[1];
                        } else {
                            intCheck(v, -MAX, MAX, p);
                            if (v) MIN_EXP = -(MAX_EXP = v < 0 ? -v : v);
                            else throw Error(bignumberError + p + ' cannot be zero: ' + v);
                        }
                    }
                    // CRYPTO {boolean} true or false.
                    // '[BigNumber Error] CRYPTO not true or false: {v}'
                    // '[BigNumber Error] crypto unavailable'
                    if (obj.hasOwnProperty(p = 'CRYPTO')) {
                        v = obj[p];
                        if (v === !!v) {
                            if (v) {
                                if (typeof crypto != 'undefined' && crypto && (crypto.getRandomValues || crypto.randomBytes)) CRYPTO = v;
                                else {
                                    CRYPTO = !v;
                                    throw Error(bignumberError + 'crypto unavailable');
                                }
                            } else CRYPTO = v;
                        } else throw Error(bignumberError + p + ' not true or false: ' + v);
                    }
                    // MODULO_MODE {number} Integer, 0 to 9 inclusive.
                    // '[BigNumber Error] MODULO_MODE {not a primitive number|not an integer|out of range}: {v}'
                    if (obj.hasOwnProperty(p = 'MODULO_MODE')) {
                        v = obj[p];
                        intCheck(v, 0, 9, p);
                        MODULO_MODE = v;
                    }
                    // POW_PRECISION {number} Integer, 0 to MAX inclusive.
                    // '[BigNumber Error] POW_PRECISION {not a primitive number|not an integer|out of range}: {v}'
                    if (obj.hasOwnProperty(p = 'POW_PRECISION')) {
                        v = obj[p];
                        intCheck(v, 0, MAX, p);
                        POW_PRECISION = v;
                    }
                    // FORMAT {object}
                    // '[BigNumber Error] FORMAT not an object: {v}'
                    if (obj.hasOwnProperty(p = 'FORMAT')) {
                        v = obj[p];
                        if (typeof v == 'object') FORMAT = v;
                        else throw Error(bignumberError + p + ' not an object: ' + v);
                    }
                    // ALPHABET {string}
                    // '[BigNumber Error] ALPHABET invalid: {v}'
                    if (obj.hasOwnProperty(p = 'ALPHABET')) {
                        v = obj[p];
                        // Disallow if less than two characters,
                        // or if it contains '+', '-', '.', whitespace, or a repeated character.
                        if (typeof v == 'string' && !/^.?$|[+\-.\s]|(.).*\1/.test(v)) ALPHABET = v;
                        else throw Error(bignumberError + p + ' invalid: ' + v);
                    }
                } else // '[BigNumber Error] Object expected: {v}'
                throw Error(bignumberError + 'Object expected: ' + obj);
            }
            return {
                DECIMAL_PLACES: DECIMAL_PLACES,
                ROUNDING_MODE: ROUNDING_MODE,
                EXPONENTIAL_AT: [
                    TO_EXP_NEG,
                    TO_EXP_POS
                ],
                RANGE: [
                    MIN_EXP,
                    MAX_EXP
                ],
                CRYPTO: CRYPTO,
                MODULO_MODE: MODULO_MODE,
                POW_PRECISION: POW_PRECISION,
                FORMAT: FORMAT,
                ALPHABET: ALPHABET
            };
        };
        /*
     * Return true if v is a BigNumber instance, otherwise return false.
     *
     * If BigNumber.DEBUG is true, throw if a BigNumber instance is not well-formed.
     *
     * v {any}
     *
     * '[BigNumber Error] Invalid BigNumber: {v}'
     */ BigNumber.isBigNumber = function(v) {
            if (!v || v._isBigNumber !== true) return false;
            if (!BigNumber.DEBUG) return true;
            var i, n, c = v.c, e = v.e, s = v.s;
            out: if (({
            }).toString.call(c) == '[object Array]') {
                if ((s === 1 || s === -1) && e >= -MAX && e <= MAX && e === mathfloor(e)) {
                    // If the first element is zero, the BigNumber value must be zero.
                    if (c[0] === 0) {
                        if (e === 0 && c.length === 1) return true;
                        break out;
                    }
                    // Calculate number of digits that c[0] should have, based on the exponent.
                    i = (e + 1) % LOG_BASE;
                    if (i < 1) i += LOG_BASE;
                    // Calculate number of digits of c[0].
                    //if (Math.ceil(Math.log(c[0] + 1) / Math.LN10) == i) {
                    if (String(c[0]).length == i) {
                        for(i = 0; i < c.length; i++){
                            n = c[i];
                            if (n < 0 || n >= BASE || n !== mathfloor(n)) break out;
                        }
                        // Last element cannot be zero, unless it is the only element.
                        if (n !== 0) return true;
                    }
                }
            } else if (c === null && e === null && (s === null || s === 1 || s === -1)) return true;
            throw Error(bignumberError + 'Invalid BigNumber: ' + v);
        };
        /*
     * Return a new BigNumber whose value is the maximum of the arguments.
     *
     * arguments {number|string|BigNumber}
     */ BigNumber.maximum = BigNumber.max = function() {
            return maxOrMin(arguments, P.lt);
        };
        /*
     * Return a new BigNumber whose value is the minimum of the arguments.
     *
     * arguments {number|string|BigNumber}
     */ BigNumber.minimum = BigNumber.min = function() {
            return maxOrMin(arguments, P.gt);
        };
        /*
     * Return a new BigNumber with a random value equal to or greater than 0 and less than 1,
     * and with dp, or DECIMAL_PLACES if dp is omitted, decimal places (or less if trailing
     * zeros are produced).
     *
     * [dp] {number} Decimal places. Integer, 0 to MAX inclusive.
     *
     * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {dp}'
     * '[BigNumber Error] crypto unavailable'
     */ BigNumber.random = (function() {
            var pow2_53 = 9007199254740992;
            // Return a 53 bit integer n, where 0 <= n < 9007199254740992.
            // Check if Math.random() produces more than 32 bits of randomness.
            // If it does, assume at least 53 bits are produced, otherwise assume at least 30 bits.
            // 0x40000000 is 2^30, 0x800000 is 2^23, 0x1fffff is 2^21 - 1.
            var random53bitInt = Math.random() * pow2_53 & 2097151 ? function() {
                return mathfloor(Math.random() * pow2_53);
            } : function() {
                return (Math.random() * 1073741824 | 0) * 8388608 + (Math.random() * 8388608 | 0);
            };
            return function(dp) {
                var a, b, e, k, v, i = 0, c = [], rand = new BigNumber(ONE);
                if (dp == null) dp = DECIMAL_PLACES;
                else intCheck(dp, 0, MAX);
                k = mathceil(dp / LOG_BASE);
                if (CRYPTO) {
                    // Browsers supporting crypto.getRandomValues.
                    if (crypto.getRandomValues) {
                        a = crypto.getRandomValues(new Uint32Array(k *= 2));
                        for(; i < k;){
                            // 53 bits:
                            // ((Math.pow(2, 32) - 1) * Math.pow(2, 21)).toString(2)
                            // 11111 11111111 11111111 11111111 11100000 00000000 00000000
                            // ((Math.pow(2, 32) - 1) >>> 11).toString(2)
                            //                                     11111 11111111 11111111
                            // 0x20000 is 2^21.
                            v = a[i] * 131072 + (a[i + 1] >>> 11);
                            // Rejection sampling:
                            // 0 <= v < 9007199254740992
                            // Probability that v >= 9e15, is
                            // 7199254740992 / 9007199254740992 ~= 0.0008, i.e. 1 in 1251
                            if (v >= 9000000000000000) {
                                b = crypto.getRandomValues(new Uint32Array(2));
                                a[i] = b[0];
                                a[i + 1] = b[1];
                            } else {
                                // 0 <= v <= 8999999999999999
                                // 0 <= (v % 1e14) <= 99999999999999
                                c.push(v % 100000000000000);
                                i += 2;
                            }
                        }
                        i = k / 2;
                    // Node.js supporting crypto.randomBytes.
                    } else if (crypto.randomBytes) {
                        // buffer
                        a = crypto.randomBytes(k *= 7);
                        for(; i < k;){
                            // 0x1000000000000 is 2^48, 0x10000000000 is 2^40
                            // 0x100000000 is 2^32, 0x1000000 is 2^24
                            // 11111 11111111 11111111 11111111 11111111 11111111 11111111
                            // 0 <= v < 9007199254740992
                            v = (a[i] & 31) * 281474976710656 + a[i + 1] * 1099511627776 + a[i + 2] * 4294967296 + a[i + 3] * 16777216 + (a[i + 4] << 16) + (a[i + 5] << 8) + a[i + 6];
                            if (v >= 9000000000000000) crypto.randomBytes(7).copy(a, i);
                            else {
                                // 0 <= (v % 1e14) <= 99999999999999
                                c.push(v % 100000000000000);
                                i += 7;
                            }
                        }
                        i = k / 7;
                    } else {
                        CRYPTO = false;
                        throw Error(bignumberError + 'crypto unavailable');
                    }
                }
                // Use Math.random.
                if (!CRYPTO) for(; i < k;){
                    v = random53bitInt();
                    if (v < 9000000000000000) c[i++] = v % 100000000000000;
                }
                k = c[--i];
                dp %= LOG_BASE;
                // Convert trailing digits to zeros according to dp.
                if (k && dp) {
                    v = POWS_TEN[LOG_BASE - dp];
                    c[i] = mathfloor(k / v) * v;
                }
                // Remove trailing elements which are zero.
                for(; c[i] === 0; c.pop(), i--);
                // Zero?
                if (i < 0) c = [
                    e = 0
                ];
                else {
                    // Remove leading elements which are zero and adjust exponent accordingly.
                    for(e = -1; c[0] === 0; c.splice(0, 1), e -= LOG_BASE);
                    // Count the digits of the first element of c to determine leading zeros, and...
                    for(i = 1, v = c[0]; v >= 10; v /= 10, i++);
                    // adjust the exponent accordingly.
                    if (i < LOG_BASE) e -= LOG_BASE - i;
                }
                rand.e = e;
                rand.c = c;
                return rand;
            };
        })();
        /*
     * Return a BigNumber whose value is the sum of the arguments.
     *
     * arguments {number|string|BigNumber}
     */ BigNumber.sum = function() {
            var i = 1, args = arguments, sum = new BigNumber(args[0]);
            for(; i < args.length;)sum = sum.plus(args[i++]);
            return sum;
        };
        // PRIVATE FUNCTIONS
        // Called by BigNumber and BigNumber.prototype.toString.
        convertBase = (function() {
            var decimal = '0123456789';
            /*
       * Convert string of baseIn to an array of numbers of baseOut.
       * Eg. toBaseOut('255', 10, 16) returns [15, 15].
       * Eg. toBaseOut('ff', 16, 10) returns [2, 5, 5].
       */ function toBaseOut(str, baseIn, baseOut, alphabet) {
                var j, arr = [
                    0
                ], arrL, i = 0, len = str.length;
                for(; i < len;){
                    for(arrL = arr.length; arrL--; arr[arrL] *= baseIn);
                    arr[0] += alphabet.indexOf(str.charAt(i++));
                    for(j = 0; j < arr.length; j++)if (arr[j] > baseOut - 1) {
                        if (arr[j + 1] == null) arr[j + 1] = 0;
                        arr[j + 1] += arr[j] / baseOut | 0;
                        arr[j] %= baseOut;
                    }
                }
                return arr.reverse();
            }
            // Convert a numeric string of baseIn to a numeric string of baseOut.
            // If the caller is toString, we are converting from base 10 to baseOut.
            // If the caller is BigNumber, we are converting from baseIn to base 10.
            return function(str, baseIn, baseOut, sign, callerIsToString) {
                var alphabet, d, e, k, r, x, xc, y, i = str.indexOf('.'), dp = DECIMAL_PLACES, rm = ROUNDING_MODE;
                // Non-integer.
                if (i >= 0) {
                    k = POW_PRECISION;
                    // Unlimited precision.
                    POW_PRECISION = 0;
                    str = str.replace('.', '');
                    y = new BigNumber(baseIn);
                    x = y.pow(str.length - i);
                    POW_PRECISION = k;
                    // Convert str as if an integer, then restore the fraction part by dividing the
                    // result by its base raised to a power.
                    y.c = toBaseOut(toFixedPoint(coeffToString(x.c), x.e, '0'), 10, baseOut, decimal);
                    y.e = y.c.length;
                }
                // Convert the number as integer.
                xc = toBaseOut(str, baseIn, baseOut, callerIsToString ? (alphabet = ALPHABET, decimal) : (alphabet = decimal, ALPHABET));
                // xc now represents str as an integer and converted to baseOut. e is the exponent.
                e = k = xc.length;
                // Remove trailing zeros.
                for(; xc[--k] == 0; xc.pop());
                // Zero?
                if (!xc[0]) return alphabet.charAt(0);
                // Does str represent an integer? If so, no need for the division.
                if (i < 0) --e;
                else {
                    x.c = xc;
                    x.e = e;
                    // The sign is needed for correct rounding.
                    x.s = sign;
                    x = div(x, y, dp, rm, baseOut);
                    xc = x.c;
                    r = x.r;
                    e = x.e;
                }
                // xc now represents str converted to baseOut.
                // THe index of the rounding digit.
                d = e + dp + 1;
                // The rounding digit: the digit to the right of the digit that may be rounded up.
                i = xc[d];
                // Look at the rounding digits and mode to determine whether to round up.
                k = baseOut / 2;
                r = r || d < 0 || xc[d + 1] != null;
                r = rm < 4 ? (i != null || r) && (rm == 0 || rm == (x.s < 0 ? 3 : 2)) : i > k || i == k && (rm == 4 || r || rm == 6 && xc[d - 1] & 1 || rm == (x.s < 0 ? 8 : 7));
                // If the index of the rounding digit is not greater than zero, or xc represents
                // zero, then the result of the base conversion is zero or, if rounding up, a value
                // such as 0.00001.
                if (d < 1 || !xc[0]) // 1^-dp or 0
                str = r ? toFixedPoint(alphabet.charAt(1), -dp, alphabet.charAt(0)) : alphabet.charAt(0);
                else {
                    // Truncate xc to the required number of decimal places.
                    xc.length = d;
                    // Round up?
                    if (r) // Rounding up may mean the previous digit has to be rounded up and so on.
                    for(--baseOut; ++xc[--d] > baseOut;){
                        xc[d] = 0;
                        if (!d) {
                            ++e;
                            xc = [
                                1
                            ].concat(xc);
                        }
                    }
                    // Determine trailing zeros.
                    for(k = xc.length; !xc[--k];);
                    // E.g. [4, 11, 15] becomes 4bf.
                    for(i = 0, str = ''; i <= k; str += alphabet.charAt(xc[i++]));
                    // Add leading zeros, decimal point and trailing zeros as required.
                    str = toFixedPoint(str, e, alphabet.charAt(0));
                }
                // The caller will add the sign.
                return str;
            };
        })();
        // Perform division in the specified base. Called by div and convertBase.
        div = (function() {
            // Assume non-zero x and k.
            function multiply(x, k, base) {
                var m, temp, xlo, xhi, carry = 0, i = x.length, klo = k % SQRT_BASE, khi = k / SQRT_BASE | 0;
                for(x = x.slice(); i--;){
                    xlo = x[i] % SQRT_BASE;
                    xhi = x[i] / SQRT_BASE | 0;
                    m = khi * xlo + xhi * klo;
                    temp = klo * xlo + m % SQRT_BASE * SQRT_BASE + carry;
                    carry = (temp / base | 0) + (m / SQRT_BASE | 0) + khi * xhi;
                    x[i] = temp % base;
                }
                if (carry) x = [
                    carry
                ].concat(x);
                return x;
            }
            function compare(a, b, aL, bL) {
                var i, cmp;
                if (aL != bL) cmp = aL > bL ? 1 : -1;
                else {
                    for(i = cmp = 0; i < aL; i++)if (a[i] != b[i]) {
                        cmp = a[i] > b[i] ? 1 : -1;
                        break;
                    }
                }
                return cmp;
            }
            function subtract(a, b, aL, base) {
                var i = 0;
                // Subtract b from a.
                for(; aL--;){
                    a[aL] -= i;
                    i = a[aL] < b[aL] ? 1 : 0;
                    a[aL] = i * base + a[aL] - b[aL];
                }
                // Remove leading zeros.
                for(; !a[0] && a.length > 1; a.splice(0, 1));
            }
            // x: dividend, y: divisor.
            return function(x, y, dp, rm, base) {
                var cmp, e, i, more, n, prod, prodL, q, qc, rem, remL, rem0, xi, xL, yc0, yL, yz, s = x.s == y.s ? 1 : -1, xc = x.c, yc = y.c;
                // Either NaN, Infinity or 0?
                if (!xc || !xc[0] || !yc || !yc[0]) return new BigNumber(// Return NaN if either NaN, or both Infinity or 0.
                !x.s || !y.s || (xc ? yc && xc[0] == yc[0] : !yc) ? NaN : // Return ±0 if x is ±0 or y is ±Infinity, or return ±Infinity as y is ±0.
                xc && xc[0] == 0 || !yc ? s * 0 : s / 0);
                q = new BigNumber(s);
                qc = q.c = [];
                e = x.e - y.e;
                s = dp + e + 1;
                if (!base) {
                    base = BASE;
                    e = bitFloor(x.e / LOG_BASE) - bitFloor(y.e / LOG_BASE);
                    s = s / LOG_BASE | 0;
                }
                // Result exponent may be one less then the current value of e.
                // The coefficients of the BigNumbers from convertBase may have trailing zeros.
                for(i = 0; yc[i] == (xc[i] || 0); i++);
                if (yc[i] > (xc[i] || 0)) e--;
                if (s < 0) {
                    qc.push(1);
                    more = true;
                } else {
                    xL = xc.length;
                    yL = yc.length;
                    i = 0;
                    s += 2;
                    // Normalise xc and yc so highest order digit of yc is >= base / 2.
                    n = mathfloor(base / (yc[0] + 1));
                    // Not necessary, but to handle odd bases where yc[0] == (base / 2) - 1.
                    // if (n > 1 || n++ == 1 && yc[0] < base / 2) {
                    if (n > 1) {
                        yc = multiply(yc, n, base);
                        xc = multiply(xc, n, base);
                        yL = yc.length;
                        xL = xc.length;
                    }
                    xi = yL;
                    rem = xc.slice(0, yL);
                    remL = rem.length;
                    // Add zeros to make remainder as long as divisor.
                    for(; remL < yL; rem[remL++] = 0);
                    yz = yc.slice();
                    yz = [
                        0
                    ].concat(yz);
                    yc0 = yc[0];
                    if (yc[1] >= base / 2) yc0++;
                    // Not necessary, but to prevent trial digit n > base, when using base 3.
                    // else if (base == 3 && yc0 == 1) yc0 = 1 + 1e-15;
                    do {
                        n = 0;
                        // Compare divisor and remainder.
                        cmp = compare(yc, rem, yL, remL);
                        // If divisor < remainder.
                        if (cmp < 0) {
                            // Calculate trial digit, n.
                            rem0 = rem[0];
                            if (yL != remL) rem0 = rem0 * base + (rem[1] || 0);
                            // n is how many times the divisor goes into the current remainder.
                            n = mathfloor(rem0 / yc0);
                            //  Algorithm:
                            //  product = divisor multiplied by trial digit (n).
                            //  Compare product and remainder.
                            //  If product is greater than remainder:
                            //    Subtract divisor from product, decrement trial digit.
                            //  Subtract product from remainder.
                            //  If product was less than remainder at the last compare:
                            //    Compare new remainder and divisor.
                            //    If remainder is greater than divisor:
                            //      Subtract divisor from remainder, increment trial digit.
                            if (n > 1) {
                                // n may be > base only when base is 3.
                                if (n >= base) n = base - 1;
                                // product = divisor * trial digit.
                                prod = multiply(yc, n, base);
                                prodL = prod.length;
                                remL = rem.length;
                                // Compare product and remainder.
                                // If product > remainder then trial digit n too high.
                                // n is 1 too high about 5% of the time, and is not known to have
                                // ever been more than 1 too high.
                                while(compare(prod, rem, prodL, remL) == 1){
                                    n--;
                                    // Subtract divisor from product.
                                    subtract(prod, yL < prodL ? yz : yc, prodL, base);
                                    prodL = prod.length;
                                    cmp = 1;
                                }
                            } else {
                                // n is 0 or 1, cmp is -1.
                                // If n is 0, there is no need to compare yc and rem again below,
                                // so change cmp to 1 to avoid it.
                                // If n is 1, leave cmp as -1, so yc and rem are compared again.
                                if (n == 0) // divisor < remainder, so n must be at least 1.
                                cmp = n = 1;
                                // product = divisor
                                prod = yc.slice();
                                prodL = prod.length;
                            }
                            if (prodL < remL) prod = [
                                0
                            ].concat(prod);
                            // Subtract product from remainder.
                            subtract(rem, prod, remL, base);
                            remL = rem.length;
                            // If product was < remainder.
                            if (cmp == -1) // Compare divisor and new remainder.
                            // If divisor < new remainder, subtract divisor from remainder.
                            // Trial digit n too low.
                            // n is 1 too low about 5% of the time, and very rarely 2 too low.
                            while(compare(yc, rem, yL, remL) < 1){
                                n++;
                                // Subtract divisor from remainder.
                                subtract(rem, yL < remL ? yz : yc, remL, base);
                                remL = rem.length;
                            }
                        } else if (cmp === 0) {
                            n++;
                            rem = [
                                0
                            ];
                        } // else cmp === 1 and n will be 0
                        // Add the next digit, n, to the result array.
                        qc[i++] = n;
                        // Update the remainder.
                        if (rem[0]) rem[remL++] = xc[xi] || 0;
                        else {
                            rem = [
                                xc[xi]
                            ];
                            remL = 1;
                        }
                    }while (((xi++) < xL || rem[0] != null) && s--)
                    more = rem[0] != null;
                    // Leading zero?
                    if (!qc[0]) qc.splice(0, 1);
                }
                if (base == BASE) {
                    // To calculate q.e, first get the number of digits of qc[0].
                    for(i = 1, s = qc[0]; s >= 10; s /= 10, i++);
                    round(q, dp + (q.e = i + e * LOG_BASE - 1) + 1, rm, more);
                // Caller is convertBase.
                } else {
                    q.e = e;
                    q.r = +more;
                }
                return q;
            };
        })();
        /*
     * Return a string representing the value of BigNumber n in fixed-point or exponential
     * notation rounded to the specified decimal places or significant digits.
     *
     * n: a BigNumber.
     * i: the index of the last digit required (i.e. the digit that may be rounded up).
     * rm: the rounding mode.
     * id: 1 (toExponential) or 2 (toPrecision).
     */ function format1(n, i, rm, id) {
            var c0, e, ne, len, str;
            if (rm == null) rm = ROUNDING_MODE;
            else intCheck(rm, 0, 8);
            if (!n.c) return n.toString();
            c0 = n.c[0];
            ne = n.e;
            if (i == null) {
                str = coeffToString(n.c);
                str = id == 1 || id == 2 && (ne <= TO_EXP_NEG || ne >= TO_EXP_POS) ? toExponential(str, ne) : toFixedPoint(str, ne, '0');
            } else {
                n = round(new BigNumber(n), i, rm);
                // n.e may have changed if the value was rounded up.
                e = n.e;
                str = coeffToString(n.c);
                len = str.length;
                // toPrecision returns exponential notation if the number of significant digits
                // specified is less than the number of digits necessary to represent the integer
                // part of the value in fixed-point notation.
                // Exponential notation.
                if (id == 1 || id == 2 && (i <= e || e <= TO_EXP_NEG)) {
                    // Append zeros?
                    for(; len < i; str += '0', len++);
                    str = toExponential(str, e);
                // Fixed-point notation.
                } else {
                    i -= ne;
                    str = toFixedPoint(str, e, '0');
                    // Append zeros?
                    if (e + 1 > len) {
                        if (--i > 0) for(str += '.'; i--; str += '0');
                    } else {
                        i += e - len;
                        if (i > 0) {
                            if (e + 1 == len) str += '.';
                            for(; i--; str += '0');
                        }
                    }
                }
            }
            return n.s < 0 && c0 ? '-' + str : str;
        }
        // Handle BigNumber.max and BigNumber.min.
        function maxOrMin(args, method) {
            var n, i = 1, m = new BigNumber(args[0]);
            for(; i < args.length; i++){
                n = new BigNumber(args[i]);
                // If any number is NaN, return NaN.
                if (!n.s) {
                    m = n;
                    break;
                } else if (method.call(m, n)) m = n;
            }
            return m;
        }
        /*
     * Strip trailing zeros, calculate base 10 exponent and check against MIN_EXP and MAX_EXP.
     * Called by minus, plus and times.
     */ function normalise(n, c, e) {
            var i = 1, j = c.length;
            // Remove trailing zeros.
            for(; !c[--j]; c.pop());
            // Calculate the base 10 exponent. First get the number of digits of c[0].
            for(j = c[0]; j >= 10; j /= 10, i++);
            // Overflow?
            if ((e = i + e * LOG_BASE - 1) > MAX_EXP) // Infinity.
            n.c = n.e = null;
            else if (e < MIN_EXP) // Zero.
            n.c = [
                n.e = 0
            ];
            else {
                n.e = e;
                n.c = c;
            }
            return n;
        }
        // Handle values that fail the validity test in BigNumber.
        parseNumeric = (function() {
            var basePrefix = /^(-?)0([xbo])(?=\w[\w.]*$)/i, dotAfter = /^([^.]+)\.$/, dotBefore = /^\.([^.]+)$/, isInfinityOrNaN = /^-?(Infinity|NaN)$/, whitespaceOrPlus = /^\s*\+(?=[\w.])|^\s+|\s+$/g;
            return function(x, str, isNum, b) {
                var base, s = isNum ? str : str.replace(whitespaceOrPlus, '');
                // No exception on ±Infinity or NaN.
                if (isInfinityOrNaN.test(s)) x.s = isNaN(s) ? null : s < 0 ? -1 : 1;
                else {
                    if (!isNum) {
                        // basePrefix = /^(-?)0([xbo])(?=\w[\w.]*$)/i
                        s = s.replace(basePrefix, function(m, p1, p2) {
                            base = (p2 = p2.toLowerCase()) == 'x' ? 16 : p2 == 'b' ? 2 : 8;
                            return !b || b == base ? p1 : m;
                        });
                        if (b) {
                            base = b;
                            // E.g. '1.' to '1', '.1' to '0.1'
                            s = s.replace(dotAfter, '$1').replace(dotBefore, '0.$1');
                        }
                        if (str != s) return new BigNumber(s, base);
                    }
                    // '[BigNumber Error] Not a number: {n}'
                    // '[BigNumber Error] Not a base {b} number: {n}'
                    if (BigNumber.DEBUG) throw Error(bignumberError + 'Not a' + (b ? ' base ' + b : '') + ' number: ' + str);
                    // NaN
                    x.s = null;
                }
                x.c = x.e = null;
            };
        })();
        /*
     * Round x to sd significant digits using rounding mode rm. Check for over/under-flow.
     * If r is truthy, it is known that there are more digits after the rounding digit.
     */ function round(x, sd, rm, r) {
            var d, i, j, k, n, ni, rd, xc = x.c, pows10 = POWS_TEN;
            // if x is not Infinity or NaN...
            if (xc) {
                // rd is the rounding digit, i.e. the digit after the digit that may be rounded up.
                // n is a base 1e14 number, the value of the element of array x.c containing rd.
                // ni is the index of n within x.c.
                // d is the number of digits of n.
                // i is the index of rd within n including leading zeros.
                // j is the actual index of rd within n (if < 0, rd is a leading zero).
                out: {
                    // Get the number of digits of the first element of xc.
                    for(d = 1, k = xc[0]; k >= 10; k /= 10, d++);
                    i = sd - d;
                    // If the rounding digit is in the first element of xc...
                    if (i < 0) {
                        i += LOG_BASE;
                        j = sd;
                        n = xc[ni = 0];
                        // Get the rounding digit at index j of n.
                        rd = n / pows10[d - j - 1] % 10 | 0;
                    } else {
                        ni = mathceil((i + 1) / LOG_BASE);
                        if (ni >= xc.length) {
                            if (r) {
                                // Needed by sqrt.
                                for(; xc.length <= ni; xc.push(0));
                                n = rd = 0;
                                d = 1;
                                i %= LOG_BASE;
                                j = i - LOG_BASE + 1;
                            } else break out;
                        } else {
                            n = k = xc[ni];
                            // Get the number of digits of n.
                            for(d = 1; k >= 10; k /= 10, d++);
                            // Get the index of rd within n.
                            i %= LOG_BASE;
                            // Get the index of rd within n, adjusted for leading zeros.
                            // The number of leading zeros of n is given by LOG_BASE - d.
                            j = i - LOG_BASE + d;
                            // Get the rounding digit at index j of n.
                            rd = j < 0 ? 0 : n / pows10[d - j - 1] % 10 | 0;
                        }
                    }
                    r = r || sd < 0 || // Are there any non-zero digits after the rounding digit?
                    // The expression  n % pows10[d - j - 1]  returns all digits of n to the right
                    // of the digit at j, e.g. if n is 908714 and j is 2, the expression gives 714.
                    xc[ni + 1] != null || (j < 0 ? n : n % pows10[d - j - 1]);
                    r = rm < 4 ? (rd || r) && (rm == 0 || rm == (x.s < 0 ? 3 : 2)) : rd > 5 || rd == 5 && (rm == 4 || r || rm == 6 && // Check whether the digit to the left of the rounding digit is odd.
                    (i > 0 ? j > 0 ? n / pows10[d - j] : 0 : xc[ni - 1]) % 10 & 1 || rm == (x.s < 0 ? 8 : 7));
                    if (sd < 1 || !xc[0]) {
                        xc.length = 0;
                        if (r) {
                            // Convert sd to decimal places.
                            sd -= x.e + 1;
                            // 1, 0.1, 0.01, 0.001, 0.0001 etc.
                            xc[0] = pows10[(LOG_BASE - sd % LOG_BASE) % LOG_BASE];
                            x.e = -sd || 0;
                        } else // Zero.
                        xc[0] = x.e = 0;
                        return x;
                    }
                    // Remove excess digits.
                    if (i == 0) {
                        xc.length = ni;
                        k = 1;
                        ni--;
                    } else {
                        xc.length = ni + 1;
                        k = pows10[LOG_BASE - i];
                        // E.g. 56700 becomes 56000 if 7 is the rounding digit.
                        // j > 0 means i > number of leading zeros of n.
                        xc[ni] = j > 0 ? mathfloor(n / pows10[d - j] % pows10[j]) * k : 0;
                    }
                    // Round up?
                    if (r) {
                        for(;;)// If the digit to be rounded up is in the first element of xc...
                        if (ni == 0) {
                            // i will be the length of xc[0] before k is added.
                            for(i = 1, j = xc[0]; j >= 10; j /= 10, i++);
                            j = xc[0] += k;
                            for(k = 1; j >= 10; j /= 10, k++);
                            // if i != k the length has increased.
                            if (i != k) {
                                x.e++;
                                if (xc[0] == BASE) xc[0] = 1;
                            }
                            break;
                        } else {
                            xc[ni] += k;
                            if (xc[ni] != BASE) break;
                            xc[ni--] = 0;
                            k = 1;
                        }
                    }
                    // Remove trailing zeros.
                    for(i = xc.length; xc[--i] === 0; xc.pop());
                }
                // Overflow? Infinity.
                if (x.e > MAX_EXP) x.c = x.e = null;
                else if (x.e < MIN_EXP) x.c = [
                    x.e = 0
                ];
            }
            return x;
        }
        function valueOf(n) {
            var str, e = n.e;
            if (e === null) return n.toString();
            str = coeffToString(n.c);
            str = e <= TO_EXP_NEG || e >= TO_EXP_POS ? toExponential(str, e) : toFixedPoint(str, e, '0');
            return n.s < 0 ? '-' + str : str;
        }
        // PROTOTYPE/INSTANCE METHODS
        /*
     * Return a new BigNumber whose value is the absolute value of this BigNumber.
     */ P.absoluteValue = P.abs = function() {
            var x = new BigNumber(this);
            if (x.s < 0) x.s = 1;
            return x;
        };
        /*
     * Return
     *   1 if the value of this BigNumber is greater than the value of BigNumber(y, b),
     *   -1 if the value of this BigNumber is less than the value of BigNumber(y, b),
     *   0 if they have the same value,
     *   or null if the value of either is NaN.
     */ P.comparedTo = function(y, b) {
            return compare1(this, new BigNumber(y, b));
        };
        /*
     * If dp is undefined or null or true or false, return the number of decimal places of the
     * value of this BigNumber, or null if the value of this BigNumber is ±Infinity or NaN.
     *
     * Otherwise, if dp is a number, return a new BigNumber whose value is the value of this
     * BigNumber rounded to a maximum of dp decimal places using rounding mode rm, or
     * ROUNDING_MODE if rm is omitted.
     *
     * [dp] {number} Decimal places: integer, 0 to MAX inclusive.
     * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
     *
     * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {dp|rm}'
     */ P.decimalPlaces = P.dp = function(dp, rm) {
            var c, n, v, x = this;
            if (dp != null) {
                intCheck(dp, 0, MAX);
                if (rm == null) rm = ROUNDING_MODE;
                else intCheck(rm, 0, 8);
                return round(new BigNumber(x), dp + x.e + 1, rm);
            }
            if (!(c = x.c)) return null;
            n = ((v = c.length - 1) - bitFloor(this.e / LOG_BASE)) * LOG_BASE;
            // Subtract the number of trailing zeros of the last number.
            if (v = c[v]) for(; v % 10 == 0; v /= 10, n--);
            if (n < 0) n = 0;
            return n;
        };
        /*
     *  n / 0 = I
     *  n / N = N
     *  n / I = 0
     *  0 / n = 0
     *  0 / 0 = N
     *  0 / N = N
     *  0 / I = 0
     *  N / n = N
     *  N / 0 = N
     *  N / N = N
     *  N / I = N
     *  I / n = I
     *  I / 0 = I
     *  I / N = N
     *  I / I = N
     *
     * Return a new BigNumber whose value is the value of this BigNumber divided by the value of
     * BigNumber(y, b), rounded according to DECIMAL_PLACES and ROUNDING_MODE.
     */ P.dividedBy = P.div = function(y, b) {
            return div(this, new BigNumber(y, b), DECIMAL_PLACES, ROUNDING_MODE);
        };
        /*
     * Return a new BigNumber whose value is the integer part of dividing the value of this
     * BigNumber by the value of BigNumber(y, b).
     */ P.dividedToIntegerBy = P.idiv = function(y, b) {
            return div(this, new BigNumber(y, b), 0, 1);
        };
        /*
     * Return a BigNumber whose value is the value of this BigNumber exponentiated by n.
     *
     * If m is present, return the result modulo m.
     * If n is negative round according to DECIMAL_PLACES and ROUNDING_MODE.
     * If POW_PRECISION is non-zero and m is not present, round to POW_PRECISION using ROUNDING_MODE.
     *
     * The modular power operation works efficiently when x, n, and m are integers, otherwise it
     * is equivalent to calculating x.exponentiatedBy(n).modulo(m) with a POW_PRECISION of 0.
     *
     * n {number|string|BigNumber} The exponent. An integer.
     * [m] {number|string|BigNumber} The modulus.
     *
     * '[BigNumber Error] Exponent not an integer: {n}'
     */ P.exponentiatedBy = P.pow = function(n, m) {
            var half, isModExp, i, k, more, nIsBig, nIsNeg, nIsOdd, y, x = this;
            n = new BigNumber(n);
            // Allow NaN and ±Infinity, but not other non-integers.
            if (n.c && !n.isInteger()) throw Error(bignumberError + 'Exponent not an integer: ' + valueOf(n));
            if (m != null) m = new BigNumber(m);
            // Exponent of MAX_SAFE_INTEGER is 15.
            nIsBig = n.e > 14;
            // If x is NaN, ±Infinity, ±0 or ±1, or n is ±Infinity, NaN or ±0.
            if (!x.c || !x.c[0] || x.c[0] == 1 && !x.e && x.c.length == 1 || !n.c || !n.c[0]) {
                // The sign of the result of pow when x is negative depends on the evenness of n.
                // If +n overflows to ±Infinity, the evenness of n would be not be known.
                y = new BigNumber(Math.pow(+valueOf(x), nIsBig ? 2 - isOdd(n) : +valueOf(n)));
                return m ? y.mod(m) : y;
            }
            nIsNeg = n.s < 0;
            if (m) {
                // x % m returns NaN if abs(m) is zero, or m is NaN.
                if (m.c ? !m.c[0] : !m.s) return new BigNumber(NaN);
                isModExp = !nIsNeg && x.isInteger() && m.isInteger();
                if (isModExp) x = x.mod(m);
            // Overflow to ±Infinity: >=2**1e10 or >=1.0000024**1e15.
            // Underflow to ±0: <=0.79**1e10 or <=0.9999975**1e15.
            } else if (n.e > 9 && (x.e > 0 || x.e < -1 || (x.e == 0 ? x.c[0] > 1 || nIsBig && x.c[1] >= 240000000 : x.c[0] < 80000000000000 || nIsBig && x.c[0] <= 99999750000000))) {
                // If x is negative and n is odd, k = -0, else k = 0.
                k = x.s < 0 && isOdd(n) ? -0 : 0;
                // If x >= 1, k = ±Infinity.
                if (x.e > -1) k = 1 / k;
                // If n is negative return ±0, else return ±Infinity.
                return new BigNumber(nIsNeg ? 1 / k : k);
            } else if (POW_PRECISION) // Truncating each coefficient array to a length of k after each multiplication
            // equates to truncating significant digits to POW_PRECISION + [28, 41],
            // i.e. there will be a minimum of 28 guard digits retained.
            k = mathceil(POW_PRECISION / LOG_BASE + 2);
            if (nIsBig) {
                half = new BigNumber(0.5);
                if (nIsNeg) n.s = 1;
                nIsOdd = isOdd(n);
            } else {
                i = Math.abs(+valueOf(n));
                nIsOdd = i % 2;
            }
            y = new BigNumber(ONE);
            // Performs 54 loop iterations for n of 9007199254740991.
            for(;;){
                if (nIsOdd) {
                    y = y.times(x);
                    if (!y.c) break;
                    if (k) {
                        if (y.c.length > k) y.c.length = k;
                    } else if (isModExp) y = y.mod(m); //y = y.minus(div(y, m, 0, MODULO_MODE).times(m));
                }
                if (i) {
                    i = mathfloor(i / 2);
                    if (i === 0) break;
                    nIsOdd = i % 2;
                } else {
                    n = n.times(half);
                    round(n, n.e + 1, 1);
                    if (n.e > 14) nIsOdd = isOdd(n);
                    else {
                        i = +valueOf(n);
                        if (i === 0) break;
                        nIsOdd = i % 2;
                    }
                }
                x = x.times(x);
                if (k) {
                    if (x.c && x.c.length > k) x.c.length = k;
                } else if (isModExp) x = x.mod(m); //x = x.minus(div(x, m, 0, MODULO_MODE).times(m));
            }
            if (isModExp) return y;
            if (nIsNeg) y = ONE.div(y);
            return m ? y.mod(m) : k ? round(y, POW_PRECISION, ROUNDING_MODE, more) : y;
        };
        /*
     * Return a new BigNumber whose value is the value of this BigNumber rounded to an integer
     * using rounding mode rm, or ROUNDING_MODE if rm is omitted.
     *
     * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
     *
     * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {rm}'
     */ P.integerValue = function(rm) {
            var n = new BigNumber(this);
            if (rm == null) rm = ROUNDING_MODE;
            else intCheck(rm, 0, 8);
            return round(n, n.e + 1, rm);
        };
        /*
     * Return true if the value of this BigNumber is equal to the value of BigNumber(y, b),
     * otherwise return false.
     */ P.isEqualTo = P.eq = function(y, b) {
            return compare1(this, new BigNumber(y, b)) === 0;
        };
        /*
     * Return true if the value of this BigNumber is a finite number, otherwise return false.
     */ P.isFinite = function() {
            return !!this.c;
        };
        /*
     * Return true if the value of this BigNumber is greater than the value of BigNumber(y, b),
     * otherwise return false.
     */ P.isGreaterThan = P.gt = function(y, b) {
            return compare1(this, new BigNumber(y, b)) > 0;
        };
        /*
     * Return true if the value of this BigNumber is greater than or equal to the value of
     * BigNumber(y, b), otherwise return false.
     */ P.isGreaterThanOrEqualTo = P.gte = function(y, b) {
            return (b = compare1(this, new BigNumber(y, b))) === 1 || b === 0;
        };
        /*
     * Return true if the value of this BigNumber is an integer, otherwise return false.
     */ P.isInteger = function() {
            return !!this.c && bitFloor(this.e / LOG_BASE) > this.c.length - 2;
        };
        /*
     * Return true if the value of this BigNumber is less than the value of BigNumber(y, b),
     * otherwise return false.
     */ P.isLessThan = P.lt = function(y, b) {
            return compare1(this, new BigNumber(y, b)) < 0;
        };
        /*
     * Return true if the value of this BigNumber is less than or equal to the value of
     * BigNumber(y, b), otherwise return false.
     */ P.isLessThanOrEqualTo = P.lte = function(y, b) {
            return (b = compare1(this, new BigNumber(y, b))) === -1 || b === 0;
        };
        /*
     * Return true if the value of this BigNumber is NaN, otherwise return false.
     */ P.isNaN = function() {
            return !this.s;
        };
        /*
     * Return true if the value of this BigNumber is negative, otherwise return false.
     */ P.isNegative = function() {
            return this.s < 0;
        };
        /*
     * Return true if the value of this BigNumber is positive, otherwise return false.
     */ P.isPositive = function() {
            return this.s > 0;
        };
        /*
     * Return true if the value of this BigNumber is 0 or -0, otherwise return false.
     */ P.isZero = function() {
            return !!this.c && this.c[0] == 0;
        };
        /*
     *  n - 0 = n
     *  n - N = N
     *  n - I = -I
     *  0 - n = -n
     *  0 - 0 = 0
     *  0 - N = N
     *  0 - I = -I
     *  N - n = N
     *  N - 0 = N
     *  N - N = N
     *  N - I = N
     *  I - n = I
     *  I - 0 = I
     *  I - N = N
     *  I - I = N
     *
     * Return a new BigNumber whose value is the value of this BigNumber minus the value of
     * BigNumber(y, b).
     */ P.minus = function(y, b) {
            var i, j, t, xLTy, x = this, a = x.s;
            y = new BigNumber(y, b);
            b = y.s;
            // Either NaN?
            if (!a || !b) return new BigNumber(NaN);
            // Signs differ?
            if (a != b) {
                y.s = -b;
                return x.plus(y);
            }
            var xe = x.e / LOG_BASE, ye = y.e / LOG_BASE, xc = x.c, yc = y.c;
            if (!xe || !ye) {
                // Either Infinity?
                if (!xc || !yc) return xc ? (y.s = -b, y) : new BigNumber(yc ? x : NaN);
                // Either zero?
                if (!xc[0] || !yc[0]) // Return y if y is non-zero, x if x is non-zero, or zero if both are zero.
                return yc[0] ? (y.s = -b, y) : new BigNumber(xc[0] ? x : // IEEE 754 (2008) 6.3: n - n = -0 when rounding to -Infinity
                ROUNDING_MODE == 3 ? -0 : 0);
            }
            xe = bitFloor(xe);
            ye = bitFloor(ye);
            xc = xc.slice();
            // Determine which is the bigger number.
            if (a = xe - ye) {
                if (xLTy = a < 0) {
                    a = -a;
                    t = xc;
                } else {
                    ye = xe;
                    t = yc;
                }
                t.reverse();
                // Prepend zeros to equalise exponents.
                for(b = a; b--; t.push(0));
                t.reverse();
            } else {
                // Exponents equal. Check digit by digit.
                j = (xLTy = (a = xc.length) < (b = yc.length)) ? a : b;
                for(a = b = 0; b < j; b++)if (xc[b] != yc[b]) {
                    xLTy = xc[b] < yc[b];
                    break;
                }
            }
            // x < y? Point xc to the array of the bigger number.
            if (xLTy) t = xc, xc = yc, yc = t, y.s = -y.s;
            b = (j = yc.length) - (i = xc.length);
            // Append zeros to xc if shorter.
            // No need to add zeros to yc if shorter as subtract only needs to start at yc.length.
            if (b > 0) for(; b--; xc[i++] = 0);
            b = BASE - 1;
            // Subtract yc from xc.
            for(; j > a;){
                if (xc[--j] < yc[j]) {
                    for(i = j; i && !xc[--i]; xc[i] = b);
                    --xc[i];
                    xc[j] += BASE;
                }
                xc[j] -= yc[j];
            }
            // Remove leading zeros and adjust exponent accordingly.
            for(; xc[0] == 0; xc.splice(0, 1), --ye);
            // Zero?
            if (!xc[0]) {
                // Following IEEE 754 (2008) 6.3,
                // n - n = +0  but  n - n = -0  when rounding towards -Infinity.
                y.s = ROUNDING_MODE == 3 ? -1 : 1;
                y.c = [
                    y.e = 0
                ];
                return y;
            }
            // No need to check for Infinity as +x - +y != Infinity && -x - -y != Infinity
            // for finite x and y.
            return normalise(y, xc, ye);
        };
        /*
     *   n % 0 =  N
     *   n % N =  N
     *   n % I =  n
     *   0 % n =  0
     *  -0 % n = -0
     *   0 % 0 =  N
     *   0 % N =  N
     *   0 % I =  0
     *   N % n =  N
     *   N % 0 =  N
     *   N % N =  N
     *   N % I =  N
     *   I % n =  N
     *   I % 0 =  N
     *   I % N =  N
     *   I % I =  N
     *
     * Return a new BigNumber whose value is the value of this BigNumber modulo the value of
     * BigNumber(y, b). The result depends on the value of MODULO_MODE.
     */ P.modulo = P.mod = function(y, b) {
            var q, s, x = this;
            y = new BigNumber(y, b);
            // Return NaN if x is Infinity or NaN, or y is NaN or zero.
            if (!x.c || !y.s || y.c && !y.c[0]) return new BigNumber(NaN);
            else if (!y.c || x.c && !x.c[0]) return new BigNumber(x);
            if (MODULO_MODE == 9) {
                // Euclidian division: q = sign(y) * floor(x / abs(y))
                // r = x - qy    where  0 <= r < abs(y)
                s = y.s;
                y.s = 1;
                q = div(x, y, 0, 3);
                y.s = s;
                q.s *= s;
            } else q = div(x, y, 0, MODULO_MODE);
            y = x.minus(q.times(y));
            // To match JavaScript %, ensure sign of zero is sign of dividend.
            if (!y.c[0] && MODULO_MODE == 1) y.s = x.s;
            return y;
        };
        /*
     *  n * 0 = 0
     *  n * N = N
     *  n * I = I
     *  0 * n = 0
     *  0 * 0 = 0
     *  0 * N = N
     *  0 * I = N
     *  N * n = N
     *  N * 0 = N
     *  N * N = N
     *  N * I = N
     *  I * n = I
     *  I * 0 = N
     *  I * N = N
     *  I * I = I
     *
     * Return a new BigNumber whose value is the value of this BigNumber multiplied by the value
     * of BigNumber(y, b).
     */ P.multipliedBy = P.times = function(y, b) {
            var c, e, i, j, k, m, xcL, xlo, xhi, ycL, ylo, yhi, zc, base, sqrtBase, x = this, xc = x.c, yc = (y = new BigNumber(y, b)).c;
            // Either NaN, ±Infinity or ±0?
            if (!xc || !yc || !xc[0] || !yc[0]) {
                // Return NaN if either is NaN, or one is 0 and the other is Infinity.
                if (!x.s || !y.s || xc && !xc[0] && !yc || yc && !yc[0] && !xc) y.c = y.e = y.s = null;
                else {
                    y.s *= x.s;
                    // Return ±Infinity if either is ±Infinity.
                    if (!xc || !yc) y.c = y.e = null;
                    else {
                        y.c = [
                            0
                        ];
                        y.e = 0;
                    }
                }
                return y;
            }
            e = bitFloor(x.e / LOG_BASE) + bitFloor(y.e / LOG_BASE);
            y.s *= x.s;
            xcL = xc.length;
            ycL = yc.length;
            // Ensure xc points to longer array and xcL to its length.
            if (xcL < ycL) zc = xc, xc = yc, yc = zc, i = xcL, xcL = ycL, ycL = i;
            // Initialise the result array with zeros.
            for(i = xcL + ycL, zc = []; i--; zc.push(0));
            base = BASE;
            sqrtBase = SQRT_BASE;
            for(i = ycL; --i >= 0;){
                c = 0;
                ylo = yc[i] % sqrtBase;
                yhi = yc[i] / sqrtBase | 0;
                for(k = xcL, j = i + k; j > i;){
                    xlo = xc[--k] % sqrtBase;
                    xhi = xc[k] / sqrtBase | 0;
                    m = yhi * xlo + xhi * ylo;
                    xlo = ylo * xlo + m % sqrtBase * sqrtBase + zc[j] + c;
                    c = (xlo / base | 0) + (m / sqrtBase | 0) + yhi * xhi;
                    zc[j--] = xlo % base;
                }
                zc[j] = c;
            }
            if (c) ++e;
            else zc.splice(0, 1);
            return normalise(y, zc, e);
        };
        /*
     * Return a new BigNumber whose value is the value of this BigNumber negated,
     * i.e. multiplied by -1.
     */ P.negated = function() {
            var x = new BigNumber(this);
            x.s = -x.s || null;
            return x;
        };
        /*
     *  n + 0 = n
     *  n + N = N
     *  n + I = I
     *  0 + n = n
     *  0 + 0 = 0
     *  0 + N = N
     *  0 + I = I
     *  N + n = N
     *  N + 0 = N
     *  N + N = N
     *  N + I = N
     *  I + n = I
     *  I + 0 = I
     *  I + N = N
     *  I + I = I
     *
     * Return a new BigNumber whose value is the value of this BigNumber plus the value of
     * BigNumber(y, b).
     */ P.plus = function(y, b) {
            var t, x = this, a = x.s;
            y = new BigNumber(y, b);
            b = y.s;
            // Either NaN?
            if (!a || !b) return new BigNumber(NaN);
            // Signs differ?
            if (a != b) {
                y.s = -b;
                return x.minus(y);
            }
            var xe = x.e / LOG_BASE, ye = y.e / LOG_BASE, xc = x.c, yc = y.c;
            if (!xe || !ye) {
                // Return ±Infinity if either ±Infinity.
                if (!xc || !yc) return new BigNumber(a / 0);
                // Either zero?
                // Return y if y is non-zero, x if x is non-zero, or zero if both are zero.
                if (!xc[0] || !yc[0]) return yc[0] ? y : new BigNumber(xc[0] ? x : a * 0);
            }
            xe = bitFloor(xe);
            ye = bitFloor(ye);
            xc = xc.slice();
            // Prepend zeros to equalise exponents. Faster to use reverse then do unshifts.
            if (a = xe - ye) {
                if (a > 0) {
                    ye = xe;
                    t = yc;
                } else {
                    a = -a;
                    t = xc;
                }
                t.reverse();
                for(; a--; t.push(0));
                t.reverse();
            }
            a = xc.length;
            b = yc.length;
            // Point xc to the longer array, and b to the shorter length.
            if (a - b < 0) t = yc, yc = xc, xc = t, b = a;
            // Only start adding at yc.length - 1 as the further digits of xc can be ignored.
            for(a = 0; b;){
                a = (xc[--b] = xc[b] + yc[b] + a) / BASE | 0;
                xc[b] = BASE === xc[b] ? 0 : xc[b] % BASE;
            }
            if (a) {
                xc = [
                    a
                ].concat(xc);
                ++ye;
            }
            // No need to check for zero, as +x + +y != 0 && -x + -y != 0
            // ye = MAX_EXP + 1 possible
            return normalise(y, xc, ye);
        };
        /*
     * If sd is undefined or null or true or false, return the number of significant digits of
     * the value of this BigNumber, or null if the value of this BigNumber is ±Infinity or NaN.
     * If sd is true include integer-part trailing zeros in the count.
     *
     * Otherwise, if sd is a number, return a new BigNumber whose value is the value of this
     * BigNumber rounded to a maximum of sd significant digits using rounding mode rm, or
     * ROUNDING_MODE if rm is omitted.
     *
     * sd {number|boolean} number: significant digits: integer, 1 to MAX inclusive.
     *                     boolean: whether to count integer-part trailing zeros: true or false.
     * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
     *
     * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {sd|rm}'
     */ P.precision = P.sd = function(sd, rm) {
            var c, n, v, x = this;
            if (sd != null && sd !== !!sd) {
                intCheck(sd, 1, MAX);
                if (rm == null) rm = ROUNDING_MODE;
                else intCheck(rm, 0, 8);
                return round(new BigNumber(x), sd, rm);
            }
            if (!(c = x.c)) return null;
            v = c.length - 1;
            n = v * LOG_BASE + 1;
            if (v = c[v]) {
                // Subtract the number of trailing zeros of the last element.
                for(; v % 10 == 0; v /= 10, n--);
                // Add the number of digits of the first element.
                for(v = c[0]; v >= 10; v /= 10, n++);
            }
            if (sd && x.e + 1 > n) n = x.e + 1;
            return n;
        };
        /*
     * Return a new BigNumber whose value is the value of this BigNumber shifted by k places
     * (powers of 10). Shift to the right if n > 0, and to the left if n < 0.
     *
     * k {number} Integer, -MAX_SAFE_INTEGER to MAX_SAFE_INTEGER inclusive.
     *
     * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {k}'
     */ P.shiftedBy = function(k) {
            intCheck(k, -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER);
            return this.times('1e' + k);
        };
        /*
     *  sqrt(-n) =  N
     *  sqrt(N) =  N
     *  sqrt(-I) =  N
     *  sqrt(I) =  I
     *  sqrt(0) =  0
     *  sqrt(-0) = -0
     *
     * Return a new BigNumber whose value is the square root of the value of this BigNumber,
     * rounded according to DECIMAL_PLACES and ROUNDING_MODE.
     */ P.squareRoot = P.sqrt = function() {
            var m, n, r, rep, t, x = this, c = x.c, s = x.s, e = x.e, dp = DECIMAL_PLACES + 4, half = new BigNumber('0.5');
            // Negative/NaN/Infinity/zero?
            if (s !== 1 || !c || !c[0]) return new BigNumber(!s || s < 0 && (!c || c[0]) ? NaN : c ? x : 1 / 0);
            // Initial estimate.
            s = Math.sqrt(+valueOf(x));
            // Math.sqrt underflow/overflow?
            // Pass x to Math.sqrt as integer, then adjust the exponent of the result.
            if (s == 0 || s == 1 / 0) {
                n = coeffToString(c);
                if ((n.length + e) % 2 == 0) n += '0';
                s = Math.sqrt(+n);
                e = bitFloor((e + 1) / 2) - (e < 0 || e % 2);
                if (s == 1 / 0) n = '5e' + e;
                else {
                    n = s.toExponential();
                    n = n.slice(0, n.indexOf('e') + 1) + e;
                }
                r = new BigNumber(n);
            } else r = new BigNumber(s + '');
            // Check for zero.
            // r could be zero if MIN_EXP is changed after the this value was created.
            // This would cause a division by zero (x/t) and hence Infinity below, which would cause
            // coeffToString to throw.
            if (r.c[0]) {
                e = r.e;
                s = e + dp;
                if (s < 3) s = 0;
                // Newton-Raphson iteration.
                for(;;){
                    t = r;
                    r = half.times(t.plus(div(x, t, dp, 1)));
                    if (coeffToString(t.c).slice(0, s) === (n = coeffToString(r.c)).slice(0, s)) {
                        // The exponent of r may here be one less than the final result exponent,
                        // e.g 0.0009999 (e-4) --> 0.001 (e-3), so adjust s so the rounding digits
                        // are indexed correctly.
                        if (r.e < e) --s;
                        n = n.slice(s - 3, s + 1);
                        // The 4th rounding digit may be in error by -1 so if the 4 rounding digits
                        // are 9999 or 4999 (i.e. approaching a rounding boundary) continue the
                        // iteration.
                        if (n == '9999' || !rep && n == '4999') {
                            // On the first iteration only, check to see if rounding up gives the
                            // exact result as the nines may infinitely repeat.
                            if (!rep) {
                                round(t, t.e + DECIMAL_PLACES + 2, 0);
                                if (t.times(t).eq(x)) {
                                    r = t;
                                    break;
                                }
                            }
                            dp += 4;
                            s += 4;
                            rep = 1;
                        } else {
                            // If rounding digits are null, 0{0,4} or 50{0,3}, check for exact
                            // result. If not, then there are further digits and m will be truthy.
                            if (!+n || !+n.slice(1) && n.charAt(0) == '5') {
                                // Truncate to the first rounding digit.
                                round(r, r.e + DECIMAL_PLACES + 2, 1);
                                m = !r.times(r).eq(x);
                            }
                            break;
                        }
                    }
                }
            }
            return round(r, r.e + DECIMAL_PLACES + 1, ROUNDING_MODE, m);
        };
        /*
     * Return a string representing the value of this BigNumber in exponential notation and
     * rounded using ROUNDING_MODE to dp fixed decimal places.
     *
     * [dp] {number} Decimal places. Integer, 0 to MAX inclusive.
     * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
     *
     * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {dp|rm}'
     */ P.toExponential = function(dp, rm) {
            if (dp != null) {
                intCheck(dp, 0, MAX);
                dp++;
            }
            return format1(this, dp, rm, 1);
        };
        /*
     * Return a string representing the value of this BigNumber in fixed-point notation rounding
     * to dp fixed decimal places using rounding mode rm, or ROUNDING_MODE if rm is omitted.
     *
     * Note: as with JavaScript's number type, (-0).toFixed(0) is '0',
     * but e.g. (-0.00001).toFixed(0) is '-0'.
     *
     * [dp] {number} Decimal places. Integer, 0 to MAX inclusive.
     * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
     *
     * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {dp|rm}'
     */ P.toFixed = function(dp, rm) {
            if (dp != null) {
                intCheck(dp, 0, MAX);
                dp = dp + this.e + 1;
            }
            return format1(this, dp, rm);
        };
        /*
     * Return a string representing the value of this BigNumber in fixed-point notation rounded
     * using rm or ROUNDING_MODE to dp decimal places, and formatted according to the properties
     * of the format or FORMAT object (see BigNumber.set).
     *
     * The formatting object may contain some or all of the properties shown below.
     *
     * FORMAT = {
     *   prefix: '',
     *   groupSize: 3,
     *   secondaryGroupSize: 0,
     *   groupSeparator: ',',
     *   decimalSeparator: '.',
     *   fractionGroupSize: 0,
     *   fractionGroupSeparator: '\xA0',      // non-breaking space
     *   suffix: ''
     * };
     *
     * [dp] {number} Decimal places. Integer, 0 to MAX inclusive.
     * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
     * [format] {object} Formatting options. See FORMAT pbject above.
     *
     * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {dp|rm}'
     * '[BigNumber Error] Argument not an object: {format}'
     */ P.toFormat = function(dp, rm, format) {
            var str, x = this;
            if (format == null) {
                if (dp != null && rm && typeof rm == 'object') {
                    format = rm;
                    rm = null;
                } else if (dp && typeof dp == 'object') {
                    format = dp;
                    dp = rm = null;
                } else format = FORMAT;
            } else if (typeof format != 'object') throw Error(bignumberError + 'Argument not an object: ' + format);
            str = x.toFixed(dp, rm);
            if (x.c) {
                var i, arr = str.split('.'), g1 = +format.groupSize, g2 = +format.secondaryGroupSize, groupSeparator = format.groupSeparator || '', intPart = arr[0], fractionPart = arr[1], isNeg = x.s < 0, intDigits = isNeg ? intPart.slice(1) : intPart, len = intDigits.length;
                if (g2) i = g1, g1 = g2, g2 = i, len -= i;
                if (g1 > 0 && len > 0) {
                    i = len % g1 || g1;
                    intPart = intDigits.substr(0, i);
                    for(; i < len; i += g1)intPart += groupSeparator + intDigits.substr(i, g1);
                    if (g2 > 0) intPart += groupSeparator + intDigits.slice(i);
                    if (isNeg) intPart = '-' + intPart;
                }
                str = fractionPart ? intPart + (format.decimalSeparator || '') + ((g2 = +format.fractionGroupSize) ? fractionPart.replace(new RegExp('\\d{' + g2 + '}\\B', 'g'), '$&' + (format.fractionGroupSeparator || '')) : fractionPart) : intPart;
            }
            return (format.prefix || '') + str + (format.suffix || '');
        };
        /*
     * Return an array of two BigNumbers representing the value of this BigNumber as a simple
     * fraction with an integer numerator and an integer denominator.
     * The denominator will be a positive non-zero value less than or equal to the specified
     * maximum denominator. If a maximum denominator is not specified, the denominator will be
     * the lowest value necessary to represent the number exactly.
     *
     * [md] {number|string|BigNumber} Integer >= 1, or Infinity. The maximum denominator.
     *
     * '[BigNumber Error] Argument {not an integer|out of range} : {md}'
     */ P.toFraction = function(md) {
            var d, d0, d1, d2, e, exp, n, n0, n1, q, r, s, x = this, xc = x.c;
            if (md != null) {
                n = new BigNumber(md);
                // Throw if md is less than one or is not an integer, unless it is Infinity.
                if (!n.isInteger() && (n.c || n.s !== 1) || n.lt(ONE)) throw Error(bignumberError + 'Argument ' + (n.isInteger() ? 'out of range: ' : 'not an integer: ') + valueOf(n));
            }
            if (!xc) return new BigNumber(x);
            d = new BigNumber(ONE);
            n1 = d0 = new BigNumber(ONE);
            d1 = n0 = new BigNumber(ONE);
            s = coeffToString(xc);
            // Determine initial denominator.
            // d is a power of 10 and the minimum max denominator that specifies the value exactly.
            e = d.e = s.length - x.e - 1;
            d.c[0] = POWS_TEN[(exp = e % LOG_BASE) < 0 ? LOG_BASE + exp : exp];
            md = !md || n.comparedTo(d) > 0 ? e > 0 ? d : n1 : n;
            exp = MAX_EXP;
            MAX_EXP = 1 / 0;
            n = new BigNumber(s);
            // n0 = d1 = 0
            n0.c[0] = 0;
            for(;;){
                q = div(n, d, 0, 1);
                d2 = d0.plus(q.times(d1));
                if (d2.comparedTo(md) == 1) break;
                d0 = d1;
                d1 = d2;
                n1 = n0.plus(q.times(d2 = n1));
                n0 = d2;
                d = n.minus(q.times(d2 = d));
                n = d2;
            }
            d2 = div(md.minus(d0), d1, 0, 1);
            n0 = n0.plus(d2.times(n1));
            d0 = d0.plus(d2.times(d1));
            n0.s = n1.s = x.s;
            e = e * 2;
            // Determine which fraction is closer to x, n0/d0 or n1/d1
            r = div(n1, d1, e, ROUNDING_MODE).minus(x).abs().comparedTo(div(n0, d0, e, ROUNDING_MODE).minus(x).abs()) < 1 ? [
                n1,
                d1
            ] : [
                n0,
                d0
            ];
            MAX_EXP = exp;
            return r;
        };
        /*
     * Return the value of this BigNumber converted to a number primitive.
     */ P.toNumber = function() {
            return +valueOf(this);
        };
        /*
     * Return a string representing the value of this BigNumber rounded to sd significant digits
     * using rounding mode rm or ROUNDING_MODE. If sd is less than the number of digits
     * necessary to represent the integer part of the value in fixed-point notation, then use
     * exponential notation.
     *
     * [sd] {number} Significant digits. Integer, 1 to MAX inclusive.
     * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
     *
     * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {sd|rm}'
     */ P.toPrecision = function(sd, rm) {
            if (sd != null) intCheck(sd, 1, MAX);
            return format1(this, sd, rm, 2);
        };
        /*
     * Return a string representing the value of this BigNumber in base b, or base 10 if b is
     * omitted. If a base is specified, including base 10, round according to DECIMAL_PLACES and
     * ROUNDING_MODE. If a base is not specified, and this BigNumber has a positive exponent
     * that is equal to or greater than TO_EXP_POS, or a negative exponent equal to or less than
     * TO_EXP_NEG, return exponential notation.
     *
     * [b] {number} Integer, 2 to ALPHABET.length inclusive.
     *
     * '[BigNumber Error] Base {not a primitive number|not an integer|out of range}: {b}'
     */ P.toString = function(b) {
            var str, n = this, s = n.s, e = n.e;
            // Infinity or NaN?
            if (e === null) {
                if (s) {
                    str = 'Infinity';
                    if (s < 0) str = '-' + str;
                } else str = 'NaN';
            } else {
                if (b == null) str = e <= TO_EXP_NEG || e >= TO_EXP_POS ? toExponential(coeffToString(n.c), e) : toFixedPoint(coeffToString(n.c), e, '0');
                else if (b === 10) {
                    n = round(new BigNumber(n), DECIMAL_PLACES + e + 1, ROUNDING_MODE);
                    str = toFixedPoint(coeffToString(n.c), n.e, '0');
                } else {
                    intCheck(b, 2, ALPHABET.length, 'Base');
                    str = convertBase(toFixedPoint(coeffToString(n.c), e, '0'), 10, b, s, true);
                }
                if (s < 0 && n.c[0]) str = '-' + str;
            }
            return str;
        };
        /*
     * Return as toString, but do not accept a base argument, and include the minus sign for
     * negative zero.
     */ P.valueOf = P.toJSON = function() {
            return valueOf(this);
        };
        P._isBigNumber = true;
        if (configObject != null) BigNumber.set(configObject);
        return BigNumber;
    }
    // PRIVATE HELPER FUNCTIONS
    // These functions don't need access to variables,
    // e.g. DECIMAL_PLACES, in the scope of the `clone` function above.
    function bitFloor(n) {
        var i = n | 0;
        return n > 0 || n === i ? i : i - 1;
    }
    // Return a coefficient array as a string of base 10 digits.
    function coeffToString(a) {
        var s, z, i = 1, j = a.length, r = a[0] + '';
        for(; i < j;){
            s = a[i++] + '';
            z = LOG_BASE - s.length;
            for(; z--; s = '0' + s);
            r += s;
        }
        // Determine trailing zeros.
        for(j = r.length; r.charCodeAt(--j) === 48;);
        return r.slice(0, j + 1 || 1);
    }
    // Compare the value of BigNumbers x and y.
    function compare1(x, y) {
        var a, b, xc = x.c, yc = y.c, i = x.s, j = y.s, k = x.e, l = y.e;
        // Either NaN?
        if (!i || !j) return null;
        a = xc && !xc[0];
        b = yc && !yc[0];
        // Either zero?
        if (a || b) return a ? b ? 0 : -j : i;
        // Signs differ?
        if (i != j) return i;
        a = i < 0;
        b = k == l;
        // Either Infinity?
        if (!xc || !yc) return b ? 0 : !xc ^ a ? 1 : -1;
        // Compare exponents.
        if (!b) return k > l ^ a ? 1 : -1;
        j = (k = xc.length) < (l = yc.length) ? k : l;
        // Compare digit by digit.
        for(i = 0; i < j; i++)if (xc[i] != yc[i]) return xc[i] > yc[i] ^ a ? 1 : -1;
        // Compare lengths.
        return k == l ? 0 : k > l ^ a ? 1 : -1;
    }
    /*
   * Check that n is a primitive number, an integer, and in range, otherwise throw.
   */ function intCheck(n, min, max, name) {
        if (n < min || n > max || n !== mathfloor(n)) throw Error(bignumberError + (name || 'Argument') + (typeof n == 'number' ? n < min || n > max ? ' out of range: ' : ' not an integer: ' : ' not a primitive number: ') + String(n));
    }
    // Assumes finite n.
    function isOdd(n) {
        var k = n.c.length - 1;
        return bitFloor(n.e / LOG_BASE) == k && n.c[k] % 2 != 0;
    }
    function toExponential(str, e) {
        return (str.length > 1 ? str.charAt(0) + '.' + str.slice(1) : str) + (e < 0 ? 'e' : 'e+') + e;
    }
    function toFixedPoint(str, e, z) {
        var len, zs;
        // Negative exponent?
        if (e < 0) {
            // Prepend zeros.
            for(zs = z + '.'; ++e; zs += z);
            str = zs + str;
        // Positive exponent
        } else {
            len = str.length;
            // Append zeros.
            if (++e > len) {
                for(zs = z, e -= len; --e; zs += z);
                str += zs;
            } else if (e < len) str = str.slice(0, e) + '.' + str.slice(e);
        }
        return str;
    }
    // EXPORT
    BigNumber1 = clone();
    BigNumber1['default'] = BigNumber1.BigNumber = BigNumber1;
    // AMD.
    if (typeof define == 'function' && define.amd) define(function() {
        return BigNumber1;
    });
    else if (typeof module != 'undefined' && module.exports) module.exports = BigNumber1;
    else {
        if (!globalObject) globalObject = typeof self != 'undefined' && self ? self : window;
        globalObject.BigNumber = BigNumber1;
    }
})(this);

},{}],"fQFY3":[function(require,module,exports) {
'use strict';
const exp = Math.exp;
exports = module.exports = function MovingAverage(timespan) {
    if (typeof timespan !== 'number') throw new Error('must provide a timespan to the moving average constructor');
    if (timespan <= 0) throw new Error('must provide a timespan > 0 to the moving average constructor');
    let ma // moving average
    ;
    let v = 0 // variance
    ;
    let d = 0 // deviation
    ;
    let f = 0 // forecast
    ;
    let previousTime;
    let ret = {
    };
    function alpha(t, pt) {
        return 1 - exp(-(t - pt) / timespan);
    }
    ret.push = function push(time, value) {
        if (previousTime) {
            // calculate moving average
            const a = alpha(time, previousTime);
            const diff = value - ma;
            const incr = a * diff;
            ma = a * value + (1 - a) * ma;
            // calculate variance & deviation
            v = (1 - a) * (v + diff * incr);
            d = Math.sqrt(v);
            // calculate forecast
            f = ma + a * diff;
        } else ma = value;
        previousTime = time;
    };
    // Exponential Moving Average
    ret.movingAverage = function movingAverage() {
        return ma;
    };
    // Variance
    ret.variance = function variance() {
        return v;
    };
    ret.deviation = function deviation() {
        return d;
    };
    ret.forecast = function forecast() {
        return f;
    };
    return ret;
};

},{}],"2e64O":[function(require,module,exports) {
'use strict';
const debug = require('debug');
const log = Object.assign(debug('libp2p:upgrader'), {
    error: debug('libp2p:upgrader:err')
});
const errCode = require('err-code');
// @ts-ignore multistream-select does not export types
const Multistream = require('multistream-select');
const { Connection  } = require('libp2p-interfaces/src/connection');
const PeerId = require('peer-id');
const { pipe  } = require('it-pipe');
// @ts-ignore mutable-proxy does not export types
const mutableProxy = require('mutable-proxy');
const { codes  } = require('./errors');
/**
 * @typedef {import('libp2p-interfaces/src/transport/types').MultiaddrConnection} MultiaddrConnection
 * @typedef {import('libp2p-interfaces/src/stream-muxer/types').MuxerFactory} MuxerFactory
 * @typedef {import('libp2p-interfaces/src/stream-muxer/types').Muxer} Muxer
 * @typedef {import('libp2p-interfaces/src/stream-muxer/types').MuxedStream} MuxedStream
 * @typedef {import('libp2p-interfaces/src/crypto/types').Crypto} Crypto
 * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection
 * @typedef {import('multiaddr').Multiaddr} Multiaddr
 */ /**
 * @typedef CryptoResult
 * @property {MultiaddrConnection} conn A duplex iterable
 * @property {PeerId} remotePeer
 * @property {string} protocol
 */ class Upgrader {
    /**
   * @param {object} options
   * @param {PeerId} options.localPeer
   * @param {import('./metrics')} [options.metrics]
   * @param {Map<string, Crypto>} [options.cryptos]
   * @param {Map<string, MuxerFactory>} [options.muxers]
   * @param {(connection: Connection) => void} options.onConnection - Called when a connection is upgraded
   * @param {(connection: Connection) => void} options.onConnectionEnd
   */ constructor({ localPeer , metrics , cryptos =new Map() , muxers =new Map() , onConnectionEnd =()=>{
    } , onConnection =()=>{
    }  }){
        this.localPeer = localPeer;
        this.metrics = metrics;
        this.cryptos = cryptos;
        this.muxers = muxers;
        /** @type {import("./pnet") | null} */ this.protector = null;
        this.protocols = new Map();
        this.onConnection = onConnection;
        this.onConnectionEnd = onConnectionEnd;
    }
    /**
   * Upgrades an inbound connection
   *
   * @async
   * @param {MultiaddrConnection} maConn
   * @returns {Promise<Connection>}
   */ async upgradeInbound(maConn) {
        let encryptedConn;
        let remotePeer;
        let upgradedConn;
        let Muxer;
        let cryptoProtocol;
        let setPeer;
        let proxyPeer;
        if (this.metrics) {
            ({ setTarget: setPeer , proxy: proxyPeer  } = mutableProxy());
            const idString = (Math.random() * 1000000000).toString(36) + Date.now();
            setPeer({
                toB58String: ()=>idString
            });
            maConn = this.metrics.trackStream({
                stream: maConn,
                remotePeer: proxyPeer
            });
        }
        log('Starting the inbound connection upgrade');
        // Protect
        let protectedConn = maConn;
        if (this.protector) protectedConn = await this.protector.protect(maConn);
        try {
            ({ conn: encryptedConn , remotePeer , protocol: cryptoProtocol  } = await this._encryptInbound(this.localPeer, protectedConn, this.cryptos));
            // Multiplex the connection
            if (this.muxers.size) ({ stream: upgradedConn , Muxer  } = await this._multiplexInbound(encryptedConn, this.muxers));
            else upgradedConn = encryptedConn;
        } catch (err) {
            log.error('Failed to upgrade inbound connection', err);
            await maConn.close(err);
            throw err;
        }
        if (this.metrics) {
            this.metrics.updatePlaceholder(proxyPeer, remotePeer);
            setPeer(remotePeer);
        }
        log('Successfully upgraded inbound connection');
        return this._createConnection({
            cryptoProtocol,
            direction: 'inbound',
            maConn,
            upgradedConn,
            Muxer,
            remotePeer
        });
    }
    /**
   * Upgrades an outbound connection
   *
   * @async
   * @param {MultiaddrConnection} maConn
   * @returns {Promise<Connection>}
   */ async upgradeOutbound(maConn1) {
        const idStr = maConn1.remoteAddr.getPeerId();
        if (!idStr) throw errCode(new Error('outbound connection must have a peer id'), codes.ERR_INVALID_MULTIADDR);
        const remotePeerId = PeerId.createFromB58String(idStr);
        let encryptedConn;
        let remotePeer;
        let upgradedConn;
        let cryptoProtocol;
        let Muxer;
        let setPeer;
        let proxyPeer;
        if (this.metrics) {
            ({ setTarget: setPeer , proxy: proxyPeer  } = mutableProxy());
            const idString = (Math.random() * 1000000000).toString(36) + Date.now();
            setPeer({
                toB58String: ()=>idString
            });
            maConn1 = this.metrics.trackStream({
                stream: maConn1,
                remotePeer: proxyPeer
            });
        }
        log('Starting the outbound connection upgrade');
        // Protect
        let protectedConn = maConn1;
        if (this.protector) protectedConn = await this.protector.protect(maConn1);
        try {
            ({ conn: encryptedConn , remotePeer , protocol: cryptoProtocol  } = await this._encryptOutbound(this.localPeer, protectedConn, remotePeerId, this.cryptos));
            // Multiplex the connection
            if (this.muxers.size) ({ stream: upgradedConn , Muxer  } = await this._multiplexOutbound(encryptedConn, this.muxers));
            else upgradedConn = encryptedConn;
        } catch (err) {
            log.error('Failed to upgrade outbound connection', err);
            await maConn1.close(err);
            throw err;
        }
        if (this.metrics) {
            this.metrics.updatePlaceholder(proxyPeer, remotePeer);
            setPeer(remotePeer);
        }
        log('Successfully upgraded outbound connection');
        return this._createConnection({
            cryptoProtocol,
            direction: 'outbound',
            maConn: maConn1,
            upgradedConn,
            Muxer,
            remotePeer
        });
    }
    /**
   * A convenience method for generating a new `Connection`
   *
   * @private
   * @param {object} options
   * @param {string} options.cryptoProtocol - The crypto protocol that was negotiated
   * @param {'inbound' | 'outbound'} options.direction - One of ['inbound', 'outbound']
   * @param {MultiaddrConnection} options.maConn - The transport layer connection
   * @param {MuxedStream | MultiaddrConnection} options.upgradedConn - A duplex connection returned from multiplexer and/or crypto selection
   * @param {MuxerFactory} [options.Muxer] - The muxer to be used for muxing
   * @param {PeerId} options.remotePeer - The peer the connection is with
   * @returns {Connection}
   */ _createConnection({ cryptoProtocol , direction , maConn: maConn2 , upgradedConn , Muxer , remotePeer  }) {
        /** @type {import("libp2p-interfaces/src/stream-muxer/types").Muxer} */ let muxer;
        /** @type {import("libp2p-interfaces/src/connection/connection").CreatedMuxedStream | undefined} */ let newStream;
        /** @type {Connection} */ let connection // eslint-disable-line prefer-const
        ;
        if (Muxer) {
            // Create the muxer
            muxer = new Muxer({
                // Run anytime a remote stream is created
                onStream: async (muxedStream)=>{
                    if (!connection) return;
                    const mss = new Multistream.Listener(muxedStream);
                    try {
                        const { stream , protocol  } = await mss.handle(Array.from(this.protocols.keys()));
                        log('%s: incoming stream opened on %s', direction, protocol);
                        if (this.metrics) this.metrics.trackStream({
                            stream,
                            remotePeer,
                            protocol
                        });
                        connection.addStream(muxedStream, {
                            protocol
                        });
                        this._onStream({
                            connection,
                            stream: {
                                ...muxedStream,
                                ...stream
                            },
                            protocol
                        });
                    } catch (err) {
                        log.error(err);
                    }
                },
                // Run anytime a stream closes
                onStreamEnd: (muxedStream)=>{
                    connection.removeStream(muxedStream.id);
                }
            });
            newStream = async (protocols)=>{
                log('%s: starting new stream on %s', direction, protocols);
                const muxedStream = muxer.newStream();
                const mss = new Multistream.Dialer(muxedStream);
                try {
                    const { stream , protocol  } = await mss.select(protocols);
                    if (this.metrics) this.metrics.trackStream({
                        stream,
                        remotePeer,
                        protocol
                    });
                    return {
                        stream: {
                            ...muxedStream,
                            ...stream
                        },
                        protocol
                    };
                } catch (err) {
                    log.error('could not create new stream', err);
                    throw errCode(err, codes.ERR_UNSUPPORTED_PROTOCOL);
                }
            };
            // Pipe all data through the muxer
            pipe(upgradedConn, muxer, upgradedConn).catch(log.error);
        }
        const _timeline = maConn2.timeline;
        maConn2.timeline = new Proxy(_timeline, {
            set: (...args)=>{
                if (connection && args[1] === 'close' && args[2] && !_timeline.close) // Wait for close to finish before notifying of the closure
                (async ()=>{
                    try {
                        if (connection.stat.status === 'open') await connection.close();
                    } catch (err) {
                        log.error(err);
                    } finally{
                        this.onConnectionEnd(connection);
                    }
                })();
                return Reflect.set(...args);
            }
        });
        maConn2.timeline.upgraded = Date.now();
        const errConnectionNotMultiplexed = ()=>{
            throw errCode(new Error('connection is not multiplexed'), 'ERR_CONNECTION_NOT_MULTIPLEXED');
        };
        // Create the connection
        connection = new Connection({
            localAddr: maConn2.localAddr,
            remoteAddr: maConn2.remoteAddr,
            localPeer: this.localPeer,
            remotePeer: remotePeer,
            stat: {
                direction,
                // @ts-ignore
                timeline: maConn2.timeline,
                multiplexer: Muxer && Muxer.multicodec,
                encryption: cryptoProtocol
            },
            newStream: newStream || errConnectionNotMultiplexed,
            getStreams: ()=>muxer ? muxer.streams : errConnectionNotMultiplexed()
            ,
            close: async ()=>{
                await maConn2.close();
                // Ensure remaining streams are aborted
                if (muxer) muxer.streams.map((stream)=>stream.abort()
                );
            }
        });
        this.onConnection(connection);
        return connection;
    }
    /**
   * Routes incoming streams to the correct handler
   *
   * @private
   * @param {object} options
   * @param {Connection} options.connection - The connection the stream belongs to
   * @param {MuxedStream} options.stream
   * @param {string} options.protocol
   */ _onStream({ connection , stream , protocol  }) {
        const handler = this.protocols.get(protocol);
        handler({
            connection,
            stream,
            protocol
        });
    }
    /**
   * Attempts to encrypt the incoming `connection` with the provided `cryptos`.
   *
   * @private
   * @async
   * @param {PeerId} localPeer - The initiators PeerId
   * @param {*} connection
   * @param {Map<string, Crypto>} cryptos
   * @returns {Promise<CryptoResult>} An encrypted connection, remote peer `PeerId` and the protocol of the `Crypto` used
   */ async _encryptInbound(localPeer1, connection1, cryptos1) {
        const mss = new Multistream.Listener(connection1);
        const protocols = Array.from(cryptos1.keys());
        log('handling inbound crypto protocol selection', protocols);
        try {
            const { stream , protocol  } = await mss.handle(protocols);
            const crypto = cryptos1.get(protocol);
            log('encrypting inbound connection...');
            if (!crypto) throw new Error(`no crypto module found for ${protocol}`);
            return {
                ...await crypto.secureInbound(localPeer1, stream),
                protocol
            };
        } catch (err) {
            throw errCode(err, codes.ERR_ENCRYPTION_FAILED);
        }
    }
    /**
   * Attempts to encrypt the given `connection` with the provided `cryptos`.
   * The first `Crypto` module to succeed will be used
   *
   * @private
   * @async
   * @param {PeerId} localPeer - The initiators PeerId
   * @param {MultiaddrConnection} connection
   * @param {PeerId} remotePeerId
   * @param {Map<string, Crypto>} cryptos
   * @returns {Promise<CryptoResult>} An encrypted connection, remote peer `PeerId` and the protocol of the `Crypto` used
   */ async _encryptOutbound(localPeer2, connection2, remotePeerId, cryptos2) {
        const mss = new Multistream.Dialer(connection2);
        const protocols = Array.from(cryptos2.keys());
        log('selecting outbound crypto protocol', protocols);
        try {
            const { stream , protocol  } = await mss.select(protocols);
            const crypto = cryptos2.get(protocol);
            log('encrypting outbound connection to %j', remotePeerId);
            if (!crypto) throw new Error(`no crypto module found for ${protocol}`);
            return {
                ...await crypto.secureOutbound(localPeer2, stream, remotePeerId),
                protocol
            };
        } catch (err) {
            throw errCode(err, codes.ERR_ENCRYPTION_FAILED);
        }
    }
    /**
   * Selects one of the given muxers via multistream-select. That
   * muxer will be used for all future streams on the connection.
   *
   * @private
   * @async
   * @param {MultiaddrConnection} connection - A basic duplex connection to multiplex
   * @param {Map<string, MuxerFactory>} muxers - The muxers to attempt multiplexing with
   * @returns {Promise<{ stream: MuxedStream, Muxer?: MuxerFactory}>} A muxed connection
   */ async _multiplexOutbound(connection3, muxers1) {
        const dialer = new Multistream.Dialer(connection3);
        const protocols = Array.from(muxers1.keys());
        log('outbound selecting muxer %s', protocols);
        try {
            const { stream , protocol  } = await dialer.select(protocols);
            log('%s selected as muxer protocol', protocol);
            const Muxer = muxers1.get(protocol);
            return {
                stream,
                Muxer
            };
        } catch (err) {
            throw errCode(err, codes.ERR_MUXER_UNAVAILABLE);
        }
    }
    /**
   * Registers support for one of the given muxers via multistream-select. The
   * selected muxer will be used for all future streams on the connection.
   *
   * @private
   * @async
   * @param {MultiaddrConnection} connection - A basic duplex connection to multiplex
   * @param {Map<string, MuxerFactory>} muxers - The muxers to attempt multiplexing with
   * @returns {Promise<{ stream: MuxedStream, Muxer?: MuxerFactory}>} A muxed connection
   */ async _multiplexInbound(connection4, muxers2) {
        const listener = new Multistream.Listener(connection4);
        const protocols = Array.from(muxers2.keys());
        log('inbound handling muxers %s', protocols);
        try {
            const { stream , protocol  } = await listener.handle(protocols);
            const Muxer = muxers2.get(protocol);
            return {
                stream,
                Muxer
            };
        } catch (err) {
            throw errCode(err, codes.ERR_MUXER_UNAVAILABLE);
        }
    }
}
module.exports = Upgrader;

},{"debug":"lWlU4","err-code":"eQvyh","multistream-select":"9P4Ig","libp2p-interfaces/src/connection":"jrgAa","peer-id":"4VGWt","it-pipe":"4jukm","mutable-proxy":"hSrRp","./errors":"dO31S"}],"9P4Ig":[function(require,module,exports) {
'use strict';
const select = require('./select');
const handle = require('./handle');
const ls = require('./ls');
const { PROTOCOL_ID  } = require('./constants');
exports.PROTOCOL_ID = PROTOCOL_ID;
class MultistreamSelect {
    constructor(stream){
        this._stream = stream;
        this._shaken = false;
    }
    // Perform the multistream-select handshake
    async _handshake() {
        if (this._shaken) return;
        const { stream  } = await select(this._stream, PROTOCOL_ID);
        this._stream = stream;
        this._shaken = true;
    }
}
class Dialer extends MultistreamSelect {
    select(protocols) {
        return select(this._stream, protocols, this._shaken ? null : PROTOCOL_ID);
    }
    async ls() {
        await this._handshake();
        const { stream , protocols  } = await ls(this._stream);
        this._stream = stream;
        return protocols;
    }
}
exports.Dialer = Dialer;
class Listener extends MultistreamSelect {
    handle(protocols1) {
        return handle(this._stream, protocols1);
    }
}
exports.Listener = Listener;

},{"./select":"eygjT","./handle":"ryT0u","./ls":"7tTd6","./constants":"5yb2n"}],"eygjT":[function(require,module,exports) {
'use strict';
const log = require('debug')('mss:select');
const errCode = require('err-code');
const multistream = require('./multistream');
const handshake = require('it-handshake');
module.exports = async (stream, protocols, protocolId)=>{
    protocols = Array.isArray(protocols) ? [
        ...protocols
    ] : [
        protocols
    ];
    const { reader , writer , rest , stream: shakeStream  } = handshake(stream);
    const protocol = protocols.shift();
    if (protocolId) {
        log('select: write ["%s", "%s"]', protocolId, protocol);
        multistream.writeAll(writer, [
            protocolId,
            protocol
        ]);
    } else {
        log('select: write "%s"', protocol);
        multistream.write(writer, protocol);
    }
    let response = (await multistream.read(reader)).toString();
    log('select: read "%s"', response);
    // Read the protocol response if we got the protocolId in return
    if (response === protocolId) {
        response = (await multistream.read(reader)).toString();
        log('select: read "%s"', response);
    }
    // We're done
    if (response === protocol) {
        rest();
        return {
            stream: shakeStream,
            protocol
        };
    }
    // We haven't gotten a valid ack, try the other protocols
    for (const protocol1 of protocols){
        log('select: write "%s"', protocol1);
        multistream.write(writer, protocol1);
        const response = (await multistream.read(reader)).toString();
        log('select: read "%s" for "%s"', response, protocol1);
        if (response === protocol1) {
            rest() // End our writer so others can start writing to stream
            ;
            return {
                stream: shakeStream,
                protocol: protocol1
            };
        }
    }
    rest();
    throw errCode(new Error('protocol selection failed'), 'ERR_UNSUPPORTED_PROTOCOL');
};

},{"debug":"lWlU4","err-code":"eQvyh","./multistream":"gRq03","it-handshake":"gkdlr"}],"gRq03":[function(require,module,exports) {
'use strict';
const BufferList = require('bl/BufferList');
const lp = require('it-length-prefixed');
const pipe = require('it-pipe');
const errCode = require('err-code');
const { fromString: uint8ArrayFromString  } = require('uint8arrays/from-string');
const first = require('it-first');
const NewLine = uint8ArrayFromString('\n');
exports.encode = (buffer)=>lp.encode.single(new BufferList([
        buffer,
        NewLine
    ]))
;
// `write` encodes and writes a single buffer
exports.write = (writer, buffer)=>writer.push(exports.encode(buffer))
;
// `writeAll` behaves like `write`, except it encodes an array of items as a single write
exports.writeAll = (writer, buffers)=>{
    writer.push(buffers.reduce((bl, buffer)=>bl.append(exports.encode(buffer))
    , new BufferList()));
};
exports.read = async (reader)=>{
    let byteLength = 1 // Read single byte chunks until the length is known
    ;
    const varByteSource = {
        [Symbol.asyncIterator] () {
            return this;
        },
        next: ()=>reader.next(byteLength)
    };
    // Once the length has been parsed, read chunk for that length
    const onLength = (l)=>{
        byteLength = l;
    };
    const buf = await pipe(varByteSource, lp.decode({
        onLength
    }), first);
    if (buf.get(buf.length - 1) !== NewLine[0]) throw errCode(new Error('missing newline'), 'ERR_INVALID_MULTISTREAM_SELECT_MESSAGE');
    return buf.shallowSlice(0, -1) // Remove newline
    ;
};

},{"bl/BufferList":"cK5XN","it-length-prefixed":"2cvC1","it-pipe":"4jukm","err-code":"eQvyh","uint8arrays/from-string":"lo45E","it-first":"imIGO"}],"ryT0u":[function(require,module,exports) {
'use strict';
const log = require('debug')('mss:handle');
const BufferList = require('bl/BufferList');
const multistream = require('./multistream');
const handshake = require('it-handshake');
const { PROTOCOL_ID  } = require('./constants');
module.exports = async (stream, protocols)=>{
    protocols = Array.isArray(protocols) ? protocols : [
        protocols
    ];
    const { writer , reader , rest , stream: shakeStream  } = handshake(stream);
    while(true){
        const protocol = (await multistream.read(reader)).toString();
        log('read "%s"', protocol);
        if (protocol === PROTOCOL_ID) {
            log('respond with "%s" for "%s"', PROTOCOL_ID, protocol);
            multistream.write(writer, PROTOCOL_ID);
            continue;
        }
        if (protocols.includes(protocol)) {
            multistream.write(writer, protocol);
            log('respond with "%s" for "%s"', protocol, protocol);
            rest();
            return {
                stream: shakeStream,
                protocol
            };
        }
        if (protocol === 'ls') {
            // <varint-msg-len><varint-proto-name-len><proto-name>\n<varint-proto-name-len><proto-name>\n\n
            multistream.write(writer, new BufferList(protocols.map((p)=>multistream.encode(p)
            )));
            log('respond with "%s" for %s', protocols, protocol);
            continue;
        }
        multistream.write(writer, 'na');
        log('respond with "na" for "%s"', protocol);
    }
};

},{"debug":"lWlU4","bl/BufferList":"cK5XN","./multistream":"gRq03","it-handshake":"gkdlr","./constants":"5yb2n"}],"5yb2n":[function(require,module,exports) {
'use strict';
exports.PROTOCOL_ID = '/multistream/1.0.0';

},{}],"7tTd6":[function(require,module,exports) {
'use strict';
const Reader = require('it-reader');
const log = require('debug')('it-multistream-select:ls');
const multistream = require('./multistream');
const handshake = require('it-handshake');
const lp = require('it-length-prefixed');
const pipe = require('it-pipe');
module.exports = async (stream)=>{
    const { reader , writer , rest , stream: shakeStream  } = handshake(stream);
    log('write "ls"');
    multistream.write(writer, 'ls');
    rest();
    // Next message from remote will be (e.g. for 2 protocols):
    // <varint-msg-len><varint-proto-name-len><proto-name>\n<varint-proto-name-len><proto-name>\n
    const res = await multistream.read(reader);
    // After reading response we have:
    // <varint-proto-name-len><proto-name>\n<varint-proto-name-len><proto-name>\n
    const protocolsReader = Reader([
        res
    ]);
    const protocols = [];
    // Decode each of the protocols from the reader
    await pipe(protocolsReader, lp.decode(), async (source)=>{
        for await (const protocol of source)// Remove the newline
        protocols.push(protocol.shallowSlice(0, -1).toString());
    });
    return {
        stream: shakeStream,
        protocols
    };
};

},{"it-reader":"8Ef74","debug":"lWlU4","./multistream":"gRq03","it-handshake":"gkdlr","it-length-prefixed":"2cvC1","it-pipe":"4jukm"}],"jrgAa":[function(require,module,exports) {
'use strict';
exports.Connection = require('./connection');

},{"./connection":"2Qf7W"}],"2Qf7W":[function(require,module,exports) {
'use strict';
const PeerId = require('peer-id');
const { Multiaddr  } = require('multiaddr');
const errCode = require('err-code');
const { OPEN , CLOSING , CLOSED  } = require('./status');
const connectionSymbol = Symbol.for('@libp2p/interface-connection/connection');
/**
 * @typedef {import('../stream-muxer/types').MuxedStream} MuxedStream
 * @typedef {import('./status').Status} Status
 */ /**
 * @typedef {Object} Timeline
 * @property {number} open - connection opening timestamp.
 * @property {number} [upgraded] - connection upgraded timestamp.
 * @property {number} [close]
 *
 * @typedef {Object} ConectionStat
 * @property {'inbound' | 'outbound'} direction - connection establishment direction
 * @property {Timeline} timeline - connection relevant events timestamp.
 * @property {string} [multiplexer] - connection multiplexing identifier.
 * @property {string} [encryption] - connection encryption method identifier.
 *
 * @typedef {(protocols: string|string[]) => Promise<{stream: MuxedStream, protocol: string}>} CreatedMuxedStream
 *
 * @typedef {Object} ConnectionOptions
 * @property {Multiaddr} [localAddr] - local multiaddr of the connection if known.
 * @property {Multiaddr} remoteAddr - remote multiaddr of the connection.
 * @property {PeerId} localPeer - local peer-id.
 * @property {PeerId} remotePeer - remote peer-id.
 * @property {CreatedMuxedStream} newStream - new stream muxer function.
 * @property {() => Promise<void>} close - close raw connection function.
 * @property {() => MuxedStream[]} getStreams - get streams from muxer function.
 * @property {ConectionStat} stat - metadata of the connection.
 *
 * @typedef {Object} StreamData
 * @property {string} protocol - the protocol used by the stream
 * @property {Object} [metadata] - metadata of the stream
 */ /**
 * An implementation of the js-libp2p connection.
 * Any libp2p transport should use an upgrader to return this connection.
 */ class Connection {
    /**
   * An implementation of the js-libp2p connection.
   * Any libp2p transport should use an upgrader to return this connection.
   *
   * @class
   * @param {ConnectionOptions} options
   */ constructor({ localAddr: localAddr1 , remoteAddr , localPeer: localPeer1 , remotePeer: remotePeer1 , newStream: newStream1 , close: close1 , getStreams: getStreams1 , stat: stat1  }){
        validateArgs(localAddr1, localPeer1, remotePeer1, newStream1, close1, getStreams1, stat1);
        /**
     * Connection identifier.
     */ this.id = parseInt(String(Math.random() * 1000000000)).toString(36) + Date.now();
        /**
     * Observed multiaddr of the local peer
     */ this.localAddr = localAddr1;
        /**
     * Observed multiaddr of the remote peer
     */ this.remoteAddr = remoteAddr;
        /**
     * Local peer id.
     */ this.localPeer = localPeer1;
        /**
     * Remote peer id.
     */ this.remotePeer = remotePeer1;
        /**
     * Connection metadata.
     *
     * @type {ConectionStat & {status: Status}}
     */ this._stat = {
            ...stat1,
            status: OPEN
        };
        /**
     * Reference to the new stream function of the multiplexer
     */ this._newStream = newStream1;
        /**
     * Reference to the close function of the raw connection
     */ this._close = close1;
        /**
     * Reference to the getStreams function of the muxer
     */ this._getStreams = getStreams1;
        /**
     * Connection streams registry
     */ this.registry = new Map();
        /**
     * User provided tags
     *
     * @type {string[]}
     */ this.tags = [];
    }
    get [Symbol.toStringTag]() {
        return 'Connection';
    }
    get [connectionSymbol]() {
        return true;
    }
    /**
   * Checks if the given value is a `Connection` instance.
   *
   * @param {any} other
   * @returns {other is Connection}
   */ static isConnection(other) {
        return Boolean(other && other[connectionSymbol]);
    }
    /**
   * Get connection metadata
   *
   * @this {Connection}
   */ get stat() {
        return this._stat;
    }
    /**
   * Get all the streams of the muxer.
   *
   * @this {Connection}
   */ get streams() {
        return this._getStreams();
    }
    /**
   * Create a new stream from this connection
   *
   * @param {string|string[]} protocols - intended protocol for the stream
   * @returns {Promise<{stream: MuxedStream, protocol: string}>} with muxed+multistream-selected stream and selected protocol
   */ async newStream(protocols) {
        if (this.stat.status === CLOSING) throw errCode(new Error('the connection is being closed'), 'ERR_CONNECTION_BEING_CLOSED');
        if (this.stat.status === CLOSED) throw errCode(new Error('the connection is closed'), 'ERR_CONNECTION_CLOSED');
        if (!Array.isArray(protocols)) protocols = [
            protocols
        ];
        const { stream , protocol  } = await this._newStream(protocols);
        this.addStream(stream, {
            protocol
        });
        return {
            stream,
            protocol
        };
    }
    /**
   * Add a stream when it is opened to the registry.
   *
   * @param {MuxedStream} muxedStream - a muxed stream
   * @param {StreamData} data - the stream data to be registered
   * @returns {void}
   */ addStream(muxedStream, { protocol , metadata ={
    }  }) {
        // Add metadata for the stream
        this.registry.set(muxedStream.id, {
            protocol,
            ...metadata
        });
    }
    /**
   * Remove stream registry after it is closed.
   *
   * @param {string} id - identifier of the stream
   */ removeStream(id) {
        this.registry.delete(id);
    }
    /**
   * Close the connection.
   *
   * @returns {Promise<void>}
   */ async close() {
        if (this.stat.status === CLOSED) return;
        if (this._closing) return this._closing;
        this.stat.status = CLOSING;
        // Close raw connection
        this._closing = await this._close();
        this._stat.timeline.close = Date.now();
        this.stat.status = CLOSED;
    }
}
module.exports = Connection;
/**
 * @param {Multiaddr|undefined} localAddr
 * @param {PeerId} localPeer
 * @param {PeerId} remotePeer
 * @param {(protocols: string | string[]) => Promise<{ stream: import("../stream-muxer/types").MuxedStream; protocol: string; }>} newStream
 * @param {() => Promise<void>} close
 * @param {() => import("../stream-muxer/types").MuxedStream[]} getStreams
 * @param {{ direction: any; timeline: any; multiplexer?: string | undefined; encryption?: string | undefined; }} stat
 */ function validateArgs(localAddr, localPeer, remotePeer, newStream, close, getStreams, stat) {
    if (localAddr && !Multiaddr.isMultiaddr(localAddr)) throw errCode(new Error('localAddr must be an instance of multiaddr'), 'ERR_INVALID_PARAMETERS');
    if (!PeerId.isPeerId(localPeer)) throw errCode(new Error('localPeer must be an instance of peer-id'), 'ERR_INVALID_PARAMETERS');
    if (!PeerId.isPeerId(remotePeer)) throw errCode(new Error('remotePeer must be an instance of peer-id'), 'ERR_INVALID_PARAMETERS');
    if (typeof newStream !== 'function') throw errCode(new Error('new stream must be a function'), 'ERR_INVALID_PARAMETERS');
    if (typeof close !== 'function') throw errCode(new Error('close must be a function'), 'ERR_INVALID_PARAMETERS');
    if (typeof getStreams !== 'function') throw errCode(new Error('getStreams must be a function'), 'ERR_INVALID_PARAMETERS');
    if (!stat) throw errCode(new Error('connection metadata object must be provided'), 'ERR_INVALID_PARAMETERS');
    if (stat.direction !== 'inbound' && stat.direction !== 'outbound') throw errCode(new Error('direction must be "inbound" or "outbound"'), 'ERR_INVALID_PARAMETERS');
    if (!stat.timeline) throw errCode(new Error('connection timeline object must be provided in the stat object'), 'ERR_INVALID_PARAMETERS');
    if (!stat.timeline.open) throw errCode(new Error('connection open timestamp must be provided'), 'ERR_INVALID_PARAMETERS');
    if (!stat.timeline.upgraded) throw errCode(new Error('connection upgraded timestamp must be provided'), 'ERR_INVALID_PARAMETERS');
}

},{"peer-id":"4VGWt","multiaddr":"kOPrF","err-code":"eQvyh","./status":"dAU8u"}],"dAU8u":[function(require,module,exports) {
'use strict';
const STATUS = {
    OPEN: 'open',
    CLOSING: 'closing',
    CLOSED: 'closed'
};
module.exports = STATUS /**
 * @typedef {STATUS[keyof STATUS]} Status
 */ ;

},{}],"hSrRp":[function(require,module,exports) {
'use strict';
function _toConsumableArray(arr) {
    if (Array.isArray(arr)) {
        for(var i = 0, arr2 = Array(arr.length); i < arr.length; i++)arr2[i] = arr[i];
        return arr2;
    } else return Array.from(arr);
}
module.exports = function mutableProxyFactory(defaultTarget) {
    var mutableHandler = void 0;
    var mutableTarget = void 0;
    function setTarget(target) {
        if (!(target instanceof Object)) throw new Error('Target "' + target + '" is not an object');
        mutableTarget = target;
    }
    function setHandler(handler) {
        Object.keys(handler).forEach(function(key) {
            var value = handler[key];
            if (typeof value !== 'function') throw new Error('Trap "' + key + ': ' + value + '" is not a function');
            if (!Reflect[key]) throw new Error('Trap "' + key + ': ' + value + '" is not a valid trap');
        });
        mutableHandler = handler;
    }
    setTarget(function() {
    });
    if (defaultTarget) setTarget(defaultTarget);
    setHandler(Reflect);
    // Dynamically forward all the traps to the associated methods on the mutable handler
    var handler1 = new Proxy({
    }, {
        get: function get(target, property) {
            return function() {
                for(var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++)args[_key] = arguments[_key];
                return mutableHandler[property].apply(null, [
                    mutableTarget
                ].concat(_toConsumableArray(args.slice(1))));
            };
        }
    });
    return {
        setTarget: setTarget,
        setHandler: setHandler,
        getTarget: function getTarget() {
            return mutableTarget;
        },
        getHandler: function getHandler() {
            return mutableHandler;
        },
        proxy: new Proxy(mutableTarget, handler1)
    };
};

},{}],"SedIN":[function(require,module,exports) {
'use strict';
const errcode = require('err-code');
const { EventEmitter  } = require('events');
const PeerId = require('peer-id');
const AddressBook = require('./address-book');
const KeyBook = require('./key-book');
const MetadataBook = require('./metadata-book');
const ProtoBook = require('./proto-book');
const { codes: { ERR_INVALID_PARAMETERS  }  } = require('../errors');
/**
 * @typedef {import('./address-book').Address} Address
 */ /**
 * @extends {EventEmitter}
 *
 * @fires PeerStore#peer Emitted when a new peer is added.
 * @fires PeerStore#change:protocols Emitted when a known peer supports a different set of protocols.
 * @fires PeerStore#change:multiaddrs Emitted when a known peer has a different set of multiaddrs.
 * @fires PeerStore#change:pubkey Emitted emitted when a peer's public key is known.
 * @fires PeerStore#change:metadata Emitted when the known metadata of a peer change.
 */ class PeerStore extends EventEmitter {
    /**
   * Peer object
   *
   * @typedef {Object} Peer
   * @property {PeerId} id peer's peer-id instance.
   * @property {Address[]} addresses peer's addresses containing its multiaddrs and metadata.
   * @property {string[]} protocols peer's supported protocols.
   * @property {Map<string, Uint8Array>|undefined} metadata peer's metadata map.
   */ /**
   * Responsible for managing known peers, as well as their addresses, protocols and metadata.
   *
   * @param {object} options
   * @param {PeerId} options.peerId
   * @class
   */ constructor({ peerId  }){
        super();
        this._peerId = peerId;
        /**
     * AddressBook containing a map of peerIdStr to Address.
     */ this.addressBook = new AddressBook(this);
        /**
     * KeyBook containing a map of peerIdStr to their PeerId with public keys.
     */ this.keyBook = new KeyBook(this);
        /**
     * MetadataBook containing a map of peerIdStr to their metadata Map.
     */ this.metadataBook = new MetadataBook(this);
        /**
     * ProtoBook containing a map of peerIdStr to supported protocols.
     */ this.protoBook = new ProtoBook(this);
    }
    /**
   * Start the PeerStore.
   */ start() {
    }
    /**
   * Stop the PeerStore.
   */ stop() {
    }
    /**
   * Get all the stored information of every peer known.
   *
   * @returns {Map<string, Peer>}
   */ get peers() {
        const storedPeers = new Set([
            ...this.addressBook.data.keys(),
            ...this.keyBook.data.keys(),
            ...this.protoBook.data.keys(),
            ...this.metadataBook.data.keys()
        ]);
        // Remove self peer if present
        this._peerId && storedPeers.delete(this._peerId.toB58String());
        const peersData = new Map();
        storedPeers.forEach((idStr)=>{
            peersData.set(idStr, this.get(PeerId.createFromB58String(idStr)));
        });
        return peersData;
    }
    /**
   * Delete the information of the given peer in every book.
   *
   * @param {PeerId} peerId
   * @returns {boolean} true if found and removed
   */ delete(peerId1) {
        const addressesDeleted = this.addressBook.delete(peerId1);
        const keyDeleted = this.keyBook.delete(peerId1);
        const protocolsDeleted = this.protoBook.delete(peerId1);
        const metadataDeleted = this.metadataBook.delete(peerId1);
        return addressesDeleted || keyDeleted || protocolsDeleted || metadataDeleted;
    }
    /**
   * Get the stored information of a given peer.
   *
   * @param {PeerId} peerId
   * @returns {Peer|undefined}
   */ get(peerId2) {
        if (!PeerId.isPeerId(peerId2)) throw errcode(new Error('peerId must be an instance of peer-id'), ERR_INVALID_PARAMETERS);
        const id = this.keyBook.data.get(peerId2.toB58String());
        const addresses = this.addressBook.get(peerId2);
        const metadata = this.metadataBook.get(peerId2);
        const protocols = this.protoBook.get(peerId2);
        if (!id && !addresses && !metadata && !protocols) return undefined;
        return {
            id: id || peerId2,
            addresses: addresses || [],
            protocols: protocols || [],
            metadata: metadata
        };
    }
}
module.exports = PeerStore;

},{"err-code":"eQvyh","events":"bHM3D","peer-id":"4VGWt","./address-book":"exdGM","./key-book":"4GElX","./metadata-book":"8vIzv","./proto-book":"JBthV","../errors":"dO31S"}],"exdGM":[function(require,module,exports) {
'use strict';
const debug = require('debug');
const log = Object.assign(debug('libp2p:peer-store:address-book'), {
    error: debug('libp2p:peer-store:address-book:err')
});
const errcode = require('err-code');
const { Multiaddr  } = require('multiaddr');
const PeerId = require('peer-id');
const Book = require('./book');
const PeerRecord = require('../record/peer-record');
const { codes: { ERR_INVALID_PARAMETERS  }  } = require('../errors');
const Envelope = require('../record/envelope');
/**
 * @typedef {import('./')} PeerStore
 */ /**
 * @typedef {Object} Address
 * @property {Multiaddr} multiaddr peer multiaddr.
 * @property {boolean} isCertified obtained from a signed peer record.
 *
 * @typedef {Object} CertifiedRecord
 * @property {Uint8Array} raw raw envelope.
 * @property {number} seqNumber seq counter.
 *
 * @typedef {Object} Entry
 * @property {Address[]} addresses peer Addresses.
 * @property {CertifiedRecord} record certified peer record.
 */ /**
 * @extends {Book}
 */ class AddressBook extends Book {
    /**
   * The AddressBook is responsible for keeping the known multiaddrs of a peer.
   *
   * @class
   * @param {PeerStore} peerStore
   */ constructor(peerStore){
        /**
     * PeerStore Event emitter, used by the AddressBook to emit:
     * "peer" - emitted when a peer is discovered by the node.
     * "change:multiaddrs" - emitted when the known multiaddrs of a peer change.
     */ super({
            peerStore,
            eventName: 'change:multiaddrs',
            eventProperty: 'multiaddrs',
            eventTransformer: (data)=>{
                if (!data.addresses) return [];
                return data.addresses.map((/** @type {Address} */ address)=>address.multiaddr
                );
            }
        });
        /**
     * Map known peers to their known Address Entries.
     *
     * @type {Map<string, Entry>}
     */ this.data = new Map();
    }
    /**
   * ConsumePeerRecord adds addresses from a signed peer record contained in a record envelope.
   * This will return a boolean that indicates if the record was successfully processed and added
   * into the AddressBook.
   *
   * @param {Envelope} envelope
   * @returns {boolean}
   */ consumePeerRecord(envelope) {
        let peerRecord;
        try {
            peerRecord = PeerRecord.createFromProtobuf(envelope.payload);
        } catch (err) {
            log.error('invalid peer record received');
            return false;
        }
        // Verify peerId
        if (!peerRecord.peerId.equals(envelope.peerId)) {
            log('signing key does not match PeerId in the PeerRecord');
            return false;
        }
        // ensure the record has multiaddrs
        if (!peerRecord.multiaddrs || !peerRecord.multiaddrs.length) return false;
        const peerId = peerRecord.peerId;
        const id = peerId.toB58String();
        const entry = this.data.get(id) || {
            record: undefined
        };
        const storedRecord = entry.record;
        // ensure seq is greater than, or equal to, the last received
        if (storedRecord && storedRecord.seqNumber >= peerRecord.seqNumber) return false;
        const addresses = this._toAddresses(peerRecord.multiaddrs, true);
        // Replace unsigned addresses by the new ones from the record
        // TODO: Once we have ttls for the addresses, we should merge these in.
        this._setData(peerId, {
            addresses,
            record: {
                raw: envelope.marshal(),
                seqNumber: peerRecord.seqNumber
            }
        });
        log(`stored provided peer record for ${id}`);
        return true;
    }
    /**
   * Get the raw Envelope for a peer. Returns
   * undefined if no Envelope is found.
   *
   * @param {PeerId} peerId
   * @returns {Uint8Array|undefined}
   */ getRawEnvelope(peerId) {
        const entry = this.data.get(peerId.toB58String());
        if (!entry || !entry.record || !entry.record.raw) return undefined;
        return entry.record.raw;
    }
    /**
   * Get an Envelope containing a PeerRecord for the given peer.
   * Returns undefined if no record exists.
   *
   * @param {PeerId} peerId
   * @returns {Promise<Envelope|void>|undefined}
   */ getPeerRecord(peerId1) {
        const raw = this.getRawEnvelope(peerId1);
        if (!raw) return undefined;
        return Envelope.createFromProtobuf(raw);
    }
    /**
   * Set known multiaddrs of a provided peer.
   * This will replace previously stored multiaddrs, if available.
   * Replacing stored multiaddrs might result in losing obtained certified addresses.
   * If you are not sure, it's recommended to use `add` instead.
   *
   * @override
   * @param {PeerId} peerId
   * @param {Multiaddr[]} multiaddrs
   * @returns {AddressBook}
   */ set(peerId2, multiaddrs) {
        if (!PeerId.isPeerId(peerId2)) {
            log.error('peerId must be an instance of peer-id to store data');
            throw errcode(new Error('peerId must be an instance of peer-id'), ERR_INVALID_PARAMETERS);
        }
        const addresses = this._toAddresses(multiaddrs);
        // Not replace multiaddrs
        if (!addresses.length) return this;
        const id = peerId2.toB58String();
        const entry = this.data.get(id);
        // Already knows the peer
        if (entry && entry.addresses && entry.addresses.length === addresses.length) {
            const intersection = entry.addresses.filter((addr)=>addresses.some((newAddr)=>addr.multiaddr.equals(newAddr.multiaddr)
                )
            );
            // Are new addresses equal to the old ones?
            // If yes, no changes needed!
            if (intersection.length === entry.addresses.length) {
                log(`the addresses provided to store are equal to the already stored for ${id}`);
                return this;
            }
        }
        this._setData(peerId2, {
            addresses,
            record: entry && entry.record
        });
        log(`stored provided multiaddrs for ${id}`);
        // Notify the existance of a new peer
        if (!entry) this._ps.emit('peer', peerId2);
        return this;
    }
    /**
   * Add known addresses of a provided peer.
   * If the peer is not known, it is set with the given addresses.
   *
   * @param {PeerId} peerId
   * @param {Multiaddr[]} multiaddrs
   * @returns {AddressBook}
   */ add(peerId3, multiaddrs1) {
        if (!PeerId.isPeerId(peerId3)) {
            log.error('peerId must be an instance of peer-id to store data');
            throw errcode(new Error('peerId must be an instance of peer-id'), ERR_INVALID_PARAMETERS);
        }
        const addresses = this._toAddresses(multiaddrs1);
        const id = peerId3.toB58String();
        // No addresses to be added
        if (!addresses.length) return this;
        const entry = this.data.get(id);
        if (entry && entry.addresses) {
            // Add recorded uniquely to the new array (Union)
            entry.addresses.forEach((addr)=>{
                if (!addresses.find((r)=>r.multiaddr.equals(addr.multiaddr)
                )) addresses.push(addr);
            });
            // If the recorded length is equal to the new after the unique union
            // The content is the same, no need to update.
            if (entry.addresses.length === addresses.length) {
                log(`the addresses provided to store are already stored for ${id}`);
                return this;
            }
        }
        this._setData(peerId3, {
            addresses,
            record: entry && entry.record
        });
        log(`added provided multiaddrs for ${id}`);
        // Notify the existance of a new peer
        if (!(entry && entry.addresses)) this._ps.emit('peer', peerId3);
        return this;
    }
    /**
   * Get the known data of a provided peer.
   *
   * @override
   * @param {PeerId} peerId
   * @returns {Address[]|undefined}
   */ get(peerId4) {
        if (!PeerId.isPeerId(peerId4)) throw errcode(new Error('peerId must be an instance of peer-id'), ERR_INVALID_PARAMETERS);
        const entry = this.data.get(peerId4.toB58String());
        return entry && entry.addresses ? [
            ...entry.addresses
        ] : undefined;
    }
    /**
   * Transforms received multiaddrs into Address.
   *
   * @private
   * @param {Multiaddr[]} multiaddrs
   * @param {boolean} [isCertified]
   * @returns {Address[]}
   */ _toAddresses(multiaddrs2, isCertified = false) {
        if (!multiaddrs2) {
            log.error('multiaddrs must be provided to store data');
            throw errcode(new Error('multiaddrs must be provided'), ERR_INVALID_PARAMETERS);
        }
        // create Address for each address
        /** @type {Address[]} */ const addresses = [];
        multiaddrs2.forEach((addr)=>{
            if (!Multiaddr.isMultiaddr(addr)) {
                log.error(`multiaddr ${addr} must be an instance of multiaddr`);
                throw errcode(new Error(`multiaddr ${addr} must be an instance of multiaddr`), ERR_INVALID_PARAMETERS);
            }
            // Guarantee no replicates
            if (!addresses.find((a)=>a.multiaddr.equals(addr)
            )) addresses.push({
                multiaddr: addr,
                isCertified
            });
        });
        return addresses;
    }
    /**
   * Get the known multiaddrs for a given peer. All returned multiaddrs
   * will include the encapsulated `PeerId` of the peer.
   * Returns `undefined` if there are no known multiaddrs for the given peer.
   *
   * @param {PeerId} peerId
   * @param {(addresses: Address[]) => Address[]} [addressSorter]
   * @returns {Multiaddr[]|undefined}
   */ getMultiaddrsForPeer(peerId5, addressSorter = (ms)=>ms
    ) {
        if (!PeerId.isPeerId(peerId5)) throw errcode(new Error('peerId must be an instance of peer-id'), ERR_INVALID_PARAMETERS);
        const entry = this.data.get(peerId5.toB58String());
        if (!entry || !entry.addresses) return undefined;
        return addressSorter(entry.addresses || []).map((address)=>{
            const multiaddr = address.multiaddr;
            const idString = multiaddr.getPeerId();
            if (idString && idString === peerId5.toB58String()) return multiaddr;
            return multiaddr.encapsulate(`/p2p/${peerId5.toB58String()}`);
        });
    }
}
module.exports = AddressBook;

},{"debug":"lWlU4","err-code":"eQvyh","multiaddr":"kOPrF","peer-id":"4VGWt","./book":"3k32Y","../record/peer-record":"2gkB6","../errors":"dO31S","../record/envelope":"dFiHn"}],"3k32Y":[function(require,module,exports) {
'use strict';
const errcode = require('err-code');
const PeerId = require('peer-id');
const { codes: { ERR_INVALID_PARAMETERS  }  } = require('../errors');
/**
 * @param {any} data
 */ const passthrough = (data)=>data
;
/**
 * @typedef {import('./')} PeerStore
 */ class Book {
    /**
   * The Book is the skeleton for the PeerStore books.
   *
   * @class
   * @param {Object} properties
   * @param {PeerStore} properties.peerStore - PeerStore instance.
   * @param {string} properties.eventName - Name of the event to emit by the PeerStore.
   * @param {string} properties.eventProperty - Name of the property to emit by the PeerStore.
   * @param {(data: any) => any[]} [properties.eventTransformer] - Transformer function of the provided data for being emitted.
   */ constructor({ peerStore , eventName , eventProperty , eventTransformer =passthrough  }){
        this._ps = peerStore;
        this.eventName = eventName;
        this.eventProperty = eventProperty;
        this.eventTransformer = eventTransformer;
        /**
     * Map known peers to their data.
     *
     * @type {Map<string, any[]|any>}
     */ this.data = new Map();
    }
    /**
   * Set known data of a provided peer.
   *
   * @param {PeerId} peerId
   * @param {any[]|any} data
   */ set(peerId, data) {
        throw errcode(new Error('set must be implemented by the subclass'), 'ERR_NOT_IMPLEMENTED');
    }
    /**
   * Set data into the datastructure, persistence and emit it using the provided transformers.
   *
   * @protected
   * @param {PeerId} peerId - peerId of the data to store
   * @param {any} data - data to store.
   * @param {Object} [options] - storing options.
   * @param {boolean} [options.emit = true] - emit the provided data.
   * @returns {void}
   */ _setData(peerId1, data1, { emit =true  } = {
    }) {
        const b58key = peerId1.toB58String();
        // Store data in memory
        this.data.set(b58key, data1);
        // Emit event
        emit && this._emit(peerId1, data1);
    }
    /**
   * Emit data.
   *
   * @protected
   * @param {PeerId} peerId
   * @param {any} [data]
   */ _emit(peerId2, data2) {
        this._ps.emit(this.eventName, {
            peerId: peerId2,
            [this.eventProperty]: this.eventTransformer(data2)
        });
    }
    /**
   * Get the known data of a provided peer.
   * Returns `undefined` if there is no available data for the given peer.
   *
   * @param {PeerId} peerId
   * @returns {any[]|any|undefined}
   */ get(peerId3) {
        if (!PeerId.isPeerId(peerId3)) throw errcode(new Error('peerId must be an instance of peer-id'), ERR_INVALID_PARAMETERS);
        const rec = this.data.get(peerId3.toB58String());
        // @ts-ignore
        return rec ? [
            ...rec
        ] : undefined;
    }
    /**
   * Deletes the provided peer from the book.
   *
   * @param {PeerId} peerId
   * @returns {boolean}
   */ delete(peerId4) {
        if (!PeerId.isPeerId(peerId4)) throw errcode(new Error('peerId must be an instance of peer-id'), ERR_INVALID_PARAMETERS);
        if (!this.data.delete(peerId4.toB58String())) return false;
        this._emit(peerId4, []);
        return true;
    }
}
module.exports = Book;

},{"err-code":"eQvyh","peer-id":"4VGWt","../errors":"dO31S"}],"4GElX":[function(require,module,exports) {
'use strict';
const debug = require('debug');
const log = Object.assign(debug('libp2p:peer-store:key-book'), {
    error: debug('libp2p:peer-store:key-book:err')
});
const errcode = require('err-code');
const PeerId = require('peer-id');
const Book = require('./book');
const { codes: { ERR_INVALID_PARAMETERS  }  } = require('../errors');
/**
 * @typedef {import('./')} PeerStore
 * @typedef {import('libp2p-crypto').PublicKey} PublicKey
 */ /**
 * @extends {Book}
 */ class KeyBook extends Book {
    /**
   * The KeyBook is responsible for keeping the known public keys of a peer.
   *
   * @class
   * @param {PeerStore} peerStore
   */ constructor(peerStore){
        super({
            peerStore,
            eventName: 'change:pubkey',
            eventProperty: 'pubkey',
            eventTransformer: (data)=>data.pubKey
        });
        /**
     * Map known peers to their known Public Key.
     *
     * @type {Map<string, PeerId>}
     */ this.data = new Map();
    }
    /**
   * Set the Peer public key.
   *
   * @override
   * @param {PeerId} peerId
   * @param {PublicKey} publicKey
   * @returns {KeyBook}
   */ set(peerId, publicKey) {
        if (!PeerId.isPeerId(peerId)) {
            log.error('peerId must be an instance of peer-id to store data');
            throw errcode(new Error('peerId must be an instance of peer-id'), ERR_INVALID_PARAMETERS);
        }
        const id = peerId.toB58String();
        const recPeerId = this.data.get(id);
        // If no record available, and this is valid
        if (!recPeerId && publicKey) {
            // This might be unecessary, but we want to store the PeerId
            // to avoid an async operation when reconstructing the PeerId
            peerId.pubKey = publicKey;
            this._setData(peerId, peerId);
            log(`stored provided public key for ${id}`);
        }
        return this;
    }
    /**
   * Get Public key of the given PeerId, if stored.
   *
   * @override
   * @param {PeerId} peerId
   * @returns {PublicKey | undefined}
   */ get(peerId1) {
        if (!PeerId.isPeerId(peerId1)) throw errcode(new Error('peerId must be an instance of peer-id'), ERR_INVALID_PARAMETERS);
        const rec = this.data.get(peerId1.toB58String());
        return rec ? rec.pubKey : undefined;
    }
}
module.exports = KeyBook;

},{"debug":"lWlU4","err-code":"eQvyh","peer-id":"4VGWt","./book":"3k32Y","../errors":"dO31S"}],"8vIzv":[function(require,module,exports) {
'use strict';
const debug = require('debug');
const log = Object.assign(debug('libp2p:peer-store:proto-book'), {
    error: debug('libp2p:peer-store:proto-book:err')
});
const errcode = require('err-code');
const { equals: uint8ArrayEquals  } = require('uint8arrays/equals');
const PeerId = require('peer-id');
const Book = require('./book');
const { codes: { ERR_INVALID_PARAMETERS  }  } = require('../errors');
/**
 * @typedef {import('./')} PeerStore
 */ /**
 * @extends {Book}
 *
 * @fires MetadataBook#change:metadata
 */ class MetadataBook extends Book {
    /**
   * The MetadataBook is responsible for keeping the known supported
   * protocols of a peer.
   *
   * @class
   * @param {PeerStore} peerStore
   */ constructor(peerStore){
        /**
     * PeerStore Event emitter, used by the MetadataBook to emit:
     * "change:metadata" - emitted when the known metadata of a peer change.
     */ super({
            peerStore,
            eventName: 'change:metadata',
            eventProperty: 'metadata'
        });
        /**
     * Map known peers to their known protocols.
     *
     * @type {Map<string, Map<string, Uint8Array>>}
     */ this.data = new Map();
    }
    /**
   * Set metadata key and value of a provided peer.
   *
   * @override
   * @param {PeerId} peerId
   * @param {string} key - metadata key
   * @param {Uint8Array} value - metadata value
   * @returns {MetadataBook}
   */ // @ts-ignore override with more then the parameters expected in Book
    set(peerId, key, value) {
        if (!PeerId.isPeerId(peerId)) {
            log.error('peerId must be an instance of peer-id to store data');
            throw errcode(new Error('peerId must be an instance of peer-id'), ERR_INVALID_PARAMETERS);
        }
        if (typeof key !== 'string' || !(value instanceof Uint8Array)) {
            log.error('valid key and value must be provided to store data');
            throw errcode(new Error('valid key and value must be provided'), ERR_INVALID_PARAMETERS);
        }
        this._setValue(peerId, key, value);
        return this;
    }
    /**
   * Set data into the datastructure
   *
   * @override
   * @param {PeerId} peerId
   * @param {string} key
   * @param {Uint8Array} value
   */ _setValue(peerId1, key1, value1, { emit =true  } = {
    }) {
        const id = peerId1.toB58String();
        const rec = this.data.get(id) || new Map();
        const recMap = rec.get(key1);
        // Already exists and is equal
        if (recMap && uint8ArrayEquals(value1, recMap)) {
            log(`the metadata provided to store is equal to the already stored for ${id} on ${key1}`);
            return;
        }
        rec.set(key1, value1);
        this.data.set(id, rec);
        emit && this._emit(peerId1, key1);
    }
    /**
   * Get the known data of a provided peer.
   *
   * @param {PeerId} peerId
   * @returns {Map<string, Uint8Array>|undefined}
   */ get(peerId2) {
        if (!PeerId.isPeerId(peerId2)) throw errcode(new Error('peerId must be an instance of peer-id'), ERR_INVALID_PARAMETERS);
        return this.data.get(peerId2.toB58String());
    }
    /**
   * Get specific metadata value, if it exists
   *
   * @param {PeerId} peerId
   * @param {string} key
   * @returns {Uint8Array | undefined}
   */ getValue(peerId3, key2) {
        if (!PeerId.isPeerId(peerId3)) throw errcode(new Error('peerId must be an instance of peer-id'), ERR_INVALID_PARAMETERS);
        const rec = this.data.get(peerId3.toB58String());
        return rec && rec.get(key2);
    }
    /**
   * Deletes the provided peer from the book.
   *
   * @param {PeerId} peerId
   * @returns {boolean}
   */ delete(peerId4) {
        if (!PeerId.isPeerId(peerId4)) throw errcode(new Error('peerId must be an instance of peer-id'), ERR_INVALID_PARAMETERS);
        if (!this.data.delete(peerId4.toB58String())) return false;
        this._emit(peerId4);
        return true;
    }
    /**
   * Deletes the provided peer metadata key from the book.
   *
   * @param {PeerId} peerId
   * @param {string} key
   * @returns {boolean}
   */ deleteValue(peerId5, key3) {
        if (!PeerId.isPeerId(peerId5)) throw errcode(new Error('peerId must be an instance of peer-id'), ERR_INVALID_PARAMETERS);
        const rec = this.data.get(peerId5.toB58String());
        if (!rec || !rec.delete(key3)) return false;
        this._emit(peerId5, key3);
        return true;
    }
}
module.exports = MetadataBook;

},{"debug":"lWlU4","err-code":"eQvyh","uint8arrays/equals":"fjLeN","peer-id":"4VGWt","./book":"3k32Y","../errors":"dO31S"}],"JBthV":[function(require,module,exports) {
'use strict';
const debug = require('debug');
const log = Object.assign(debug('libp2p:peer-store:proto-book'), {
    error: debug('libp2p:peer-store:proto-book:err')
});
const errcode = require('err-code');
const PeerId = require('peer-id');
const Book = require('./book');
const { codes: { ERR_INVALID_PARAMETERS  }  } = require('../errors');
/**
 * @typedef {import('./')} PeerStore
 */ /**
 * @extends {Book}
 *
 * @fires ProtoBook#change:protocols
 */ class ProtoBook extends Book {
    /**
   * The ProtoBook is responsible for keeping the known supported
   * protocols of a peer.
   *
   * @class
   * @param {PeerStore} peerStore
   */ constructor(peerStore){
        /**
     * PeerStore Event emitter, used by the ProtoBook to emit:
     * "change:protocols" - emitted when the known protocols of a peer change.
     */ super({
            peerStore,
            eventName: 'change:protocols',
            eventProperty: 'protocols',
            eventTransformer: (data)=>Array.from(data)
        });
        /**
     * Map known peers to their known protocols.
     *
     * @type {Map<string, Set<string>>}
     */ this.data = new Map();
    }
    /**
   * Set known protocols of a provided peer.
   * If the peer was not known before, it will be added.
   *
   * @override
   * @param {PeerId} peerId
   * @param {string[]} protocols
   * @returns {ProtoBook}
   */ set(peerId, protocols) {
        if (!PeerId.isPeerId(peerId)) {
            log.error('peerId must be an instance of peer-id to store data');
            throw errcode(new Error('peerId must be an instance of peer-id'), ERR_INVALID_PARAMETERS);
        }
        if (!protocols) {
            log.error('protocols must be provided to store data');
            throw errcode(new Error('protocols must be provided'), ERR_INVALID_PARAMETERS);
        }
        const id = peerId.toB58String();
        const recSet = this.data.get(id);
        const newSet = new Set(protocols);
        /**
     * @param {Set<string>} a
     * @param {Set<string>} b
     */ const isSetEqual = (a, b)=>a.size === b.size && [
                ...a
            ].every((value)=>b.has(value)
            )
        ;
        // Already knows the peer and the recorded protocols are the same?
        // If yes, no changes needed!
        if (recSet && isSetEqual(recSet, newSet)) {
            log(`the protocols provided to store are equal to the already stored for ${id}`);
            return this;
        }
        this._setData(peerId, newSet);
        log(`stored provided protocols for ${id}`);
        return this;
    }
    /**
   * Adds known protocols of a provided peer.
   * If the peer was not known before, it will be added.
   *
   * @param {PeerId} peerId
   * @param {string[]} protocols
   * @returns {ProtoBook}
   */ add(peerId1, protocols1) {
        if (!PeerId.isPeerId(peerId1)) {
            log.error('peerId must be an instance of peer-id to store data');
            throw errcode(new Error('peerId must be an instance of peer-id'), ERR_INVALID_PARAMETERS);
        }
        if (!protocols1) {
            log.error('protocols must be provided to store data');
            throw errcode(new Error('protocols must be provided'), ERR_INVALID_PARAMETERS);
        }
        const id = peerId1.toB58String();
        const recSet = this.data.get(id) || new Set();
        const newSet = new Set([
            ...recSet,
            ...protocols1
        ]) // Set Union
        ;
        // Any new protocol added?
        if (recSet.size === newSet.size) {
            log(`the protocols provided to store are already stored for ${id}`);
            return this;
        }
        this._setData(peerId1, newSet);
        log(`added provided protocols for ${id}`);
        return this;
    }
    /**
   * Removes known protocols of a provided peer.
   * If the protocols did not exist before, nothing will be done.
   *
   * @param {PeerId} peerId
   * @param {string[]} protocols
   * @returns {ProtoBook}
   */ remove(peerId2, protocols2) {
        if (!PeerId.isPeerId(peerId2)) {
            log.error('peerId must be an instance of peer-id to store data');
            throw errcode(new Error('peerId must be an instance of peer-id'), ERR_INVALID_PARAMETERS);
        }
        if (!protocols2) {
            log.error('protocols must be provided to store data');
            throw errcode(new Error('protocols must be provided'), ERR_INVALID_PARAMETERS);
        }
        const id = peerId2.toB58String();
        const recSet = this.data.get(id);
        if (recSet) {
            const newSet = new Set([
                ...recSet
            ].filter((p)=>!protocols2.includes(p)
            ));
            // Any protocol removed?
            if (recSet.size === newSet.size) return this;
            this._setData(peerId2, newSet);
            log(`removed provided protocols for ${id}`);
        }
        return this;
    }
}
module.exports = ProtoBook;

},{"debug":"lWlU4","err-code":"eQvyh","peer-id":"4VGWt","./book":"3k32Y","../errors":"dO31S"}],"hpvjv":[function(require,module,exports) {
'use strict';
// Pubsub adapter to keep API with handlers while not removed.
/**
 * @typedef {import('libp2p-interfaces/src/pubsub').InMessage} InMessage
 * @typedef {import('libp2p-interfaces/src/pubsub')} PubsubRouter
 */ /**
 * @param {{new(...args: any[]): PubsubRouter}} PubsubRouter
 * @param {import('.')} libp2p
 * @param {{ enabled: boolean; } & import(".").PubsubLocalOptions & import("libp2p-interfaces/src/pubsub").PubsubOptions} options
 */ function pubsubAdapter(PubsubRouter, libp2p, options) {
    /** @type {PubsubRouter & { _subscribeAdapter: PubsubRouter['subscribe'], _unsubscribeAdapter: PubsubRouter['unsubscribe'] }} */ // @ts-ignore we set the extra _subscribeAdapter and _unsubscribeAdapter properties afterwards
    const pubsub = new PubsubRouter(libp2p, options);
    pubsub._subscribeAdapter = pubsub.subscribe;
    pubsub._unsubscribeAdapter = pubsub.unsubscribe;
    /**
   * Subscribes to a given topic.
   *
   * @override
   * @param {string} topic
   * @param {(msg: InMessage) => void} [handler]
   * @returns {void}
   */ function subscribe(topic, handler) {
        // Bind provided handler
        handler && pubsub.on(topic, handler);
        pubsub._subscribeAdapter(topic);
    }
    /**
   * Unsubscribe from the given topic.
   *
   * @override
   * @param {string} topic
   * @param {(msg: InMessage) => void} [handler]
   * @returns {void}
   */ function unsubscribe(topic, handler) {
        if (!handler) pubsub.removeAllListeners(topic);
        else pubsub.removeListener(topic, handler);
        if (pubsub.listenerCount(topic) === 0) pubsub._unsubscribeAdapter(topic);
    }
    pubsub.subscribe = subscribe;
    pubsub.unsubscribe = unsubscribe;
    return pubsub;
}
module.exports = pubsubAdapter;

},{}],"hlkIm":[function(require,module,exports) {
'use strict';
const debug = require('debug');
const log = Object.assign(debug('libp2p:persistent-peer-store'), {
    error: debug('libp2p:persistent-peer-store:err')
});
const { Key  } = require('interface-datastore/key');
const { Multiaddr  } = require('multiaddr');
const PeerId = require('peer-id');
const { base32  } = require('multiformats/bases/base32');
const PeerStore = require('..');
const { NAMESPACE_ADDRESS , NAMESPACE_COMMON , NAMESPACE_KEYS , NAMESPACE_METADATA , NAMESPACE_PROTOCOL  } = require('./consts');
const { Addresses  } = require('./pb/address-book');
const { Protocols  } = require('./pb/proto-book');
/**
 * @typedef {import('interface-datastore').Batch} Batch
 * @typedef {import('../address-book.js').Address} Address
 */ /**
 * @typedef {Object} PersistentPeerStoreProperties
 * @property {PeerId} peerId
 * @property {import('interface-datastore').Datastore} datastore
 *
 * @typedef {Object} PersistentPeerStoreOptions
 * @property {number} [threshold = 5] - Number of dirty peers allowed before commit data.
 */ /**
 * Responsible for managing the persistence of data in the PeerStore.
 */ class PersistentPeerStore extends PeerStore {
    /**
   * @class
   * @param {PersistentPeerStoreProperties & PersistentPeerStoreOptions} properties
   */ constructor({ peerId , datastore , threshold =5  }){
        super({
            peerId
        });
        /**
     * Backend datastore used to persist data.
     */ this._datastore = datastore;
        /**
     * Peers modified after the latest data persisted.
     */ this._dirtyPeers = new Set();
        /**
     * Peers metadata changed mapping peer identifers to metadata changed.
     *
     * @type {Map<string, Set<string>>}
     */ this._dirtyMetadata = new Map();
        this.threshold = threshold;
        this._addDirtyPeer = this._addDirtyPeer.bind(this);
    }
    /**
   * Start Persistent PeerStore.
   *
   * @returns {Promise<void>}
   */ async start() {
        log('PeerStore is starting');
        // Handlers for dirty peers
        this.on('change:protocols', this._addDirtyPeer);
        this.on('change:multiaddrs', this._addDirtyPeer);
        this.on('change:pubkey', this._addDirtyPeerKey);
        this.on('change:metadata', this._addDirtyPeerMetadata);
        // Load data
        for await (const entry of this._datastore.query({
            prefix: NAMESPACE_COMMON
        }))await this._processDatastoreEntry(entry);
        log('PeerStore started');
    }
    /**
   * Stop Persistent PeerStore.
   *
   * @returns {Promise<void>}
   */ async stop() {
        log('PeerStore is stopping');
        this.removeAllListeners();
        await this._commitData();
        log('PeerStore stopped');
    }
    /**
   * Add modified peer to the dirty set
   *
   * @private
   * @param {Object} params
   * @param {PeerId} params.peerId
   */ _addDirtyPeer({ peerId: peerId1  }) {
        const peerIdstr = peerId1.toB58String();
        log('add dirty peer', peerIdstr);
        this._dirtyPeers.add(peerIdstr);
        if (this._dirtyPeers.size >= this.threshold) // Commit current data
        this._commitData().catch((err)=>{
            log.error('error committing data', err);
        });
    }
    /**
   * Add modified peer key to the dirty set
   *
   * @private
   * @param {Object} params
   * @param {PeerId} params.peerId
   */ _addDirtyPeerKey({ peerId: peerId2  }) {
        // Not add if inline key available
        if (peerId2.hasInlinePublicKey()) return;
        const peerIdstr = peerId2.toB58String();
        log('add dirty peer key', peerIdstr);
        this._dirtyPeers.add(peerIdstr);
        if (this._dirtyPeers.size >= this.threshold) // Commit current data
        this._commitData().catch((err)=>{
            log.error('error committing data', err);
        });
    }
    /**
   * Add modified metadata peer to the set.
   *
   * @private
   * @param {Object} params
   * @param {PeerId} params.peerId
   * @param {string} params.metadata
   */ _addDirtyPeerMetadata({ peerId: peerId3 , metadata  }) {
        const peerIdstr = peerId3.toB58String();
        log('add dirty metadata peer', peerIdstr);
        this._dirtyPeers.add(peerIdstr);
        // Add dirty metadata key
        const mData = this._dirtyMetadata.get(peerIdstr) || new Set();
        mData.add(metadata);
        this._dirtyMetadata.set(peerIdstr, mData);
        if (this._dirtyPeers.size >= this.threshold) // Commit current data
        this._commitData().catch((err)=>{
            log.error('error committing data', err);
        });
    }
    /**
   * Add all the peers current data to a datastore batch and commit it.
   *
   * @private
   * @returns {Promise<void>}
   */ async _commitData() {
        const commitPeers = Array.from(this._dirtyPeers);
        if (!commitPeers.length) return;
        // Clear Dirty Peers set
        this._dirtyPeers.clear();
        log('create batch commit');
        const batch = this._datastore.batch();
        for (const peerIdStr of commitPeers){
            // PeerId
            const peerId = this.keyBook.data.get(peerIdStr) || PeerId.createFromB58String(peerIdStr);
            // Address Book
            this._batchAddressBook(peerId, batch);
            // Key Book
            !peerId.hasInlinePublicKey() && this._batchKeyBook(peerId, batch);
            // Metadata Book
            this._batchMetadataBook(peerId, batch);
            // Proto Book
            this._batchProtoBook(peerId, batch);
        }
        await batch.commit();
        log('batch committed');
    }
    /**
   * Add address book data of the peer to the batch.
   *
   * @private
   * @param {PeerId} peerId
   * @param {Batch} batch
   */ _batchAddressBook(peerId4, batch) {
        const b32key = peerId4.toString();
        const key = new Key(`${NAMESPACE_ADDRESS}${b32key}`);
        const entry = this.addressBook.data.get(peerId4.toB58String());
        try {
            // Deleted from the book
            if (!entry) {
                batch.delete(key);
                return;
            }
            const encodedData = Addresses.encode({
                addrs: entry.addresses.map((address)=>({
                        multiaddr: address.multiaddr.bytes,
                        isCertified: address.isCertified
                    })
                ),
                certifiedRecord: entry.record ? {
                    seq: entry.record.seqNumber,
                    raw: entry.record.raw
                } : undefined
            }).finish();
            batch.put(key, encodedData);
        } catch (err) {
            log.error(err);
        }
    }
    /**
   * Add Key book data of the peer to the batch.
   *
   * @private
   * @param {PeerId} peerId
   * @param {Batch} batch
   */ _batchKeyBook(peerId5, batch1) {
        const b32key = peerId5.toString();
        const key = new Key(`${NAMESPACE_KEYS}${b32key}`);
        try {
            // Deleted from the book
            if (!peerId5.pubKey) {
                batch1.delete(key);
                return;
            }
            const encodedData = peerId5.marshalPubKey();
            batch1.put(key, encodedData);
        } catch (err) {
            log.error(err);
        }
    }
    /**
   * Add metadata book data of the peer to the batch.
   *
   * @private
   * @param {PeerId} peerId
   * @param {Batch} batch
   */ _batchMetadataBook(peerId6, batch2) {
        const b32key = peerId6.toString();
        const dirtyMetada = this._dirtyMetadata.get(peerId6.toB58String()) || [];
        try {
            dirtyMetada.forEach((/** @type {string} */ dirtyKey)=>{
                const key = new Key(`${NAMESPACE_METADATA}${b32key}/${dirtyKey}`);
                const dirtyValue = this.metadataBook.getValue(peerId6, dirtyKey);
                if (dirtyValue) batch2.put(key, dirtyValue);
                else batch2.delete(key);
            });
        } catch (err) {
            log.error(err);
        }
    }
    /**
   * Add proto book data of the peer to the batch.
   *
   * @private
   * @param {PeerId} peerId
   * @param {Batch} batch
   */ _batchProtoBook(peerId7, batch3) {
        const b32key = peerId7.toString();
        const key = new Key(`${NAMESPACE_PROTOCOL}${b32key}`);
        const protocols = this.protoBook.get(peerId7);
        try {
            // Deleted from the book
            if (!protocols) {
                batch3.delete(key);
                return;
            }
            const encodedData = Protocols.encode({
                protocols
            }).finish();
            batch3.put(key, encodedData);
        } catch (err) {
            log.error(err);
        }
    }
    /**
   * Process datastore entry and add its data to the correct book.
   *
   * @private
   * @param {Object} params
   * @param {Key} params.key - datastore key
   * @param {Uint8Array} params.value - datastore value stored
   * @returns {Promise<void>}
   */ async _processDatastoreEntry({ key , value  }) {
        try {
            const keyParts = key.toString().split('/');
            const peerId = PeerId.createFromBytes(base32.decode(keyParts[3]));
            let decoded;
            switch(keyParts[2]){
                case 'addrs':
                    decoded = Addresses.decode(value);
                    // @ts-ignore protected function
                    this.addressBook._setData(peerId, {
                        addresses: decoded.addrs.map((address)=>({
                                multiaddr: new Multiaddr(address.multiaddr),
                                isCertified: Boolean(address.isCertified)
                            })
                        ),
                        record: decoded.certifiedRecord ? {
                            raw: decoded.certifiedRecord.raw,
                            seqNumber: decoded.certifiedRecord.seq
                        } : undefined
                    }, {
                        emit: false
                    });
                    break;
                case 'keys':
                    decoded = await PeerId.createFromPubKey(value);
                    // @ts-ignore protected function
                    this.keyBook._setData(decoded, decoded, {
                        emit: false
                    });
                    break;
                case 'metadata':
                    this.metadataBook._setValue(peerId, keyParts[4], value, {
                        emit: false
                    });
                    break;
                case 'protos':
                    decoded = Protocols.decode(value);
                    // @ts-ignore protected function
                    this.protoBook._setData(peerId, new Set(decoded.protocols), {
                        emit: false
                    });
                    break;
                default:
                    log('invalid data persisted for: ', key.toString());
            }
        } catch (err) {
            log.error(err);
        }
    }
}
module.exports = PersistentPeerStore;

},{"debug":"lWlU4","interface-datastore/key":"ccQWS","multiaddr":"kOPrF","peer-id":"4VGWt","multiformats/bases/base32":"63xDB","..":"SedIN","./consts":"hNXUz","./pb/address-book":"7XIwT","./pb/proto-book":"buyZT"}],"hNXUz":[function(require,module,exports) {
'use strict';
module.exports.NAMESPACE_COMMON = '/peers/';
// /peers/protos/<b32 peer id no padding>
module.exports.NAMESPACE_ADDRESS = '/peers/addrs/';
// /peers/keys/<b32 peer id no padding>
module.exports.NAMESPACE_KEYS = '/peers/keys/';
// /peers/metadata/<b32 peer id no padding>/<key>
module.exports.NAMESPACE_METADATA = '/peers/metadata/';
// /peers/addrs/<b32 peer id no padding>
module.exports.NAMESPACE_PROTOCOL = '/peers/protos/';

},{}],"7XIwT":[function(require,module,exports) {
/*eslint-disable*/ "use strict";
var $protobuf = require("protobufjs/minimal");
// Common aliases
var $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util;
// Exported root namespace
var $root = $protobuf.roots["libp2p-address-book"] || ($protobuf.roots["libp2p-address-book"] = {
});
$root.Addresses = (function() {
    /**
     * Properties of an Addresses.
     * @exports IAddresses
     * @interface IAddresses
     * @property {Array.<Addresses.IAddress>|null} [addrs] Addresses addrs
     * @property {Addresses.ICertifiedRecord|null} [certifiedRecord] Addresses certifiedRecord
     */ /**
     * Constructs a new Addresses.
     * @exports Addresses
     * @classdesc Represents an Addresses.
     * @implements IAddresses
     * @constructor
     * @param {IAddresses=} [p] Properties to set
     */ function Addresses(p) {
        this.addrs = [];
        if (p) {
            for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
        }
    }
    /**
     * Addresses addrs.
     * @member {Array.<Addresses.IAddress>} addrs
     * @memberof Addresses
     * @instance
     */ Addresses.prototype.addrs = $util.emptyArray;
    /**
     * Addresses certifiedRecord.
     * @member {Addresses.ICertifiedRecord|null|undefined} certifiedRecord
     * @memberof Addresses
     * @instance
     */ Addresses.prototype.certifiedRecord = null;
    /**
     * Encodes the specified Addresses message. Does not implicitly {@link Addresses.verify|verify} messages.
     * @function encode
     * @memberof Addresses
     * @static
     * @param {IAddresses} m Addresses message or plain object to encode
     * @param {$protobuf.Writer} [w] Writer to encode to
     * @returns {$protobuf.Writer} Writer
     */ Addresses.encode = function encode(m, w) {
        if (!w) w = $Writer.create();
        if (m.addrs != null && m.addrs.length) for(var i = 0; i < m.addrs.length; ++i)$root.Addresses.Address.encode(m.addrs[i], w.uint32(10).fork()).ldelim();
        if (m.certifiedRecord != null && Object.hasOwnProperty.call(m, "certifiedRecord")) $root.Addresses.CertifiedRecord.encode(m.certifiedRecord, w.uint32(18).fork()).ldelim();
        return w;
    };
    /**
     * Decodes an Addresses message from the specified reader or buffer.
     * @function decode
     * @memberof Addresses
     * @static
     * @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
     * @param {number} [l] Message length if known beforehand
     * @returns {Addresses} Addresses
     * @throws {Error} If the payload is not a reader or valid buffer
     * @throws {$protobuf.util.ProtocolError} If required fields are missing
     */ Addresses.decode = function decode(r, l) {
        if (!(r instanceof $Reader)) r = $Reader.create(r);
        var c = l === undefined ? r.len : r.pos + l, m = new $root.Addresses();
        while(r.pos < c){
            var t = r.uint32();
            switch(t >>> 3){
                case 1:
                    if (!(m.addrs && m.addrs.length)) m.addrs = [];
                    m.addrs.push($root.Addresses.Address.decode(r, r.uint32()));
                    break;
                case 2:
                    m.certifiedRecord = $root.Addresses.CertifiedRecord.decode(r, r.uint32());
                    break;
                default:
                    r.skipType(t & 7);
                    break;
            }
        }
        return m;
    };
    /**
     * Creates an Addresses message from a plain object. Also converts values to their respective internal types.
     * @function fromObject
     * @memberof Addresses
     * @static
     * @param {Object.<string,*>} d Plain object
     * @returns {Addresses} Addresses
     */ Addresses.fromObject = function fromObject(d) {
        if (d instanceof $root.Addresses) return d;
        var m = new $root.Addresses();
        if (d.addrs) {
            if (!Array.isArray(d.addrs)) throw TypeError(".Addresses.addrs: array expected");
            m.addrs = [];
            for(var i = 0; i < d.addrs.length; ++i){
                if (typeof d.addrs[i] !== "object") throw TypeError(".Addresses.addrs: object expected");
                m.addrs[i] = $root.Addresses.Address.fromObject(d.addrs[i]);
            }
        }
        if (d.certifiedRecord != null) {
            if (typeof d.certifiedRecord !== "object") throw TypeError(".Addresses.certifiedRecord: object expected");
            m.certifiedRecord = $root.Addresses.CertifiedRecord.fromObject(d.certifiedRecord);
        }
        return m;
    };
    /**
     * Creates a plain object from an Addresses message. Also converts values to other types if specified.
     * @function toObject
     * @memberof Addresses
     * @static
     * @param {Addresses} m Addresses
     * @param {$protobuf.IConversionOptions} [o] Conversion options
     * @returns {Object.<string,*>} Plain object
     */ Addresses.toObject = function toObject(m, o) {
        if (!o) o = {
        };
        var d = {
        };
        if (o.arrays || o.defaults) d.addrs = [];
        if (o.defaults) d.certifiedRecord = null;
        if (m.addrs && m.addrs.length) {
            d.addrs = [];
            for(var j = 0; j < m.addrs.length; ++j)d.addrs[j] = $root.Addresses.Address.toObject(m.addrs[j], o);
        }
        if (m.certifiedRecord != null && m.hasOwnProperty("certifiedRecord")) d.certifiedRecord = $root.Addresses.CertifiedRecord.toObject(m.certifiedRecord, o);
        return d;
    };
    /**
     * Converts this Addresses to JSON.
     * @function toJSON
     * @memberof Addresses
     * @instance
     * @returns {Object.<string,*>} JSON object
     */ Addresses.prototype.toJSON = function toJSON() {
        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
    };
    Addresses.Address = (function() {
        /**
         * Properties of an Address.
         * @memberof Addresses
         * @interface IAddress
         * @property {Uint8Array|null} [multiaddr] Address multiaddr
         * @property {boolean|null} [isCertified] Address isCertified
         */ /**
         * Constructs a new Address.
         * @memberof Addresses
         * @classdesc Represents an Address.
         * @implements IAddress
         * @constructor
         * @param {Addresses.IAddress=} [p] Properties to set
         */ function Address(p) {
            if (p) {
                for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
            }
        }
        /**
         * Address multiaddr.
         * @member {Uint8Array} multiaddr
         * @memberof Addresses.Address
         * @instance
         */ Address.prototype.multiaddr = $util.newBuffer([]);
        /**
         * Address isCertified.
         * @member {boolean} isCertified
         * @memberof Addresses.Address
         * @instance
         */ Address.prototype.isCertified = false;
        /**
         * Encodes the specified Address message. Does not implicitly {@link Addresses.Address.verify|verify} messages.
         * @function encode
         * @memberof Addresses.Address
         * @static
         * @param {Addresses.IAddress} m Address message or plain object to encode
         * @param {$protobuf.Writer} [w] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */ Address.encode = function encode(m, w) {
            if (!w) w = $Writer.create();
            if (m.multiaddr != null && Object.hasOwnProperty.call(m, "multiaddr")) w.uint32(10).bytes(m.multiaddr);
            if (m.isCertified != null && Object.hasOwnProperty.call(m, "isCertified")) w.uint32(16).bool(m.isCertified);
            return w;
        };
        /**
         * Decodes an Address message from the specified reader or buffer.
         * @function decode
         * @memberof Addresses.Address
         * @static
         * @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
         * @param {number} [l] Message length if known beforehand
         * @returns {Addresses.Address} Address
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */ Address.decode = function decode(r, l) {
            if (!(r instanceof $Reader)) r = $Reader.create(r);
            var c = l === undefined ? r.len : r.pos + l, m = new $root.Addresses.Address();
            while(r.pos < c){
                var t = r.uint32();
                switch(t >>> 3){
                    case 1:
                        m.multiaddr = r.bytes();
                        break;
                    case 2:
                        m.isCertified = r.bool();
                        break;
                    default:
                        r.skipType(t & 7);
                        break;
                }
            }
            return m;
        };
        /**
         * Creates an Address message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof Addresses.Address
         * @static
         * @param {Object.<string,*>} d Plain object
         * @returns {Addresses.Address} Address
         */ Address.fromObject = function fromObject(d) {
            if (d instanceof $root.Addresses.Address) return d;
            var m = new $root.Addresses.Address();
            if (d.multiaddr != null) {
                if (typeof d.multiaddr === "string") $util.base64.decode(d.multiaddr, m.multiaddr = $util.newBuffer($util.base64.length(d.multiaddr)), 0);
                else if (d.multiaddr.length) m.multiaddr = d.multiaddr;
            }
            if (d.isCertified != null) m.isCertified = Boolean(d.isCertified);
            return m;
        };
        /**
         * Creates a plain object from an Address message. Also converts values to other types if specified.
         * @function toObject
         * @memberof Addresses.Address
         * @static
         * @param {Addresses.Address} m Address
         * @param {$protobuf.IConversionOptions} [o] Conversion options
         * @returns {Object.<string,*>} Plain object
         */ Address.toObject = function toObject(m, o) {
            if (!o) o = {
            };
            var d = {
            };
            if (o.defaults) {
                if (o.bytes === String) d.multiaddr = "";
                else {
                    d.multiaddr = [];
                    if (o.bytes !== Array) d.multiaddr = $util.newBuffer(d.multiaddr);
                }
                d.isCertified = false;
            }
            if (m.multiaddr != null && m.hasOwnProperty("multiaddr")) d.multiaddr = o.bytes === String ? $util.base64.encode(m.multiaddr, 0, m.multiaddr.length) : o.bytes === Array ? Array.prototype.slice.call(m.multiaddr) : m.multiaddr;
            if (m.isCertified != null && m.hasOwnProperty("isCertified")) d.isCertified = m.isCertified;
            return d;
        };
        /**
         * Converts this Address to JSON.
         * @function toJSON
         * @memberof Addresses.Address
         * @instance
         * @returns {Object.<string,*>} JSON object
         */ Address.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };
        return Address;
    })();
    Addresses.CertifiedRecord = (function() {
        /**
         * Properties of a CertifiedRecord.
         * @memberof Addresses
         * @interface ICertifiedRecord
         * @property {number|null} [seq] CertifiedRecord seq
         * @property {Uint8Array|null} [raw] CertifiedRecord raw
         */ /**
         * Constructs a new CertifiedRecord.
         * @memberof Addresses
         * @classdesc Represents a CertifiedRecord.
         * @implements ICertifiedRecord
         * @constructor
         * @param {Addresses.ICertifiedRecord=} [p] Properties to set
         */ function CertifiedRecord(p) {
            if (p) {
                for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
            }
        }
        /**
         * CertifiedRecord seq.
         * @member {number} seq
         * @memberof Addresses.CertifiedRecord
         * @instance
         */ CertifiedRecord.prototype.seq = $util.Long ? $util.Long.fromBits(0, 0, true) : 0;
        /**
         * CertifiedRecord raw.
         * @member {Uint8Array} raw
         * @memberof Addresses.CertifiedRecord
         * @instance
         */ CertifiedRecord.prototype.raw = $util.newBuffer([]);
        /**
         * Encodes the specified CertifiedRecord message. Does not implicitly {@link Addresses.CertifiedRecord.verify|verify} messages.
         * @function encode
         * @memberof Addresses.CertifiedRecord
         * @static
         * @param {Addresses.ICertifiedRecord} m CertifiedRecord message or plain object to encode
         * @param {$protobuf.Writer} [w] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */ CertifiedRecord.encode = function encode(m, w) {
            if (!w) w = $Writer.create();
            if (m.seq != null && Object.hasOwnProperty.call(m, "seq")) w.uint32(8).uint64(m.seq);
            if (m.raw != null && Object.hasOwnProperty.call(m, "raw")) w.uint32(18).bytes(m.raw);
            return w;
        };
        /**
         * Decodes a CertifiedRecord message from the specified reader or buffer.
         * @function decode
         * @memberof Addresses.CertifiedRecord
         * @static
         * @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
         * @param {number} [l] Message length if known beforehand
         * @returns {Addresses.CertifiedRecord} CertifiedRecord
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */ CertifiedRecord.decode = function decode(r, l) {
            if (!(r instanceof $Reader)) r = $Reader.create(r);
            var c = l === undefined ? r.len : r.pos + l, m = new $root.Addresses.CertifiedRecord();
            while(r.pos < c){
                var t = r.uint32();
                switch(t >>> 3){
                    case 1:
                        m.seq = r.uint64();
                        break;
                    case 2:
                        m.raw = r.bytes();
                        break;
                    default:
                        r.skipType(t & 7);
                        break;
                }
            }
            return m;
        };
        /**
         * Creates a CertifiedRecord message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof Addresses.CertifiedRecord
         * @static
         * @param {Object.<string,*>} d Plain object
         * @returns {Addresses.CertifiedRecord} CertifiedRecord
         */ CertifiedRecord.fromObject = function fromObject(d) {
            if (d instanceof $root.Addresses.CertifiedRecord) return d;
            var m = new $root.Addresses.CertifiedRecord();
            if (d.seq != null) {
                if ($util.Long) (m.seq = $util.Long.fromValue(d.seq)).unsigned = true;
                else if (typeof d.seq === "string") m.seq = parseInt(d.seq, 10);
                else if (typeof d.seq === "number") m.seq = d.seq;
                else if (typeof d.seq === "object") m.seq = new $util.LongBits(d.seq.low >>> 0, d.seq.high >>> 0).toNumber(true);
            }
            if (d.raw != null) {
                if (typeof d.raw === "string") $util.base64.decode(d.raw, m.raw = $util.newBuffer($util.base64.length(d.raw)), 0);
                else if (d.raw.length) m.raw = d.raw;
            }
            return m;
        };
        /**
         * Creates a plain object from a CertifiedRecord message. Also converts values to other types if specified.
         * @function toObject
         * @memberof Addresses.CertifiedRecord
         * @static
         * @param {Addresses.CertifiedRecord} m CertifiedRecord
         * @param {$protobuf.IConversionOptions} [o] Conversion options
         * @returns {Object.<string,*>} Plain object
         */ CertifiedRecord.toObject = function toObject(m, o) {
            if (!o) o = {
            };
            var d = {
            };
            if (o.defaults) {
                if ($util.Long) {
                    var n = new $util.Long(0, 0, true);
                    d.seq = o.longs === String ? n.toString() : o.longs === Number ? n.toNumber() : n;
                } else d.seq = o.longs === String ? "0" : 0;
                if (o.bytes === String) d.raw = "";
                else {
                    d.raw = [];
                    if (o.bytes !== Array) d.raw = $util.newBuffer(d.raw);
                }
            }
            if (m.seq != null && m.hasOwnProperty("seq")) {
                if (typeof m.seq === "number") d.seq = o.longs === String ? String(m.seq) : m.seq;
                else d.seq = o.longs === String ? $util.Long.prototype.toString.call(m.seq) : o.longs === Number ? new $util.LongBits(m.seq.low >>> 0, m.seq.high >>> 0).toNumber(true) : m.seq;
            }
            if (m.raw != null && m.hasOwnProperty("raw")) d.raw = o.bytes === String ? $util.base64.encode(m.raw, 0, m.raw.length) : o.bytes === Array ? Array.prototype.slice.call(m.raw) : m.raw;
            return d;
        };
        /**
         * Converts this CertifiedRecord to JSON.
         * @function toJSON
         * @memberof Addresses.CertifiedRecord
         * @instance
         * @returns {Object.<string,*>} JSON object
         */ CertifiedRecord.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };
        return CertifiedRecord;
    })();
    return Addresses;
})();
module.exports = $root;

},{"protobufjs/minimal":"9Jmso"}],"buyZT":[function(require,module,exports) {
/*eslint-disable*/ "use strict";
var $protobuf = require("protobufjs/minimal");
// Common aliases
var $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util;
// Exported root namespace
var $root = $protobuf.roots["libp2p-proto-book"] || ($protobuf.roots["libp2p-proto-book"] = {
});
$root.Protocols = (function() {
    /**
     * Properties of a Protocols.
     * @exports IProtocols
     * @interface IProtocols
     * @property {Array.<string>|null} [protocols] Protocols protocols
     */ /**
     * Constructs a new Protocols.
     * @exports Protocols
     * @classdesc Represents a Protocols.
     * @implements IProtocols
     * @constructor
     * @param {IProtocols=} [p] Properties to set
     */ function Protocols(p) {
        this.protocols = [];
        if (p) {
            for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
        }
    }
    /**
     * Protocols protocols.
     * @member {Array.<string>} protocols
     * @memberof Protocols
     * @instance
     */ Protocols.prototype.protocols = $util.emptyArray;
    /**
     * Encodes the specified Protocols message. Does not implicitly {@link Protocols.verify|verify} messages.
     * @function encode
     * @memberof Protocols
     * @static
     * @param {IProtocols} m Protocols message or plain object to encode
     * @param {$protobuf.Writer} [w] Writer to encode to
     * @returns {$protobuf.Writer} Writer
     */ Protocols.encode = function encode(m, w) {
        if (!w) w = $Writer.create();
        if (m.protocols != null && m.protocols.length) for(var i = 0; i < m.protocols.length; ++i)w.uint32(10).string(m.protocols[i]);
        return w;
    };
    /**
     * Decodes a Protocols message from the specified reader or buffer.
     * @function decode
     * @memberof Protocols
     * @static
     * @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
     * @param {number} [l] Message length if known beforehand
     * @returns {Protocols} Protocols
     * @throws {Error} If the payload is not a reader or valid buffer
     * @throws {$protobuf.util.ProtocolError} If required fields are missing
     */ Protocols.decode = function decode(r, l) {
        if (!(r instanceof $Reader)) r = $Reader.create(r);
        var c = l === undefined ? r.len : r.pos + l, m = new $root.Protocols();
        while(r.pos < c){
            var t = r.uint32();
            switch(t >>> 3){
                case 1:
                    if (!(m.protocols && m.protocols.length)) m.protocols = [];
                    m.protocols.push(r.string());
                    break;
                default:
                    r.skipType(t & 7);
                    break;
            }
        }
        return m;
    };
    /**
     * Creates a Protocols message from a plain object. Also converts values to their respective internal types.
     * @function fromObject
     * @memberof Protocols
     * @static
     * @param {Object.<string,*>} d Plain object
     * @returns {Protocols} Protocols
     */ Protocols.fromObject = function fromObject(d) {
        if (d instanceof $root.Protocols) return d;
        var m = new $root.Protocols();
        if (d.protocols) {
            if (!Array.isArray(d.protocols)) throw TypeError(".Protocols.protocols: array expected");
            m.protocols = [];
            for(var i = 0; i < d.protocols.length; ++i)m.protocols[i] = String(d.protocols[i]);
        }
        return m;
    };
    /**
     * Creates a plain object from a Protocols message. Also converts values to other types if specified.
     * @function toObject
     * @memberof Protocols
     * @static
     * @param {Protocols} m Protocols
     * @param {$protobuf.IConversionOptions} [o] Conversion options
     * @returns {Object.<string,*>} Plain object
     */ Protocols.toObject = function toObject(m, o) {
        if (!o) o = {
        };
        var d = {
        };
        if (o.arrays || o.defaults) d.protocols = [];
        if (m.protocols && m.protocols.length) {
            d.protocols = [];
            for(var j = 0; j < m.protocols.length; ++j)d.protocols[j] = m.protocols[j];
        }
        return d;
    };
    /**
     * Converts this Protocols to JSON.
     * @function toJSON
     * @memberof Protocols
     * @instance
     * @returns {Object.<string,*>} JSON object
     */ Protocols.prototype.toJSON = function toJSON() {
        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
    };
    return Protocols;
})();
module.exports = $root;

},{"protobufjs/minimal":"9Jmso"}],"gAB2y":[function(require,module,exports) {
'use strict';
const debug = require('debug');
const log = Object.assign(debug('libp2p:registrar'), {
    error: debug('libp2p:registrar:err')
});
const errcode = require('err-code');
const { codes: { ERR_INVALID_PARAMETERS  }  } = require('./errors');
const Topology = require('libp2p-interfaces/src/topology');
/**
 * @typedef {import('peer-id')} PeerId
 * @typedef {import('./peer-store')} PeerStore
 * @typedef {import('./connection-manager')} ConnectionManager
 * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection
 * @typedef {import('./').HandlerProps} HandlerProps
 */ /**
 *
 */ /**
 * Responsible for notifying registered protocols of events in the network.
 */ class Registrar {
    /**
   * @param {Object} props
   * @param {PeerStore} props.peerStore
   * @param {ConnectionManager} props.connectionManager
   * @class
   */ constructor({ peerStore , connectionManager  }){
        // Used on topology to listen for protocol changes
        this.peerStore = peerStore;
        this.connectionManager = connectionManager;
        /**
     * Map of topologies
     *
     * @type {Map<string, Topology>}
     */ this.topologies = new Map();
        /** @type {(protocols: string[]|string, handler: (props: HandlerProps) => void) => void} */ // @ts-ignore handle is not optional
        this._handle = undefined;
        this._onDisconnect = this._onDisconnect.bind(this);
        this.connectionManager.on('peer:disconnect', this._onDisconnect);
    }
    /**
   * @returns {(protocols: string[]|string, handler: (props: HandlerProps) => void) => void}
   */ get handle() {
        return this._handle;
    }
    /**
   * @param {(protocols: string[]|string, handler: (props: HandlerProps) => void) => void} handle
   */ set handle(handle) {
        this._handle = handle;
    }
    /**
   * Get a connection with a peer.
   *
   * @param {PeerId} peerId
   * @returns {Connection | null}
   */ getConnection(peerId) {
        return this.connectionManager.get(peerId);
    }
    /**
   * Register handlers for a set of multicodecs given
   *
   * @param {Topology} topology - protocol topology
   * @returns {string} registrar identifier
   */ register(topology) {
        if (!Topology.isTopology(topology)) {
            log.error('topology must be an instance of interfaces/topology');
            throw errcode(new Error('topology must be an instance of interfaces/topology'), ERR_INVALID_PARAMETERS);
        }
        // Create topology
        const id = (Math.random() * 1000000000).toString(36) + Date.now();
        this.topologies.set(id, topology);
        // Set registrar
        topology.registrar = this;
        return id;
    }
    /**
   * Unregister topology.
   *
   * @param {string} id - registrar identifier
   * @returns {boolean} unregistered successfully
   */ unregister(id) {
        return this.topologies.delete(id);
    }
    /**
   * Remove a disconnected peer from the record
   *
   * @param {Connection} connection
   * @returns {void}
   */ _onDisconnect(connection) {
        for (const [, topology] of this.topologies)topology.disconnect(connection.remotePeer);
    }
}
module.exports = Registrar;

},{"debug":"lWlU4","err-code":"eQvyh","./errors":"dO31S","libp2p-interfaces/src/topology":"gFGI4"}],"4QQ6u":[function(require,module,exports) {
'use strict';
const debug = require('debug');
const log = Object.assign(debug('libp2p:ping'), {
    error: debug('libp2p:ping:err')
});
const errCode = require('err-code');
const crypto = require('libp2p-crypto');
const { pipe  } = require('it-pipe');
// @ts-ignore it-buffer has no types exported
const { toBuffer  } = require('it-buffer');
const { collect , take  } = require('streaming-iterables');
const { equals  } = require('uint8arrays/equals');
const { PROTOCOL_NAME , PING_LENGTH , PROTOCOL_VERSION  } = require('./constants');
/**
 * @typedef {import('../')} Libp2p
 * @typedef {import('multiaddr').Multiaddr} Multiaddr
 * @typedef {import('peer-id')} PeerId
 * @typedef {import('libp2p-interfaces/src/stream-muxer/types').MuxedStream} MuxedStream
 */ /**
 * Ping a given peer and wait for its response, getting the operation latency.
 *
 * @param {Libp2p} node
 * @param {PeerId|Multiaddr} peer
 * @returns {Promise<number>}
 */ async function ping(node, peer) {
    const protocol = `/${node._config.protocolPrefix}/${PROTOCOL_NAME}/${PROTOCOL_VERSION}`;
    // @ts-ignore multiaddr might not have toB58String
    log('dialing %s to %s', protocol, peer.toB58String ? peer.toB58String() : peer);
    const connection = await node.dial(peer);
    const { stream: stream1  } = await connection.newStream(protocol);
    const start = Date.now();
    const data = crypto.randomBytes(PING_LENGTH);
    const [result] = await pipe([
        data
    ], stream1, (/** @type {MuxedStream} */ stream)=>take(1, stream)
    , toBuffer, collect);
    const end = Date.now();
    if (!equals(data, result)) throw errCode(new Error('Received wrong ping ack'), 'ERR_WRONG_PING_ACK');
    return end - start;
}
/**
 * Subscribe ping protocol handler.
 *
 * @param {Libp2p} node
 */ function mount(node) {
    node.handle(`/${node._config.protocolPrefix}/${PROTOCOL_NAME}/${PROTOCOL_VERSION}`, ({ stream  })=>pipe(stream, stream)
    );
}
/**
 * Unsubscribe ping protocol handler.
 *
 * @param {Libp2p} node
 */ function unmount(node) {
    node.unhandle(`/${node._config.protocolPrefix}/${PROTOCOL_NAME}/${PROTOCOL_VERSION}`);
}
exports = module.exports = ping;
exports.mount = mount;
exports.unmount = unmount;

},{"debug":"lWlU4","err-code":"eQvyh","libp2p-crypto":"hsRcr","it-pipe":"4jukm","it-buffer":"cfN57","streaming-iterables":"9JcGF","uint8arrays/equals":"fjLeN","./constants":"fqIDu"}],"fqIDu":[function(require,module,exports) {
'use strict';
module.exports = {
    PROTOCOL: '/ipfs/ping/1.0.0',
    PING_LENGTH: 32,
    PROTOCOL_VERSION: '1.0.0',
    PROTOCOL_NAME: 'ping'
};

},{}],"aTTi0":[function(require,module,exports) {
'use strict';
const debug = require('debug');
const log = Object.assign(debug('libp2p:identify'), {
    error: debug('libp2p:identify:err')
});
const errCode = require('err-code');
const lp = require('it-length-prefixed');
const { pipe  } = require('it-pipe');
const { collect , take , consume  } = require('streaming-iterables');
const { fromString: uint8ArrayFromString  } = require('uint8arrays/from-string');
const PeerId = require('peer-id');
const { Multiaddr  } = require('multiaddr');
// @ts-ignore it-buffer does not have types
const { toBuffer  } = require('it-buffer');
const Message = require('./message');
const Envelope = require('../record/envelope');
const PeerRecord = require('../record/peer-record');
const { MULTICODEC_IDENTIFY , MULTICODEC_IDENTIFY_PUSH , IDENTIFY_PROTOCOL_VERSION , MULTICODEC_IDENTIFY_PROTOCOL_NAME , MULTICODEC_IDENTIFY_PUSH_PROTOCOL_NAME , MULTICODEC_IDENTIFY_PROTOCOL_VERSION , MULTICODEC_IDENTIFY_PUSH_PROTOCOL_VERSION  } = require('./consts');
const { codes  } = require('../errors');
/**
 * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection
 * @typedef {import('libp2p-interfaces/src/stream-muxer/types').MuxedStream} MuxedStream
 */ /**
 * @typedef {Object} HostProperties
 * @property {string} agentVersion
 */ class IdentifyService {
    /**
   * @param {import('../')} libp2p
   */ static getProtocolStr(libp2p) {
        return {
            identifyProtocolStr: `/${libp2p._config.protocolPrefix}/${MULTICODEC_IDENTIFY_PROTOCOL_NAME}/${MULTICODEC_IDENTIFY_PROTOCOL_VERSION}`,
            identifyPushProtocolStr: `/${libp2p._config.protocolPrefix}/${MULTICODEC_IDENTIFY_PUSH_PROTOCOL_NAME}/${MULTICODEC_IDENTIFY_PUSH_PROTOCOL_VERSION}`
        };
    }
    /**
   * @class
   * @param {Object} options
   * @param {import('../')} options.libp2p
   */ constructor({ libp2p: libp2p1  }){
        this._libp2p = libp2p1;
        this.peerStore = libp2p1.peerStore;
        this.addressManager = libp2p1.addressManager;
        this.connectionManager = libp2p1.connectionManager;
        this.peerId = libp2p1.peerId;
        this.handleMessage = this.handleMessage.bind(this);
        const protocolStr = IdentifyService.getProtocolStr(libp2p1);
        this.identifyProtocolStr = protocolStr.identifyProtocolStr;
        this.identifyPushProtocolStr = protocolStr.identifyPushProtocolStr;
        // Store self host metadata
        this._host = {
            protocolVersion: `${libp2p1._config.protocolPrefix}/${IDENTIFY_PROTOCOL_VERSION}`,
            ...libp2p1._options.host
        };
        this.peerStore.metadataBook.set(this.peerId, 'AgentVersion', uint8ArrayFromString(this._host.agentVersion));
        this.peerStore.metadataBook.set(this.peerId, 'ProtocolVersion', uint8ArrayFromString(this._host.protocolVersion));
        // When a new connection happens, trigger identify
        this.connectionManager.on('peer:connect', (connection)=>{
            this.identify(connection).catch(log.error);
        });
        // When self multiaddrs change, trigger identify-push
        this.peerStore.on('change:multiaddrs', ({ peerId  })=>{
            if (peerId.toString() === this.peerId.toString()) this.pushToPeerStore();
        });
        // When self protocols change, trigger identify-push
        this.peerStore.on('change:protocols', ({ peerId  })=>{
            if (peerId.toString() === this.peerId.toString()) this.pushToPeerStore();
        });
    }
    /**
   * Send an Identify Push update to the list of connections
   *
   * @param {Connection[]} connections
   * @returns {Promise<void[]>}
   */ async push(connections) {
        const signedPeerRecord = await this.peerStore.addressBook.getRawEnvelope(this.peerId);
        const listenAddrs = this._libp2p.multiaddrs.map((ma)=>ma.bytes
        );
        const protocols = this.peerStore.protoBook.get(this.peerId) || [];
        const pushes = connections.map(async (connection)=>{
            try {
                const { stream  } = await connection.newStream(this.identifyPushProtocolStr);
                await pipe([
                    Message.Identify.encode({
                        listenAddrs,
                        signedPeerRecord,
                        protocols
                    }).finish()
                ], lp.encode(), stream, consume);
            } catch (err) {
                // Just log errors
                log.error('could not push identify update to peer', err);
            }
        });
        return Promise.all(pushes);
    }
    /**
   * Calls `push` for all peers in the `peerStore` that are connected
   *
   * @returns {void}
   */ pushToPeerStore() {
        // Do not try to push if libp2p node is not running
        if (!this._libp2p.isStarted()) return;
        const connections = [];
        let connection;
        for (const peer of this.peerStore.peers.values())if (peer.protocols.includes(this.identifyPushProtocolStr) && (connection = this.connectionManager.get(peer.id))) connections.push(connection);
        this.push(connections);
    }
    /**
   * Requests the `Identify` message from peer associated with the given `connection`.
   * If the identified peer does not match the `PeerId` associated with the connection,
   * an error will be thrown.
   *
   * @async
   * @param {Connection} connection
   * @returns {Promise<void>}
   */ async identify(connection) {
        const { stream  } = await connection.newStream(this.identifyProtocolStr);
        const [data] = await pipe([], stream, lp.decode(), take(1), toBuffer, collect);
        if (!data) throw errCode(new Error('No data could be retrieved'), codes.ERR_CONNECTION_ENDED);
        let message;
        try {
            message = Message.Identify.decode(data);
        } catch (err) {
            throw errCode(err, codes.ERR_INVALID_MESSAGE);
        }
        const { publicKey , listenAddrs , protocols , observedAddr , signedPeerRecord  } = message;
        const id = await PeerId.createFromPubKey(publicKey);
        if (connection.remotePeer.toB58String() !== id.toB58String()) throw errCode(new Error('identified peer does not match the expected peer'), codes.ERR_INVALID_PEER);
        // Get the observedAddr if there is one
        const cleanObservedAddr = IdentifyService.getCleanMultiaddr(observedAddr);
        try {
            const envelope = await Envelope.openAndCertify(signedPeerRecord, PeerRecord.DOMAIN);
            if (this.peerStore.addressBook.consumePeerRecord(envelope)) {
                this.peerStore.protoBook.set(id, protocols);
                this.peerStore.metadataBook.set(id, 'AgentVersion', uint8ArrayFromString(message.agentVersion));
                this.peerStore.metadataBook.set(id, 'ProtocolVersion', uint8ArrayFromString(message.protocolVersion));
                return;
            }
        } catch (err1) {
            log('received invalid envelope, discard it and fallback to listenAddrs is available', err1);
        }
        // LEGACY: Update peers data in PeerStore
        try {
            this.peerStore.addressBook.set(id, listenAddrs.map((addr)=>new Multiaddr(addr)
            ));
        } catch (err2) {
            log.error('received invalid addrs', err2);
        }
        this.peerStore.protoBook.set(id, protocols);
        this.peerStore.metadataBook.set(id, 'AgentVersion', uint8ArrayFromString(message.agentVersion));
        this.peerStore.metadataBook.set(id, 'ProtocolVersion', uint8ArrayFromString(message.protocolVersion));
        // TODO: Add and score our observed addr
        log('received observed address of %s', cleanObservedAddr);
    // this.addressManager.addObservedAddr(observedAddr)
    }
    /**
   * A handler to register with Libp2p to process identify messages.
   *
   * @param {Object} options
   * @param {Connection} options.connection
   * @param {MuxedStream} options.stream
   * @param {string} options.protocol
   * @returns {Promise<void>|undefined}
   */ handleMessage({ connection: connection1 , stream , protocol  }) {
        switch(protocol){
            case this.identifyProtocolStr:
                return this._handleIdentify({
                    connection: connection1,
                    stream
                });
            case this.identifyPushProtocolStr:
                return this._handlePush({
                    connection: connection1,
                    stream
                });
            default:
                log.error('cannot handle unknown protocol %s', protocol);
        }
    }
    /**
   * Sends the `Identify` response with the Signed Peer Record
   * to the requesting peer over the given `connection`
   *
   * @private
   * @param {Object} options
   * @param {MuxedStream} options.stream
   * @param {Connection} options.connection
   * @returns {Promise<void>}
   */ async _handleIdentify({ connection: connection2 , stream: stream1  }) {
        let publicKey = new Uint8Array(0);
        if (this.peerId.pubKey) publicKey = this.peerId.pubKey.bytes;
        const signedPeerRecord = await this.peerStore.addressBook.getRawEnvelope(this.peerId);
        const protocols = this.peerStore.protoBook.get(this.peerId) || [];
        const message = Message.Identify.encode({
            protocolVersion: this._host.protocolVersion,
            agentVersion: this._host.agentVersion,
            publicKey,
            listenAddrs: this._libp2p.multiaddrs.map((ma)=>ma.bytes
            ),
            signedPeerRecord,
            observedAddr: connection2.remoteAddr.bytes,
            protocols
        }).finish();
        try {
            await pipe([
                message
            ], lp.encode(), stream1, consume);
        } catch (err) {
            log.error('could not respond to identify request', err);
        }
    }
    /**
   * Reads the Identify Push message from the given `connection`
   *
   * @private
   * @param {object} options
   * @param {MuxedStream} options.stream
   * @param {Connection} options.connection
   * @returns {Promise<void>}
   */ async _handlePush({ connection: connection3 , stream: stream2  }) {
        let message;
        try {
            const [data] = await pipe([], stream2, lp.decode(), take(1), toBuffer, collect);
            message = Message.Identify.decode(data);
        } catch (err) {
            return log.error('received invalid message', err);
        }
        const id = connection3.remotePeer;
        try {
            const envelope = await Envelope.openAndCertify(message.signedPeerRecord, PeerRecord.DOMAIN);
            if (this.peerStore.addressBook.consumePeerRecord(envelope)) {
                this.peerStore.protoBook.set(id, message.protocols);
                return;
            }
        } catch (err3) {
            log('received invalid envelope, discard it and fallback to listenAddrs is available', err3);
        }
        // LEGACY: Update peers data in PeerStore
        try {
            this.peerStore.addressBook.set(id, message.listenAddrs.map((addr)=>new Multiaddr(addr)
            ));
        } catch (err4) {
            log.error('received invalid addrs', err4);
        }
        // Update the protocols
        this.peerStore.protoBook.set(id, message.protocols);
    }
    /**
   * Takes the `addr` and converts it to a Multiaddr if possible
   *
   * @param {Uint8Array | string} addr
   * @returns {Multiaddr|null}
   */ static getCleanMultiaddr(addr) {
        if (addr && addr.length > 0) try {
            return new Multiaddr(addr);
        } catch (_) {
            return null;
        }
        return null;
    }
}
/**
 * The protocols the IdentifyService supports
 *
 * @property multicodecs
 */ const multicodecs = {
    IDENTIFY: MULTICODEC_IDENTIFY,
    IDENTIFY_PUSH: MULTICODEC_IDENTIFY_PUSH
};
IdentifyService.multicodecs = multicodecs;
IdentifyService.Messsage = Message;
module.exports = IdentifyService;

},{"debug":"lWlU4","err-code":"eQvyh","it-length-prefixed":"2cvC1","it-pipe":"4jukm","streaming-iterables":"9JcGF","uint8arrays/from-string":"lo45E","peer-id":"4VGWt","multiaddr":"kOPrF","it-buffer":"cfN57","./message":"hdMex","../record/envelope":"dFiHn","../record/peer-record":"2gkB6","./consts":"5EOHd","../errors":"dO31S"}],"hdMex":[function(require,module,exports) {
/*eslint-disable*/ "use strict";
var $protobuf = require("protobufjs/minimal");
// Common aliases
var $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util;
// Exported root namespace
var $root = $protobuf.roots["libp2p-identify"] || ($protobuf.roots["libp2p-identify"] = {
});
$root.Identify = (function() {
    /**
     * Properties of an Identify.
     * @exports IIdentify
     * @interface IIdentify
     * @property {string|null} [protocolVersion] Identify protocolVersion
     * @property {string|null} [agentVersion] Identify agentVersion
     * @property {Uint8Array|null} [publicKey] Identify publicKey
     * @property {Array.<Uint8Array>|null} [listenAddrs] Identify listenAddrs
     * @property {Uint8Array|null} [observedAddr] Identify observedAddr
     * @property {Array.<string>|null} [protocols] Identify protocols
     * @property {Uint8Array|null} [signedPeerRecord] Identify signedPeerRecord
     */ /**
     * Constructs a new Identify.
     * @exports Identify
     * @classdesc Represents an Identify.
     * @implements IIdentify
     * @constructor
     * @param {IIdentify=} [p] Properties to set
     */ function Identify(p) {
        this.listenAddrs = [];
        this.protocols = [];
        if (p) {
            for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
        }
    }
    /**
     * Identify protocolVersion.
     * @member {string} protocolVersion
     * @memberof Identify
     * @instance
     */ Identify.prototype.protocolVersion = "";
    /**
     * Identify agentVersion.
     * @member {string} agentVersion
     * @memberof Identify
     * @instance
     */ Identify.prototype.agentVersion = "";
    /**
     * Identify publicKey.
     * @member {Uint8Array} publicKey
     * @memberof Identify
     * @instance
     */ Identify.prototype.publicKey = $util.newBuffer([]);
    /**
     * Identify listenAddrs.
     * @member {Array.<Uint8Array>} listenAddrs
     * @memberof Identify
     * @instance
     */ Identify.prototype.listenAddrs = $util.emptyArray;
    /**
     * Identify observedAddr.
     * @member {Uint8Array} observedAddr
     * @memberof Identify
     * @instance
     */ Identify.prototype.observedAddr = $util.newBuffer([]);
    /**
     * Identify protocols.
     * @member {Array.<string>} protocols
     * @memberof Identify
     * @instance
     */ Identify.prototype.protocols = $util.emptyArray;
    /**
     * Identify signedPeerRecord.
     * @member {Uint8Array} signedPeerRecord
     * @memberof Identify
     * @instance
     */ Identify.prototype.signedPeerRecord = $util.newBuffer([]);
    /**
     * Encodes the specified Identify message. Does not implicitly {@link Identify.verify|verify} messages.
     * @function encode
     * @memberof Identify
     * @static
     * @param {IIdentify} m Identify message or plain object to encode
     * @param {$protobuf.Writer} [w] Writer to encode to
     * @returns {$protobuf.Writer} Writer
     */ Identify.encode = function encode(m, w) {
        if (!w) w = $Writer.create();
        if (m.publicKey != null && Object.hasOwnProperty.call(m, "publicKey")) w.uint32(10).bytes(m.publicKey);
        if (m.listenAddrs != null && m.listenAddrs.length) for(var i = 0; i < m.listenAddrs.length; ++i)w.uint32(18).bytes(m.listenAddrs[i]);
        if (m.protocols != null && m.protocols.length) for(var i = 0; i < m.protocols.length; ++i)w.uint32(26).string(m.protocols[i]);
        if (m.observedAddr != null && Object.hasOwnProperty.call(m, "observedAddr")) w.uint32(34).bytes(m.observedAddr);
        if (m.protocolVersion != null && Object.hasOwnProperty.call(m, "protocolVersion")) w.uint32(42).string(m.protocolVersion);
        if (m.agentVersion != null && Object.hasOwnProperty.call(m, "agentVersion")) w.uint32(50).string(m.agentVersion);
        if (m.signedPeerRecord != null && Object.hasOwnProperty.call(m, "signedPeerRecord")) w.uint32(66).bytes(m.signedPeerRecord);
        return w;
    };
    /**
     * Decodes an Identify message from the specified reader or buffer.
     * @function decode
     * @memberof Identify
     * @static
     * @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
     * @param {number} [l] Message length if known beforehand
     * @returns {Identify} Identify
     * @throws {Error} If the payload is not a reader or valid buffer
     * @throws {$protobuf.util.ProtocolError} If required fields are missing
     */ Identify.decode = function decode(r, l) {
        if (!(r instanceof $Reader)) r = $Reader.create(r);
        var c = l === undefined ? r.len : r.pos + l, m = new $root.Identify();
        while(r.pos < c){
            var t = r.uint32();
            switch(t >>> 3){
                case 5:
                    m.protocolVersion = r.string();
                    break;
                case 6:
                    m.agentVersion = r.string();
                    break;
                case 1:
                    m.publicKey = r.bytes();
                    break;
                case 2:
                    if (!(m.listenAddrs && m.listenAddrs.length)) m.listenAddrs = [];
                    m.listenAddrs.push(r.bytes());
                    break;
                case 4:
                    m.observedAddr = r.bytes();
                    break;
                case 3:
                    if (!(m.protocols && m.protocols.length)) m.protocols = [];
                    m.protocols.push(r.string());
                    break;
                case 8:
                    m.signedPeerRecord = r.bytes();
                    break;
                default:
                    r.skipType(t & 7);
                    break;
            }
        }
        return m;
    };
    /**
     * Creates an Identify message from a plain object. Also converts values to their respective internal types.
     * @function fromObject
     * @memberof Identify
     * @static
     * @param {Object.<string,*>} d Plain object
     * @returns {Identify} Identify
     */ Identify.fromObject = function fromObject(d) {
        if (d instanceof $root.Identify) return d;
        var m = new $root.Identify();
        if (d.protocolVersion != null) m.protocolVersion = String(d.protocolVersion);
        if (d.agentVersion != null) m.agentVersion = String(d.agentVersion);
        if (d.publicKey != null) {
            if (typeof d.publicKey === "string") $util.base64.decode(d.publicKey, m.publicKey = $util.newBuffer($util.base64.length(d.publicKey)), 0);
            else if (d.publicKey.length) m.publicKey = d.publicKey;
        }
        if (d.listenAddrs) {
            if (!Array.isArray(d.listenAddrs)) throw TypeError(".Identify.listenAddrs: array expected");
            m.listenAddrs = [];
            for(var i = 0; i < d.listenAddrs.length; ++i){
                if (typeof d.listenAddrs[i] === "string") $util.base64.decode(d.listenAddrs[i], m.listenAddrs[i] = $util.newBuffer($util.base64.length(d.listenAddrs[i])), 0);
                else if (d.listenAddrs[i].length) m.listenAddrs[i] = d.listenAddrs[i];
            }
        }
        if (d.observedAddr != null) {
            if (typeof d.observedAddr === "string") $util.base64.decode(d.observedAddr, m.observedAddr = $util.newBuffer($util.base64.length(d.observedAddr)), 0);
            else if (d.observedAddr.length) m.observedAddr = d.observedAddr;
        }
        if (d.protocols) {
            if (!Array.isArray(d.protocols)) throw TypeError(".Identify.protocols: array expected");
            m.protocols = [];
            for(var i = 0; i < d.protocols.length; ++i)m.protocols[i] = String(d.protocols[i]);
        }
        if (d.signedPeerRecord != null) {
            if (typeof d.signedPeerRecord === "string") $util.base64.decode(d.signedPeerRecord, m.signedPeerRecord = $util.newBuffer($util.base64.length(d.signedPeerRecord)), 0);
            else if (d.signedPeerRecord.length) m.signedPeerRecord = d.signedPeerRecord;
        }
        return m;
    };
    /**
     * Creates a plain object from an Identify message. Also converts values to other types if specified.
     * @function toObject
     * @memberof Identify
     * @static
     * @param {Identify} m Identify
     * @param {$protobuf.IConversionOptions} [o] Conversion options
     * @returns {Object.<string,*>} Plain object
     */ Identify.toObject = function toObject(m, o) {
        if (!o) o = {
        };
        var d = {
        };
        if (o.arrays || o.defaults) {
            d.listenAddrs = [];
            d.protocols = [];
        }
        if (o.defaults) {
            if (o.bytes === String) d.publicKey = "";
            else {
                d.publicKey = [];
                if (o.bytes !== Array) d.publicKey = $util.newBuffer(d.publicKey);
            }
            if (o.bytes === String) d.observedAddr = "";
            else {
                d.observedAddr = [];
                if (o.bytes !== Array) d.observedAddr = $util.newBuffer(d.observedAddr);
            }
            d.protocolVersion = "";
            d.agentVersion = "";
            if (o.bytes === String) d.signedPeerRecord = "";
            else {
                d.signedPeerRecord = [];
                if (o.bytes !== Array) d.signedPeerRecord = $util.newBuffer(d.signedPeerRecord);
            }
        }
        if (m.publicKey != null && m.hasOwnProperty("publicKey")) d.publicKey = o.bytes === String ? $util.base64.encode(m.publicKey, 0, m.publicKey.length) : o.bytes === Array ? Array.prototype.slice.call(m.publicKey) : m.publicKey;
        if (m.listenAddrs && m.listenAddrs.length) {
            d.listenAddrs = [];
            for(var j = 0; j < m.listenAddrs.length; ++j)d.listenAddrs[j] = o.bytes === String ? $util.base64.encode(m.listenAddrs[j], 0, m.listenAddrs[j].length) : o.bytes === Array ? Array.prototype.slice.call(m.listenAddrs[j]) : m.listenAddrs[j];
        }
        if (m.protocols && m.protocols.length) {
            d.protocols = [];
            for(var j = 0; j < m.protocols.length; ++j)d.protocols[j] = m.protocols[j];
        }
        if (m.observedAddr != null && m.hasOwnProperty("observedAddr")) d.observedAddr = o.bytes === String ? $util.base64.encode(m.observedAddr, 0, m.observedAddr.length) : o.bytes === Array ? Array.prototype.slice.call(m.observedAddr) : m.observedAddr;
        if (m.protocolVersion != null && m.hasOwnProperty("protocolVersion")) d.protocolVersion = m.protocolVersion;
        if (m.agentVersion != null && m.hasOwnProperty("agentVersion")) d.agentVersion = m.agentVersion;
        if (m.signedPeerRecord != null && m.hasOwnProperty("signedPeerRecord")) d.signedPeerRecord = o.bytes === String ? $util.base64.encode(m.signedPeerRecord, 0, m.signedPeerRecord.length) : o.bytes === Array ? Array.prototype.slice.call(m.signedPeerRecord) : m.signedPeerRecord;
        return d;
    };
    /**
     * Converts this Identify to JSON.
     * @function toJSON
     * @memberof Identify
     * @instance
     * @returns {Object.<string,*>} JSON object
     */ Identify.prototype.toJSON = function toJSON() {
        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
    };
    return Identify;
})();
module.exports = $root;

},{"protobufjs/minimal":"9Jmso"}],"iQ3J2":[function(require,module,exports) {
'use strict';
// @ts-ignore nat-api does not export types
const NatAPI = require('@motrix/nat-api');
const debug = require('debug');
const { promisify  } = require('es6-promisify');
const { Multiaddr  } = require('multiaddr');
const log = Object.assign(debug('libp2p:nat'), {
    error: debug('libp2p:nat:err')
});
const { isBrowser  } = require('wherearewe');
const retry = require('p-retry');
// @ts-ignore private-api does not export types
const isPrivateIp = require('private-ip');
const pkg = require('../package.json');
const errcode = require('err-code');
const { codes: { ERR_INVALID_PARAMETERS  }  } = require('./errors');
const isLoopback = require('libp2p-utils/src/multiaddr/is-loopback');
const DEFAULT_TTL = 7200;
/**
 * @typedef {import('peer-id')} PeerId
 * @typedef {import('./transport-manager')} TransportManager
 * @typedef {import('./address-manager')} AddressManager
 */ /**
 * @typedef {Object} NatManagerProperties
 * @property {PeerId} peerId - The peer ID of the current node
 * @property {TransportManager} transportManager - A transport manager
 * @property {AddressManager} addressManager - An address manager
 *
 * @typedef {Object} NatManagerOptions
 * @property {boolean} enabled - Whether to enable the NAT manager
 * @property {string} [externalIp] - Pass a value to use instead of auto-detection
 * @property {string} [description] - A string value to use for the port mapping description on the gateway
 * @property {number} [ttl = DEFAULT_TTL] - How long UPnP port mappings should last for in seconds (minimum 1200)
 * @property {boolean} [keepAlive] - Whether to automatically refresh UPnP port mappings when their TTL is reached
 * @property {string} [gateway] - Pass a value to use instead of auto-detection
 * @property {object} [pmp] - PMP options
 * @property {boolean} [pmp.enabled] - Whether to enable PMP as well as UPnP
 */ function highPort(min = 1024, max = 65535) {
    return Math.floor(Math.random() * (max - min + 1) + min);
}
class NatManager {
    /**
   * @class
   * @param {NatManagerProperties & NatManagerOptions} options
   */ constructor({ peerId , addressManager , transportManager , ...options }){
        this._peerId = peerId;
        this._addressManager = addressManager;
        this._transportManager = transportManager;
        this._enabled = options.enabled;
        this._externalIp = options.externalIp;
        this._options = {
            description: options.description || `${pkg.name}@${pkg.version} ${this._peerId}`,
            ttl: options.ttl || DEFAULT_TTL,
            autoUpdate: options.keepAlive || true,
            gateway: options.gateway,
            enablePMP: Boolean(options.pmp && options.pmp.enabled)
        };
        if (this._options.ttl < DEFAULT_TTL) throw errcode(new Error(`NatManager ttl should be at least ${DEFAULT_TTL} seconds`), ERR_INVALID_PARAMETERS);
    }
    /**
   * Starts the NAT manager
   */ start() {
        if (isBrowser || !this._enabled) return;
        // done async to not slow down startup
        this._start().catch((err)=>{
            // hole punching errors are non-fatal
            log.error(err);
        });
    }
    async _start() {
        const addrs = this._transportManager.getAddrs();
        for (const addr of addrs){
            // try to open uPnP ports for each thin waist address
            const { family , host , port , transport  } = addr.toOptions();
            if (!addr.isThinWaistAddress() || transport !== 'tcp') continue;
            if (isLoopback(addr)) continue;
            if (family !== 4) continue;
            const client = this._getClient();
            const publicIp = this._externalIp || await client.externalIp();
            if (isPrivateIp(publicIp)) throw new Error(`${publicIp} is private - please set config.nat.externalIp to an externally routable IP or ensure you are not behind a double NAT`);
            const publicPort = highPort();
            log(`opening uPnP connection from ${publicIp}:${publicPort} to ${host}:${port}`);
            await client.map({
                publicPort,
                privatePort: port,
                protocol: transport.toUpperCase()
            });
            this._addressManager.addObservedAddr(Multiaddr.fromNodeAddress({
                family: 4,
                address: publicIp,
                port: publicPort
            }, transport));
        }
    }
    _getClient() {
        if (this._client) return this._client;
        const client = new NatAPI(this._options);
        /** @type {(...any: any) => any} */ const map = promisify(client.map.bind(client));
        /** @type {(...any: any) => any} */ const destroy = promisify(client.destroy.bind(client));
        /** @type {(...any: any) => any} */ const externalIp = promisify(client.externalIp.bind(client));
        // these are all network operations so add a retry
        this._client = {
            /**
       * @param  {...any} args
       * @returns {Promise<void>}
       */ map: (...args)=>retry(()=>map(...args)
                , {
                    onFailedAttempt: log.error,
                    unref: true
                })
            ,
            /**
       * @param  {...any} args
       * @returns {Promise<void>}
       */ destroy: (...args)=>retry(()=>destroy(...args)
                , {
                    onFailedAttempt: log.error,
                    unref: true
                })
            ,
            /**
       * @param  {...any} args
       * @returns {Promise<string>}
       */ externalIp: (...args)=>retry(()=>externalIp(...args)
                , {
                    onFailedAttempt: log.error,
                    unref: true
                })
        };
        return this._client;
    }
    /**
   * Stops the NAT manager
   *
   * @async
   */ async stop() {
        if (isBrowser || !this._client) return;
        try {
            await this._client.destroy();
            this._client = null;
        } catch (err) {
            log.error(err);
        }
    }
}
module.exports = NatManager;

},{"@motrix/nat-api":"joWnX","debug":"lWlU4","es6-promisify":"1pxme","multiaddr":"kOPrF","wherearewe":"kD0Bv","p-retry":"gvwam","private-ip":"4BzE5","../package.json":"cz6QZ","err-code":"eQvyh","./errors":"dO31S","libp2p-utils/src/multiaddr/is-loopback":"aoclU"}],"1pxme":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "promisify", ()=>promisify
);
var customArgumentsToken = "__ES6-PROMISIFY--CUSTOM-ARGUMENTS__";
function promisify(a1) {
    if ("function" != typeof a1) throw new TypeError("Argument to promisify must be a function");
    var b = a1[customArgumentsToken], c1 = promisify.Promise || Promise;
    if ("function" != typeof c1) throw new Error("No Promise implementation found; do you need a polyfill?");
    return function() {
        for(var d1 = arguments.length, e1 = Array(d1), f1 = 0; f1 < d1; f1++)e1[f1] = arguments[f1];
        return new c1((c, d2)=>{
            e1.push(function(a2) {
                if (a2) return d2(a2);
                for(var e = arguments.length, f = Array(1 < e ? e - 1 : 0), g = 1; g < e; g++)f[g - 1] = arguments[g];
                if (1 === f.length || !b) return c(f[0]);
                var h = {
                };
                f.forEach((a, c)=>{
                    var d = b[c];
                    d && (h[d] = a);
                }), c(h);
            }), a1.apply(this, e1);
        });
    };
}
promisify.argumentNames = "__ES6-PROMISIFY--CUSTOM-ARGUMENTS__", promisify.Promise = void 0;

},{"@parcel/transformer-js/src/esmodule-helpers.js":"ciiiV"}],"kD0Bv":[function(require,module,exports) {
var process = require("process");
'use strict';
/** @type {() => boolean} */ // @ts-ignore
const isElectron = require('is-electron');
const IS_ENV_WITH_DOM = typeof window === 'object' && typeof document === 'object' && document.nodeType === 9;
const IS_ELECTRON = isElectron();
const IS_BROWSER = IS_ENV_WITH_DOM && !IS_ELECTRON;
const IS_ELECTRON_MAIN = IS_ELECTRON && !IS_ENV_WITH_DOM;
const IS_ELECTRON_RENDERER = IS_ELECTRON && IS_ENV_WITH_DOM;
const IS_NODE = typeof require === 'function' && typeof process !== 'undefined' && typeof process.release !== 'undefined' && process.release.name === 'node' && !IS_ELECTRON;
// @ts-ignore
// eslint-disable-next-line no-undef
const IS_WEBWORKER = typeof importScripts === 'function' && typeof self !== 'undefined' && typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope;
const IS_TEST = typeof process !== 'undefined' && typeof process.env !== 'undefined' && false;
module.exports = {
    isTest: IS_TEST,
    isElectron: IS_ELECTRON,
    isElectronMain: IS_ELECTRON_MAIN,
    isElectronRenderer: IS_ELECTRON_RENDERER,
    isNode: IS_NODE,
    /**
   * Detects browser main thread  **NOT** web worker or service worker
   */ isBrowser: IS_BROWSER,
    isWebWorker: IS_WEBWORKER,
    isEnvWithDom: IS_ENV_WITH_DOM
};

},{"process":"lDnB8","is-electron":"ijHtZ"}],"gvwam":[function(require,module,exports) {
'use strict';
const retry = require('retry');
const networkErrorMsgs = [
    'Failed to fetch',
    'NetworkError when attempting to fetch resource.',
    'The Internet connection appears to be offline.',
    'Network request failed' // `cross-fetch`
];
class AbortError extends Error {
    constructor(message){
        super();
        if (message instanceof Error) {
            this.originalError = message;
            ({ message  } = message);
        } else {
            this.originalError = new Error(message);
            this.originalError.stack = this.stack;
        }
        this.name = 'AbortError';
        this.message = message;
    }
}
const decorateErrorWithCounts = (error, attemptNumber, options)=>{
    // Minus 1 from attemptNumber because the first attempt does not count as a retry
    const retriesLeft = options.retries - (attemptNumber - 1);
    error.attemptNumber = attemptNumber;
    error.retriesLeft = retriesLeft;
    return error;
};
const isNetworkError = (errorMessage)=>networkErrorMsgs.includes(errorMessage)
;
const pRetry = (input, options)=>new Promise((resolve, reject)=>{
        options = {
            onFailedAttempt: ()=>{
            },
            retries: 10,
            ...options
        };
        const operation = retry.operation(options);
        operation.attempt(async (attemptNumber)=>{
            try {
                resolve(await input(attemptNumber));
            } catch (error) {
                if (!(error instanceof Error)) {
                    reject(new TypeError(`Non-error was thrown: "${error}". You should only throw errors.`));
                    return;
                }
                if (error instanceof AbortError) {
                    operation.stop();
                    reject(error.originalError);
                } else if (error instanceof TypeError && !isNetworkError(error.message)) {
                    operation.stop();
                    reject(error);
                } else {
                    decorateErrorWithCounts(error, attemptNumber, options);
                    try {
                        await options.onFailedAttempt(error);
                    } catch (error1) {
                        reject(error1);
                        return;
                    }
                    if (!operation.retry(error)) reject(operation.mainError());
                }
            }
        });
    })
;
module.exports = pRetry;
// TODO: remove this in the next major version
module.exports.default = pRetry;
module.exports.AbortError = AbortError;

},{"retry":"gTrZy"}],"gTrZy":[function(require,module,exports) {
module.exports = require('./lib/retry');

},{"./lib/retry":"cm8Nb"}],"cm8Nb":[function(require,module,exports) {
var RetryOperation = require('./retry_operation');
exports.operation = function(options) {
    var timeouts = exports.timeouts(options);
    return new RetryOperation(timeouts, {
        forever: options && (options.forever || options.retries === Infinity),
        unref: options && options.unref,
        maxRetryTime: options && options.maxRetryTime
    });
};
exports.timeouts = function(options) {
    if (options instanceof Array) return [].concat(options);
    var opts = {
        retries: 10,
        factor: 2,
        minTimeout: 1000,
        maxTimeout: Infinity,
        randomize: false
    };
    for(var key in options)opts[key] = options[key];
    if (opts.minTimeout > opts.maxTimeout) throw new Error('minTimeout is greater than maxTimeout');
    var timeouts = [];
    for(var i = 0; i < opts.retries; i++)timeouts.push(this.createTimeout(i, opts));
    if (options && options.forever && !timeouts.length) timeouts.push(this.createTimeout(i, opts));
    // sort the array numerically ascending
    timeouts.sort(function(a, b) {
        return a - b;
    });
    return timeouts;
};
exports.createTimeout = function(attempt, opts) {
    var random = opts.randomize ? Math.random() + 1 : 1;
    var timeout = Math.round(random * Math.max(opts.minTimeout, 1) * Math.pow(opts.factor, attempt));
    timeout = Math.min(timeout, opts.maxTimeout);
    return timeout;
};
exports.wrap = function(obj, options, methods) {
    if (options instanceof Array) {
        methods = options;
        options = null;
    }
    if (!methods) {
        methods = [];
        for(var key in obj)if (typeof obj[key] === 'function') methods.push(key);
    }
    for(var i = 0; i < methods.length; i++){
        var method = methods[i];
        var original1 = obj[method];
        obj[method] = (function retryWrapper(original) {
            var op = exports.operation(options);
            var args = Array.prototype.slice.call(arguments, 1);
            var callback = args.pop();
            args.push(function(err) {
                if (op.retry(err)) return;
                if (err) arguments[0] = op.mainError();
                callback.apply(this, arguments);
            });
            op.attempt(function() {
                original.apply(obj, args);
            });
        }).bind(obj, original1);
        obj[method].options = options;
    }
};

},{"./retry_operation":"cUsjm"}],"cUsjm":[function(require,module,exports) {
function RetryOperation(timeouts, options) {
    // Compatibility for the old (timeouts, retryForever) signature
    if (typeof options === 'boolean') options = {
        forever: options
    };
    this._originalTimeouts = JSON.parse(JSON.stringify(timeouts));
    this._timeouts = timeouts;
    this._options = options || {
    };
    this._maxRetryTime = options && options.maxRetryTime || Infinity;
    this._fn = null;
    this._errors = [];
    this._attempts = 1;
    this._operationTimeout = null;
    this._operationTimeoutCb = null;
    this._timeout = null;
    this._operationStart = null;
    this._timer = null;
    if (this._options.forever) this._cachedTimeouts = this._timeouts.slice(0);
}
module.exports = RetryOperation;
RetryOperation.prototype.reset = function() {
    this._attempts = 1;
    this._timeouts = this._originalTimeouts.slice(0);
};
RetryOperation.prototype.stop = function() {
    if (this._timeout) clearTimeout(this._timeout);
    if (this._timer) clearTimeout(this._timer);
    this._timeouts = [];
    this._cachedTimeouts = null;
};
RetryOperation.prototype.retry = function(err) {
    if (this._timeout) clearTimeout(this._timeout);
    if (!err) return false;
    var currentTime = new Date().getTime();
    if (err && currentTime - this._operationStart >= this._maxRetryTime) {
        this._errors.push(err);
        this._errors.unshift(new Error('RetryOperation timeout occurred'));
        return false;
    }
    this._errors.push(err);
    var timeout = this._timeouts.shift();
    if (timeout === undefined) {
        if (this._cachedTimeouts) {
            // retry forever, only keep last error
            this._errors.splice(0, this._errors.length - 1);
            timeout = this._cachedTimeouts.slice(-1);
        } else return false;
    }
    var self = this;
    this._timer = setTimeout(function() {
        self._attempts++;
        if (self._operationTimeoutCb) {
            self._timeout = setTimeout(function() {
                self._operationTimeoutCb(self._attempts);
            }, self._operationTimeout);
            if (self._options.unref) self._timeout.unref();
        }
        self._fn(self._attempts);
    }, timeout);
    if (this._options.unref) this._timer.unref();
    return true;
};
RetryOperation.prototype.attempt = function(fn, timeoutOps) {
    this._fn = fn;
    if (timeoutOps) {
        if (timeoutOps.timeout) this._operationTimeout = timeoutOps.timeout;
        if (timeoutOps.cb) this._operationTimeoutCb = timeoutOps.cb;
    }
    var self = this;
    if (this._operationTimeoutCb) this._timeout = setTimeout(function() {
        self._operationTimeoutCb();
    }, self._operationTimeout);
    this._operationStart = new Date().getTime();
    this._fn(this._attempts);
};
RetryOperation.prototype.try = function(fn) {
    console.log('Using RetryOperation.try() is deprecated');
    this.attempt(fn);
};
RetryOperation.prototype.start = function(fn) {
    console.log('Using RetryOperation.start() is deprecated');
    this.attempt(fn);
};
RetryOperation.prototype.start = RetryOperation.prototype.try;
RetryOperation.prototype.errors = function() {
    return this._errors;
};
RetryOperation.prototype.attempts = function() {
    return this._attempts;
};
RetryOperation.prototype.mainError = function() {
    if (this._errors.length === 0) return null;
    var counts = {
    };
    var mainError = null;
    var mainErrorCount = 0;
    for(var i = 0; i < this._errors.length; i++){
        var error = this._errors[i];
        var message = error.message;
        var count = (counts[message] || 0) + 1;
        counts[message] = count;
        if (count >= mainErrorCount) {
            mainError = error;
            mainErrorCount = count;
        }
    }
    return mainError;
};

},{}],"aoclU":[function(require,module,exports) {
'use strict';
// @ts-ignore is-loopback-addr does not publish types
const isLoopbackAddr = require('is-loopback-addr');
/**
 * @typedef {import('multiaddr').Multiaddr} Multiaddr
 */ /**
 * Check if a given multiaddr is a loopback address.
 *
 * @param {Multiaddr} ma
 * @returns {boolean}
 */ function isLoopback(ma) {
    const { address  } = ma.nodeAddress();
    return isLoopbackAddr(address);
}
module.exports = isLoopback;

},{"is-loopback-addr":"8QbvQ"}],"8QbvQ":[function(require,module,exports) {
'use strict';
/**
 * Check if a given ip address is a loopback address
 *
 * @param {string} ip - ip address to check
 * @returns {boolean}
 */ function isLoopbackAddr(ip) {
    return /^127\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(ip) || /^::1$/.test(ip);
}
module.exports = isLoopbackAddr;

},{}],"5ljCS":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var ipfsBitswap = require('ipfs-bitswap');
var libp2p = require('./libp2p.js');
var multiaddr = require('multiaddr');
var errCode = require('err-code');
var blockStorage = require('../block-storage.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
class Network {
    constructor(peerId2, libp2p1, bitswap, repo, blockstore){
        this.peerId = peerId2;
        this.libp2p = libp2p1;
        this.bitswap = bitswap;
        this.repo = repo;
        this.blockstore = blockstore;
    }
    static async start({ peerId: peerId1 , repo: repo1 , print , options  }) {
        if (repo1.closed) await repo1.open();
        const config = await repo1.config.getAll();
        const libp2p$1 = await libp2p.createLibp2p({
            options,
            repo: repo1,
            peerId: peerId1,
            multiaddrs: readAddrs(peerId1, config),
            config,
            keychainConfig: undefined
        });
        if (libp2p$1.keychain) await libp2p$1.loadKeychain();
        await libp2p$1.start();
        for (const ma of libp2p$1.multiaddrs)print(`Swarm listening on ${ma}/p2p/${peerId1.toB58String()}`);
        const bitswap = ipfsBitswap.createBitswap(libp2p$1, repo1.blocks, {
            statsEnabled: true
        });
        await bitswap.start();
        const blockstore = new blockStorage.BlockStorage(repo1.blocks, bitswap);
        repo1.blocks = blockstore;
        repo1.pins.blockstore = blockstore;
        return new Network(peerId1, libp2p$1, bitswap, repo1, blockstore);
    }
    static async stop(network) {
        network.repo.blocks = network.blockstore.unwrap();
        network.repo.pins.blockstore = network.blockstore.unwrap();
        await Promise.all([
            network.bitswap.stop(),
            network.libp2p.stop()
        ]);
    }
}
const readAddrs = (peerId, config)=>{
    const peerIdStr = peerId.toB58String();
    const addrs = [];
    const swarm = config.Addresses && config.Addresses.Swarm || [];
    for (const addr of swarm){
        let ma = new multiaddr.Multiaddr(addr);
        if (ma.protoCodes().includes(WEBSOCKET_STAR_PROTO_CODE)) throw errCode__default['default'](new Error('websocket-star swarm addresses are not supported. See https://github.com/ipfs/js-ipfs/issues/2779'), 'ERR_WEBSOCKET_STAR_SWARM_ADDR_NOT_SUPPORTED');
        const maId = ma.getPeerId();
        if (maId && maId !== peerIdStr) ma = ma.encapsulate(`/p2p/${peerIdStr}`);
        addrs.push(ma);
    }
    return addrs;
};
const WEBSOCKET_STAR_PROTO_CODE = 479;
exports.Network = Network;

},{"ipfs-bitswap":"a8hoZ","./libp2p.js":"78HPV","multiaddr":"kOPrF","err-code":"eQvyh","../block-storage.js":"f7bgG"}],"a8hoZ":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var bitswap = require('./bitswap.js');
const createBitswap = (libp2p, blockstore, options = {
})=>{
    return new bitswap.Bitswap(libp2p, blockstore, options);
};
exports.createBitswap = createBitswap;

},{"./bitswap.js":"26ucc"}],"26ucc":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var index$3 = require('./want-manager/index.js');
var network = require('./network.js');
var index$2 = require('./decision-engine/index.js');
var notifications = require('./notifications.js');
var index = require('./utils/index.js');
var index$1 = require('./stats/index.js');
var nativeAbortController = require('native-abort-controller');
var anySignal = require('any-signal');
var base = require('blockstore-core/base');
var cid1 = require('multiformats/cid');
const defaultOptions = {
    statsEnabled: false,
    statsComputeThrottleTimeout: 1000,
    statsComputeThrottleMaxQueueSize: 1000
};
const statsKeys = [
    'blocksReceived',
    'dataReceived',
    'dupBlksReceived',
    'dupDataReceived',
    'blocksSent',
    'dataSent',
    'providesBufferLength',
    'wantListLength',
    'peerCount'
];
class Bitswap extends base.BaseBlockstore {
    constructor(libp2p, blockstore, options2 = {
    }){
        super();
        this._libp2p = libp2p;
        this._log = index.logger(this.peerId);
        this._options = Object.assign({
        }, defaultOptions, options2);
        this._stats = new index$1.Stats(statsKeys, {
            enabled: this._options.statsEnabled,
            computeThrottleTimeout: this._options.statsComputeThrottleTimeout,
            computeThrottleMaxQueueSize: this._options.statsComputeThrottleMaxQueueSize
        });
        this.network = new network.Network(libp2p, this, this._stats, {
            hashLoader: options2.hashLoader
        });
        this.blockstore = blockstore;
        this.engine = new index$2.DecisionEngine(this.peerId, blockstore, this.network, this._stats);
        this.wm = new index$3.WantManager(this.peerId, this.network, this._stats);
        this.notifications = new notifications.Notifications(this.peerId);
        this.started = false;
    }
    isStarted() {
        return this.started;
    }
    get peerId() {
        return this._libp2p.peerId;
    }
    async _receiveMessage(peerId, incoming) {
        try {
            await this.engine.messageReceived(peerId, incoming);
        } catch (err) {
            this._log('failed to receive message', incoming);
        }
        if (incoming.blocks.size === 0) return;
        const received = [];
        for (const [cidStr, data1] of incoming.blocks.entries()){
            const cid$1 = cid1.CID.parse(cidStr);
            received.push({
                wasWanted: this.wm.wantlist.contains(cid$1),
                cid: cid$1,
                data: data1
            });
        }
        this.wm.cancelWants(received.filter(({ wasWanted  })=>wasWanted
        ).map(({ cid  })=>cid
        ));
        await Promise.all(received.map(({ cid , wasWanted , data  })=>this._handleReceivedBlock(peerId, cid, data, wasWanted)
        ));
    }
    async _handleReceivedBlock(peerId1, cid4, data, wasWanted) {
        this._log('received block');
        const has = await this.blockstore.has(cid4);
        this._updateReceiveCounters(peerId1.toB58String(), cid4, data, has);
        if (!wasWanted) return;
        await this.put(cid4, data);
    }
    _updateReceiveCounters(peerIdStr, cid2, data2, exists) {
        this._stats.push(peerIdStr, 'blocksReceived', 1);
        this._stats.push(peerIdStr, 'dataReceived', data2.length);
        if (exists) {
            this._stats.push(peerIdStr, 'dupBlksReceived', 1);
            this._stats.push(peerIdStr, 'dupDataReceived', data2.length);
        }
    }
    _receiveError(err1) {
        this._log.error('ReceiveError: %s', err1.message);
    }
    _onPeerConnected(peerId2) {
        this.wm.connected(peerId2);
    }
    _onPeerDisconnected(peerId3) {
        this.wm.disconnected(peerId3);
        this.engine.peerDisconnected(peerId3);
        this._stats.disconnected(peerId3);
    }
    enableStats() {
        this._stats.enable();
    }
    disableStats() {
        this._stats.disable();
    }
    wantlistForPeer(peerId4, _options) {
        return this.engine.wantlistForPeer(peerId4);
    }
    ledgerForPeer(peerId5) {
        return this.engine.ledgerForPeer(peerId5);
    }
    async get(cid3, options1 = {
    }) {
        const fetchFromNetwork = (cid, options)=>{
            this.wm.wantBlocks([
                cid
            ], options);
            return this.notifications.wantBlock(cid, options);
        };
        let promptedNetwork = false;
        const loadOrFetchFromNetwork = async (cid, options)=>{
            try {
                const block = await this.blockstore.get(cid, options);
                return block;
            } catch (err2) {
                if (err2.code !== 'ERR_NOT_FOUND') throw err2;
                if (!promptedNetwork) {
                    promptedNetwork = true;
                    this.network.findAndConnect(cid).catch((err)=>this._log.error(err)
                    );
                }
                return fetchFromNetwork(cid, options);
            }
        };
        const controller = new nativeAbortController.AbortController();
        const signal = options1.signal ? anySignal.anySignal([
            options1.signal,
            controller.signal
        ]) : controller.signal;
        const block1 = await Promise.race([
            this.notifications.wantBlock(cid3, {
                signal
            }),
            loadOrFetchFromNetwork(cid3, {
                signal
            })
        ]);
        controller.abort();
        return block1;
    }
    async *getMany(cids, options = {
    }) {
        for await (const cid of cids)yield this.get(cid, options);
    }
    unwant(cids1) {
        const cidsArray = Array.isArray(cids1) ? cids1 : [
            cids1
        ];
        this.wm.unwantBlocks(cidsArray);
        cidsArray.forEach((cid)=>this.notifications.unwantBlock(cid)
        );
    }
    cancelWants(cids2) {
        this.wm.cancelWants(Array.isArray(cids2) ? cids2 : [
            cids2
        ]);
    }
    async put(cid, block, _options1) {
        await this.blockstore.put(cid, block);
        this._sendHaveBlockNotifications(cid, block);
    }
    async *putMany(source, options3) {
        for await (const { key , value  } of this.blockstore.putMany(source, options3)){
            this._sendHaveBlockNotifications(key, value);
            yield {
                key,
                value
            };
        }
    }
    _sendHaveBlockNotifications(cid5, data3) {
        this.notifications.hasBlock(cid5, data3);
        this.engine.receivedBlocks([
            {
                cid: cid5,
                data: data3
            }
        ]);
        this.network.provide(cid5).catch((err)=>{
            this._log.error('Failed to provide: %s', err.message);
        });
    }
    getWantlist() {
        return this.wm.wantlist.entries();
    }
    peers() {
        return this.engine.peers();
    }
    stat() {
        return this._stats;
    }
    start() {
        this.wm.start();
        this.network.start();
        this.engine.start();
        this.started = true;
    }
    stop() {
        this._stats.stop();
        this.wm.stop();
        this.network.stop();
        this.engine.stop();
        this.started = false;
    }
    unwrap() {
        return this.blockstore;
    }
}
exports.Bitswap = Bitswap;

},{"./want-manager/index.js":"bNT0P","./network.js":"eAxqn","./decision-engine/index.js":"vTfGd","./notifications.js":"gDWR1","./utils/index.js":"6RuEm","./stats/index.js":"enTlZ","native-abort-controller":"9z1Uk","any-signal":"1586s","blockstore-core/base":"ajjJw","multiformats/cid":"fJJnW"}],"bNT0P":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var index$2 = require('../message/index.js');
var index = require('../wantlist/index.js');
var constants = require('../constants.js');
var msgQueue = require('./msg-queue.js');
var index$1 = require('../utils/index.js');
var base58 = require('multiformats/bases/base58');
class WantManager {
    constructor(peerId, network, stats){
        this.peers = new Map();
        this.wantlist = new index.Wantlist(stats);
        this.network = network;
        this._stats = stats;
        this._peerId = peerId;
        this._log = index$1.logger(peerId, 'want');
    }
    _addEntries(cids, cancel, force) {
        const entries = cids.map((cid, i)=>{
            return new index$2.BitswapMessage.Entry(cid, constants.kMaxPriority - i, index$2.BitswapMessage.WantType.Block, cancel);
        });
        entries.forEach((e)=>{
            if (e.cancel) {
                if (force) this.wantlist.removeForce(e.cid.toString(base58.base58btc));
                else this.wantlist.remove(e.cid);
            } else {
                this._log('adding to wl');
                this.wantlist.add(e.cid, e.priority);
            }
        });
        for (const p of this.peers.values())p.addEntries(entries);
    }
    _startPeerHandler(peerId1) {
        let mq = this.peers.get(peerId1.toB58String());
        if (mq) {
            mq.refcnt++;
            return;
        }
        mq = new msgQueue.MsgQueue(this._peerId, peerId1, this.network);
        const fullwantlist = new index$2.BitswapMessage(true);
        for (const entry of this.wantlist.entries())fullwantlist.addEntry(entry[1].cid, entry[1].priority);
        mq.addMessage(fullwantlist);
        this.peers.set(peerId1.toB58String(), mq);
        return mq;
    }
    _stopPeerHandler(peerId2) {
        const mq = this.peers.get(peerId2.toB58String());
        if (!mq) return;
        mq.refcnt--;
        if (mq.refcnt > 0) return;
        this.peers.delete(peerId2.toB58String());
    }
    wantBlocks(cids1, options = {
    }) {
        this._addEntries(cids1, false);
        if (options && options.signal) options.signal.addEventListener('abort', ()=>{
            this.cancelWants(cids1);
        });
    }
    unwantBlocks(cids2) {
        this._log('unwant blocks: %s', cids2.length);
        this._addEntries(cids2, true, true);
    }
    cancelWants(cids3) {
        this._log('cancel wants: %s', cids3.length);
        this._addEntries(cids3, true);
    }
    connectedPeers() {
        return Array.from(this.peers.keys());
    }
    connected(peerId3) {
        this._startPeerHandler(peerId3);
    }
    disconnected(peerId4) {
        this._stopPeerHandler(peerId4);
    }
    start() {
    }
    stop() {
        this.peers.forEach((mq)=>this.disconnected(mq.peerId)
        );
    }
}
exports.WantManager = WantManager;

},{"../message/index.js":"3FcDb","../wantlist/index.js":"izq7D","../constants.js":"28yrY","./msg-queue.js":"beCn1","../utils/index.js":"6RuEm","multiformats/bases/base58":"6Rnqi"}],"3FcDb":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid6 = require('multiformats/cid');
var sha2 = require('multiformats/hashes/sha2');
var base58 = require('multiformats/bases/base58');
var vd = require('varint-decoder');
var varintEncoder = require('../utils/varint-encoder.js');
var index = require('../utils/index.js');
var message = require('./message.js');
var entry1 = require('./entry.js');
var errcode = require('err-code');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var vd__default = /*#__PURE__*/ _interopDefaultLegacy(vd);
var errcode__default = /*#__PURE__*/ _interopDefaultLegacy(errcode);
class BitswapMessage {
    constructor(full){
        this.full = full;
        this.wantlist = new Map();
        this.blocks = new Map();
        this.blockPresences = new Map();
        this.pendingBytes = 0;
    }
    get empty() {
        return this.blocks.size === 0 && this.wantlist.size === 0 && this.blockPresences.size === 0;
    }
    addEntry(cid1, priority, wantType, cancel, sendDontHave) {
        if (wantType == null) wantType = BitswapMessage.WantType.Block;
        const cidStr = cid1.toString(base58.base58btc);
        const entry$1 = this.wantlist.get(cidStr);
        if (entry$1) {
            if (entry$1.wantType === wantType) entry$1.priority = priority;
            if (cancel) entry$1.cancel = Boolean(cancel);
            if (sendDontHave) entry$1.sendDontHave = Boolean(sendDontHave);
            if (wantType === BitswapMessage.WantType.Block && entry$1.wantType === BitswapMessage.WantType.Have) entry$1.wantType = wantType;
        } else this.wantlist.set(cidStr, new entry1.BitswapMessageEntry(cid1, priority, wantType, cancel, sendDontHave));
    }
    addBlock(cid2, block) {
        const cidStr = cid2.toString(base58.base58btc);
        this.blocks.set(cidStr, block);
    }
    addHave(cid3) {
        const cidStr = cid3.toString(base58.base58btc);
        if (!this.blockPresences.has(cidStr)) this.blockPresences.set(cidStr, BitswapMessage.BlockPresenceType.Have);
    }
    addDontHave(cid4) {
        const cidStr = cid4.toString(base58.base58btc);
        if (!this.blockPresences.has(cidStr)) this.blockPresences.set(cidStr, BitswapMessage.BlockPresenceType.DontHave);
    }
    cancel(cid5) {
        const cidStr = cid5.toString(base58.base58btc);
        this.wantlist.delete(cidStr);
        this.addEntry(cid5, 0, BitswapMessage.WantType.Block, true, false);
    }
    setPendingBytes(size) {
        this.pendingBytes = size;
    }
    serializeToBitswap100() {
        const msg = {
            wantlist: {
                entries: Array.from(this.wantlist.values()).map((entry)=>{
                    return {
                        block: entry.cid.bytes,
                        priority: Number(entry.priority),
                        cancel: Boolean(entry.cancel)
                    };
                }),
                full: this.full ? true : undefined
            },
            blocks: Array.from(this.blocks.values())
        };
        return message.Message.encode(msg).finish();
    }
    serializeToBitswap110() {
        const msg = {
            wantlist: {
                entries: Array.from(this.wantlist.values()).map((entry)=>{
                    return {
                        block: entry.cid.bytes,
                        priority: Number(entry.priority),
                        wantType: entry.wantType,
                        cancel: Boolean(entry.cancel),
                        sendDontHave: Boolean(entry.sendDontHave)
                    };
                }),
                full: this.full ? true : undefined
            },
            blockPresences: [],
            payload: [],
            pendingBytes: this.pendingBytes
        };
        for (const [cidStr, data] of this.blocks.entries()){
            const cid$1 = cid6.CID.parse(cidStr);
            const version = cid$1.version;
            const codec = cid$1.code;
            const multihash = cid$1.multihash.code;
            const digestLength = cid$1.multihash.digest.length;
            const prefix = varintEncoder([
                version,
                codec,
                multihash,
                digestLength
            ]);
            msg.payload.push(new message.Message.Block({
                prefix,
                data
            }));
        }
        for (const [cidStr1, bpType] of this.blockPresences)msg.blockPresences.push(new message.Message.BlockPresence({
            cid: cid6.CID.parse(cidStr1).bytes,
            type: bpType
        }));
        if (this.pendingBytes > 0) msg.pendingBytes = this.pendingBytes;
        return message.Message.encode(msg).finish();
    }
    equals(other) {
        if (this.full !== other.full || this.pendingBytes !== other.pendingBytes || !index.isMapEqual(this.wantlist, other.wantlist) || !index.isMapEqual(this.blocks, other.blocks) || !index.isMapEqual(this.blockPresences, other.blockPresences)) return false;
        return true;
    }
    get [Symbol.toStringTag]() {
        const list = Array.from(this.wantlist.keys());
        const blocks = Array.from(this.blocks.keys());
        return `BitswapMessage <full: ${this.full}, list: ${list}, blocks: ${blocks}>`;
    }
}
BitswapMessage.deserialize = async (raw, hashLoader)=>{
    const decoded = message.Message.decode(raw);
    const isFull = decoded.wantlist && decoded.wantlist.full || false;
    const msg = new BitswapMessage(isFull);
    if (decoded.wantlist && decoded.wantlist.entries) decoded.wantlist.entries.forEach((entry)=>{
        if (!entry.block) return;
        const cid$1 = cid6.CID.decode(entry.block);
        msg.addEntry(cid$1, entry.priority || 0, entry.wantType, Boolean(entry.cancel), Boolean(entry.sendDontHave));
    });
    if (decoded.blockPresences) decoded.blockPresences.forEach((blockPresence)=>{
        if (!blockPresence.cid) return;
        const cid$1 = cid6.CID.decode(blockPresence.cid);
        if (blockPresence.type === BitswapMessage.BlockPresenceType.Have) msg.addHave(cid$1);
        else msg.addDontHave(cid$1);
    });
    if (decoded.blocks.length > 0) {
        await Promise.all(decoded.blocks.map(async (b)=>{
            const hash = await sha2.sha256.digest(b);
            const cid$1 = cid6.CID.createV0(hash);
            msg.addBlock(cid$1, b);
        }));
        return msg;
    }
    if (decoded.payload.length > 0) {
        await Promise.all(decoded.payload.map(async (p)=>{
            if (!p.prefix || !p.data) return;
            const values = vd__default["default"](p.prefix);
            const cidVersion = values[0];
            const multicodec = values[1];
            const hashAlg = values[2];
            const hasher = hashAlg === sha2.sha256.code ? sha2.sha256 : hashLoader && await hashLoader.getHasher(hashAlg);
            if (!hasher) throw errcode__default["default"](new Error('Unknown hash algorithm'), 'ERR_UNKNOWN_HASH_ALG');
            const hash = await hasher.digest(p.data);
            const cid$1 = cid6.CID.create(cidVersion, multicodec, hash);
            msg.addBlock(cid$1, p.data);
        }));
        msg.setPendingBytes(decoded.pendingBytes);
        return msg;
    }
    return msg;
};
BitswapMessage.blockPresenceSize = (cid)=>{
    return cid.bytes.length + 1;
};
BitswapMessage.Entry = entry1.BitswapMessageEntry;
BitswapMessage.WantType = {
    Block: message.Message.Wantlist.WantType.Block,
    Have: message.Message.Wantlist.WantType.Have
};
BitswapMessage.BlockPresenceType = {
    Have: message.Message.BlockPresenceType.Have,
    DontHave: message.Message.BlockPresenceType.DontHave
};
exports.BitswapMessage = BitswapMessage;

},{"multiformats/cid":"fJJnW","multiformats/hashes/sha2":"i8JnP","multiformats/bases/base58":"6Rnqi","varint-decoder":"k6cDj","../utils/varint-encoder.js":"8PSVE","../utils/index.js":"6RuEm","./message.js":"1hhWn","./entry.js":"8ZuAR","err-code":"eQvyh"}],"k6cDj":[function(require,module,exports) {
'use strict';
const varint = require('varint');
module.exports = (buf)=>{
    if (!(buf instanceof Uint8Array)) throw new Error('arg needs to be a Uint8Array');
    const result = [];
    while(buf.length > 0){
        const num = varint.decode(buf);
        result.push(num);
        buf = buf.slice(varint.decode.bytes);
    }
    return result;
};

},{"varint":"lJDYP"}],"lJDYP":[function(require,module,exports) {
module.exports = {
    encode: require('./encode.js'),
    decode: require('./decode.js'),
    encodingLength: require('./length.js')
};

},{"./encode.js":"fGDMW","./decode.js":"58nLT","./length.js":"2RJmW"}],"fGDMW":[function(require,module,exports) {
module.exports = encode;
var MSB = 128, REST = 127, MSBALL = ~REST, INT = Math.pow(2, 31);
function encode(num, out, offset) {
    out = out || [];
    offset = offset || 0;
    var oldOffset = offset;
    while(num >= INT){
        out[offset++] = num & 255 | MSB;
        num /= 128;
    }
    while(num & MSBALL){
        out[offset++] = num & 255 | MSB;
        num >>>= 7;
    }
    out[offset] = num | 0;
    encode.bytes = offset - oldOffset + 1;
    return out;
}

},{}],"58nLT":[function(require,module,exports) {
module.exports = read;
var MSB = 128, REST = 127;
function read(buf, offset) {
    var res = 0, offset = offset || 0, shift = 0, counter = offset, b, l = buf.length;
    do {
        if (counter >= l) {
            read.bytes = 0;
            throw new RangeError('Could not decode varint');
        }
        b = buf[counter++];
        res += shift < 28 ? (b & REST) << shift : (b & REST) * Math.pow(2, shift);
        shift += 7;
    }while (b >= MSB)
    read.bytes = counter - offset;
    return res;
}

},{}],"2RJmW":[function(require,module,exports) {
var N1 = Math.pow(2, 7);
var N2 = Math.pow(2, 14);
var N3 = Math.pow(2, 21);
var N4 = Math.pow(2, 28);
var N5 = Math.pow(2, 35);
var N6 = Math.pow(2, 42);
var N7 = Math.pow(2, 49);
var N8 = Math.pow(2, 56);
var N9 = Math.pow(2, 63);
module.exports = function(value) {
    return value < N1 ? 1 : value < N2 ? 2 : value < N3 ? 3 : value < N4 ? 4 : value < N5 ? 5 : value < N6 ? 6 : value < N7 ? 7 : value < N8 ? 8 : value < N9 ? 9 : 10;
};

},{}],"8PSVE":[function(require,module,exports) {
'use strict';
var varint = require('varint');
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n["default"] = e;
    return Object.freeze(n);
}
var varint__namespace = /*#__PURE__*/ _interopNamespace(varint);
function varintEncoder(buf) {
    let out = new Uint8Array(buf.reduce((acc, curr)=>{
        return acc + varint__namespace.default.encodingLength(curr);
    }, 0));
    let offset = 0;
    for (const num of buf){
        out = varint__namespace.encode(num, out, offset);
        offset += varint__namespace.default.encodingLength(num);
    }
    return out;
}
module.exports = varintEncoder;

},{"varint":"l84uL"}],"6RuEm":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var debug = require('debug');
var equals = require('uint8arrays/equals');
var entry = require('../message/entry.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var debug__default = /*#__PURE__*/ _interopDefaultLegacy(debug);
const logger = (id, subsystem)=>{
    const name = [
        'bitswap'
    ];
    if (subsystem) name.push(subsystem);
    if (id) name.push(`${id.toB58String().slice(0, 8)}`);
    return Object.assign(debug__default["default"](name.join(':')), {
        error: debug__default["default"](name.concat([
            'error'
        ]).join(':'))
    });
};
const includesWith = (pred, x, list)=>{
    let idx = 0;
    const len = list.length;
    while(idx < len){
        if (pred(x, list[idx])) return true;
        idx += 1;
    }
    return false;
};
const uniqWith = (pred, list)=>{
    let idx = 0;
    const len = list.length;
    const result = [];
    let item;
    while(idx < len){
        item = list[idx];
        if (!includesWith(pred, item, result)) result[result.length] = item;
        idx += 1;
    }
    return result;
};
const groupBy = (pred, list)=>{
    return list.reduce((acc, v)=>{
        const k = pred(v);
        if (acc[k]) acc[k].push(v);
        else acc[k] = [
            v
        ];
        return acc;
    }, {
    });
};
const pullAllWith = (pred, list, values)=>{
    return list.filter((i)=>{
        return !includesWith(pred, i, values);
    });
};
const sortBy = (fn, list)=>{
    return Array.prototype.slice.call(list, 0).sort((a, b)=>{
        const aa = fn(a);
        const bb = fn(b);
        return aa < bb ? -1 : aa > bb ? 1 : 0;
    });
};
const isMapEqual = (a, b)=>{
    if (a.size !== b.size) return false;
    for (const [key, valueA] of a){
        const valueB = b.get(key);
        if (valueB === undefined) return false;
        if (valueA instanceof Uint8Array && valueB instanceof Uint8Array && !equals.equals(valueA, valueB)) return false;
        if (valueA instanceof entry.BitswapMessageEntry && valueB instanceof entry.BitswapMessageEntry && !valueA.equals(valueB)) return false;
    }
    return true;
};
exports.groupBy = groupBy;
exports.includesWith = includesWith;
exports.isMapEqual = isMapEqual;
exports.logger = logger;
exports.pullAllWith = pullAllWith;
exports.sortBy = sortBy;
exports.uniqWith = uniqWith;

},{"debug":"lWlU4","uint8arrays/equals":"fjLeN","../message/entry.js":"8ZuAR"}],"8ZuAR":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var index = require('../wantlist/index.js');
var base58 = require('multiformats/bases/base58');
const WantlistEntry = index.Wantlist.Entry;
class BitswapMessageEntry {
    constructor(cid, priority, wantType, cancel, sendDontHave){
        this.entry = new WantlistEntry(cid, priority, wantType);
        this.cancel = Boolean(cancel);
        this.sendDontHave = Boolean(sendDontHave);
    }
    get cid() {
        return this.entry.cid;
    }
    set cid(cid1) {
        this.entry.cid = cid1;
    }
    get priority() {
        return this.entry.priority;
    }
    set priority(val) {
        this.entry.priority = val;
    }
    get wantType() {
        return this.entry.wantType;
    }
    set wantType(val1) {
        this.entry.wantType = val1;
    }
    get [Symbol.toStringTag]() {
        const cidStr = this.cid.toString(base58.base58btc);
        return `BitswapMessageEntry ${cidStr} <cancel: ${this.cancel}, priority: ${this.priority}>`;
    }
    equals(other) {
        return this.cancel === other.cancel && this.sendDontHave === other.sendDontHave && this.wantType === other.wantType && this.entry.equals(other.entry);
    }
}
exports.BitswapMessageEntry = BitswapMessageEntry;

},{"../wantlist/index.js":"izq7D","multiformats/bases/base58":"6Rnqi"}],"izq7D":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var entry = require('./entry.js');
var base58 = require('multiformats/bases/base58');
var message = require('../message/message.js');
const WantType = {
    Block: message.Message.Wantlist.WantType.Block,
    Have: message.Message.Wantlist.WantType.Have
};
const sortBy = (fn, list)=>{
    return Array.prototype.slice.call(list, 0).sort((a, b)=>{
        const aa = fn(a);
        const bb = fn(b);
        return aa < bb ? -1 : aa > bb ? 1 : 0;
    });
};
class Wantlist {
    constructor(stats){
        this.set = new Map();
        this._stats = stats;
    }
    get length() {
        return this.set.size;
    }
    add(cid, priority, wantType) {
        const cidStr = cid.toString(base58.base58btc);
        const entry$1 = this.set.get(cidStr);
        if (entry$1) {
            entry$1.inc();
            entry$1.priority = priority;
            if (entry$1.wantType === WantType.Have && wantType === WantType.Block) entry$1.wantType = wantType;
        } else {
            this.set.set(cidStr, new entry.WantListEntry(cid, priority, wantType));
            if (this._stats) this._stats.push(null, 'wantListSize', 1);
        }
    }
    remove(cid1) {
        const cidStr = cid1.toString(base58.base58btc);
        const entry = this.set.get(cidStr);
        if (!entry) return;
        entry.dec();
        if (entry.hasRefs()) return;
        this.set.delete(cidStr);
        if (this._stats) this._stats.push(null, 'wantListSize', -1);
    }
    removeForce(cidStr) {
        if (this.set.has(cidStr)) this.set.delete(cidStr);
    }
    forEach(fn) {
        return this.set.forEach(fn);
    }
    entries() {
        return this.set.entries();
    }
    sortedEntries() {
        return new Map(sortBy((o)=>o[1].key
        , Array.from(this.set.entries())));
    }
    contains(cid2) {
        const cidStr = cid2.toString(base58.base58btc);
        return this.set.has(cidStr);
    }
    get(cid3) {
        const cidStr = cid3.toString(base58.base58btc);
        return this.set.get(cidStr);
    }
}
Wantlist.Entry = entry.WantListEntry;
exports.Wantlist = Wantlist;

},{"./entry.js":"1Sonv","multiformats/bases/base58":"6Rnqi","../message/message.js":"1hhWn"}],"1Sonv":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var base58 = require('multiformats/bases/base58');
class WantListEntry {
    constructor(cid, priority, wantType){
        this._refCounter = 1;
        this.cid = cid;
        this.priority = priority || 1;
        this.wantType = wantType;
    }
    inc() {
        this._refCounter += 1;
    }
    dec() {
        this._refCounter = Math.max(0, this._refCounter - 1);
    }
    hasRefs() {
        return this._refCounter > 0;
    }
    get [Symbol.toStringTag]() {
        const cidStr = this.cid.toString(base58.base58btc);
        return `WantlistEntry <key: ${cidStr}, priority: ${this.priority}, refs: ${this._refCounter}>`;
    }
    equals(other) {
        return this._refCounter === other._refCounter && this.cid.equals(other.cid) && this.priority === other.priority && this.wantType === other.wantType;
    }
}
exports.WantListEntry = WantListEntry;

},{"multiformats/bases/base58":"6Rnqi"}],"1hhWn":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var $protobuf = require('protobufjs/minimal.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var $protobuf__default = /*#__PURE__*/ _interopDefaultLegacy($protobuf);
const $Reader = $protobuf__default["default"].Reader, $Writer = $protobuf__default["default"].Writer, $util = $protobuf__default["default"].util;
const $root = $protobuf__default["default"].roots['ipfs-bitswap'] || ($protobuf__default["default"].roots['ipfs-bitswap'] = {
});
const Message1 = $root.Message = (()=>{
    function Message(p) {
        this.blocks = [];
        this.payload = [];
        this.blockPresences = [];
        if (p) {
            for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
        }
    }
    Message.prototype.wantlist = null;
    Message.prototype.blocks = $util.emptyArray;
    Message.prototype.payload = $util.emptyArray;
    Message.prototype.blockPresences = $util.emptyArray;
    Message.prototype.pendingBytes = 0;
    Message.encode = function encode(m, w) {
        if (!w) w = $Writer.create();
        if (m.wantlist != null && Object.hasOwnProperty.call(m, 'wantlist')) $root.Message.Wantlist.encode(m.wantlist, w.uint32(10).fork()).ldelim();
        if (m.blocks != null && m.blocks.length) for(var i = 0; i < m.blocks.length; ++i)w.uint32(18).bytes(m.blocks[i]);
        if (m.payload != null && m.payload.length) for(var i = 0; i < m.payload.length; ++i)$root.Message.Block.encode(m.payload[i], w.uint32(26).fork()).ldelim();
        if (m.blockPresences != null && m.blockPresences.length) for(var i = 0; i < m.blockPresences.length; ++i)$root.Message.BlockPresence.encode(m.blockPresences[i], w.uint32(34).fork()).ldelim();
        if (m.pendingBytes != null && Object.hasOwnProperty.call(m, 'pendingBytes')) w.uint32(40).int32(m.pendingBytes);
        return w;
    };
    Message.decode = function decode(r, l) {
        if (!(r instanceof $Reader)) r = $Reader.create(r);
        var c = l === undefined ? r.len : r.pos + l, m = new $root.Message();
        while(r.pos < c){
            var t = r.uint32();
            switch(t >>> 3){
                case 1:
                    m.wantlist = $root.Message.Wantlist.decode(r, r.uint32());
                    break;
                case 2:
                    if (!(m.blocks && m.blocks.length)) m.blocks = [];
                    m.blocks.push(r.bytes());
                    break;
                case 3:
                    if (!(m.payload && m.payload.length)) m.payload = [];
                    m.payload.push($root.Message.Block.decode(r, r.uint32()));
                    break;
                case 4:
                    if (!(m.blockPresences && m.blockPresences.length)) m.blockPresences = [];
                    m.blockPresences.push($root.Message.BlockPresence.decode(r, r.uint32()));
                    break;
                case 5:
                    m.pendingBytes = r.int32();
                    break;
                default:
                    r.skipType(t & 7);
                    break;
            }
        }
        return m;
    };
    Message.fromObject = function fromObject(d) {
        if (d instanceof $root.Message) return d;
        var m = new $root.Message();
        if (d.wantlist != null) {
            if (typeof d.wantlist !== 'object') throw TypeError('.Message.wantlist: object expected');
            m.wantlist = $root.Message.Wantlist.fromObject(d.wantlist);
        }
        if (d.blocks) {
            if (!Array.isArray(d.blocks)) throw TypeError('.Message.blocks: array expected');
            m.blocks = [];
            for(var i = 0; i < d.blocks.length; ++i){
                if (typeof d.blocks[i] === 'string') $util.base64.decode(d.blocks[i], m.blocks[i] = $util.newBuffer($util.base64.length(d.blocks[i])), 0);
                else if (d.blocks[i].length) m.blocks[i] = d.blocks[i];
            }
        }
        if (d.payload) {
            if (!Array.isArray(d.payload)) throw TypeError('.Message.payload: array expected');
            m.payload = [];
            for(var i = 0; i < d.payload.length; ++i){
                if (typeof d.payload[i] !== 'object') throw TypeError('.Message.payload: object expected');
                m.payload[i] = $root.Message.Block.fromObject(d.payload[i]);
            }
        }
        if (d.blockPresences) {
            if (!Array.isArray(d.blockPresences)) throw TypeError('.Message.blockPresences: array expected');
            m.blockPresences = [];
            for(var i = 0; i < d.blockPresences.length; ++i){
                if (typeof d.blockPresences[i] !== 'object') throw TypeError('.Message.blockPresences: object expected');
                m.blockPresences[i] = $root.Message.BlockPresence.fromObject(d.blockPresences[i]);
            }
        }
        if (d.pendingBytes != null) m.pendingBytes = d.pendingBytes | 0;
        return m;
    };
    Message.toObject = function toObject(m, o) {
        if (!o) o = {
        };
        var d = {
        };
        if (o.arrays || o.defaults) {
            d.blocks = [];
            d.payload = [];
            d.blockPresences = [];
        }
        if (o.defaults) {
            d.wantlist = null;
            d.pendingBytes = 0;
        }
        if (m.wantlist != null && m.hasOwnProperty('wantlist')) d.wantlist = $root.Message.Wantlist.toObject(m.wantlist, o);
        if (m.blocks && m.blocks.length) {
            d.blocks = [];
            for(var j = 0; j < m.blocks.length; ++j)d.blocks[j] = o.bytes === String ? $util.base64.encode(m.blocks[j], 0, m.blocks[j].length) : o.bytes === Array ? Array.prototype.slice.call(m.blocks[j]) : m.blocks[j];
        }
        if (m.payload && m.payload.length) {
            d.payload = [];
            for(var j = 0; j < m.payload.length; ++j)d.payload[j] = $root.Message.Block.toObject(m.payload[j], o);
        }
        if (m.blockPresences && m.blockPresences.length) {
            d.blockPresences = [];
            for(var j = 0; j < m.blockPresences.length; ++j)d.blockPresences[j] = $root.Message.BlockPresence.toObject(m.blockPresences[j], o);
        }
        if (m.pendingBytes != null && m.hasOwnProperty('pendingBytes')) d.pendingBytes = m.pendingBytes;
        return d;
    };
    Message.prototype.toJSON = function toJSON() {
        return this.constructor.toObject(this, $protobuf__default["default"].util.toJSONOptions);
    };
    Message.Wantlist = (function() {
        function Wantlist(p) {
            this.entries = [];
            if (p) {
                for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
            }
        }
        Wantlist.prototype.entries = $util.emptyArray;
        Wantlist.prototype.full = false;
        Wantlist.encode = function encode(m, w) {
            if (!w) w = $Writer.create();
            if (m.entries != null && m.entries.length) for(var i = 0; i < m.entries.length; ++i)$root.Message.Wantlist.Entry.encode(m.entries[i], w.uint32(10).fork()).ldelim();
            if (m.full != null && Object.hasOwnProperty.call(m, 'full')) w.uint32(16).bool(m.full);
            return w;
        };
        Wantlist.decode = function decode(r, l) {
            if (!(r instanceof $Reader)) r = $Reader.create(r);
            var c = l === undefined ? r.len : r.pos + l, m = new $root.Message.Wantlist();
            while(r.pos < c){
                var t = r.uint32();
                switch(t >>> 3){
                    case 1:
                        if (!(m.entries && m.entries.length)) m.entries = [];
                        m.entries.push($root.Message.Wantlist.Entry.decode(r, r.uint32()));
                        break;
                    case 2:
                        m.full = r.bool();
                        break;
                    default:
                        r.skipType(t & 7);
                        break;
                }
            }
            return m;
        };
        Wantlist.fromObject = function fromObject(d) {
            if (d instanceof $root.Message.Wantlist) return d;
            var m = new $root.Message.Wantlist();
            if (d.entries) {
                if (!Array.isArray(d.entries)) throw TypeError('.Message.Wantlist.entries: array expected');
                m.entries = [];
                for(var i = 0; i < d.entries.length; ++i){
                    if (typeof d.entries[i] !== 'object') throw TypeError('.Message.Wantlist.entries: object expected');
                    m.entries[i] = $root.Message.Wantlist.Entry.fromObject(d.entries[i]);
                }
            }
            if (d.full != null) m.full = Boolean(d.full);
            return m;
        };
        Wantlist.toObject = function toObject(m, o) {
            if (!o) o = {
            };
            var d = {
            };
            if (o.arrays || o.defaults) d.entries = [];
            if (o.defaults) d.full = false;
            if (m.entries && m.entries.length) {
                d.entries = [];
                for(var j = 0; j < m.entries.length; ++j)d.entries[j] = $root.Message.Wantlist.Entry.toObject(m.entries[j], o);
            }
            if (m.full != null && m.hasOwnProperty('full')) d.full = m.full;
            return d;
        };
        Wantlist.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf__default["default"].util.toJSONOptions);
        };
        Wantlist.WantType = (function() {
            const valuesById = {
            }, values = Object.create(valuesById);
            values[valuesById[0] = 'Block'] = 0;
            values[valuesById[1] = 'Have'] = 1;
            return values;
        })();
        Wantlist.Entry = (function() {
            function Entry(p) {
                if (p) {
                    for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
                }
            }
            Entry.prototype.block = $util.newBuffer([]);
            Entry.prototype.priority = 0;
            Entry.prototype.cancel = false;
            Entry.prototype.wantType = 0;
            Entry.prototype.sendDontHave = false;
            Entry.encode = function encode(m, w) {
                if (!w) w = $Writer.create();
                if (m.block != null && Object.hasOwnProperty.call(m, 'block')) w.uint32(10).bytes(m.block);
                if (m.priority != null && Object.hasOwnProperty.call(m, 'priority')) w.uint32(16).int32(m.priority);
                if (m.cancel != null && Object.hasOwnProperty.call(m, 'cancel')) w.uint32(24).bool(m.cancel);
                if (m.wantType != null && Object.hasOwnProperty.call(m, 'wantType')) w.uint32(32).int32(m.wantType);
                if (m.sendDontHave != null && Object.hasOwnProperty.call(m, 'sendDontHave')) w.uint32(40).bool(m.sendDontHave);
                return w;
            };
            Entry.decode = function decode(r, l) {
                if (!(r instanceof $Reader)) r = $Reader.create(r);
                var c = l === undefined ? r.len : r.pos + l, m = new $root.Message.Wantlist.Entry();
                while(r.pos < c){
                    var t = r.uint32();
                    switch(t >>> 3){
                        case 1:
                            m.block = r.bytes();
                            break;
                        case 2:
                            m.priority = r.int32();
                            break;
                        case 3:
                            m.cancel = r.bool();
                            break;
                        case 4:
                            m.wantType = r.int32();
                            break;
                        case 5:
                            m.sendDontHave = r.bool();
                            break;
                        default:
                            r.skipType(t & 7);
                            break;
                    }
                }
                return m;
            };
            Entry.fromObject = function fromObject(d) {
                if (d instanceof $root.Message.Wantlist.Entry) return d;
                var m = new $root.Message.Wantlist.Entry();
                if (d.block != null) {
                    if (typeof d.block === 'string') $util.base64.decode(d.block, m.block = $util.newBuffer($util.base64.length(d.block)), 0);
                    else if (d.block.length) m.block = d.block;
                }
                if (d.priority != null) m.priority = d.priority | 0;
                if (d.cancel != null) m.cancel = Boolean(d.cancel);
                switch(d.wantType){
                    case 'Block':
                    case 0:
                        m.wantType = 0;
                        break;
                    case 'Have':
                    case 1:
                        m.wantType = 1;
                        break;
                }
                if (d.sendDontHave != null) m.sendDontHave = Boolean(d.sendDontHave);
                return m;
            };
            Entry.toObject = function toObject(m, o) {
                if (!o) o = {
                };
                var d = {
                };
                if (o.defaults) {
                    if (o.bytes === String) d.block = '';
                    else {
                        d.block = [];
                        if (o.bytes !== Array) d.block = $util.newBuffer(d.block);
                    }
                    d.priority = 0;
                    d.cancel = false;
                    d.wantType = o.enums === String ? 'Block' : 0;
                    d.sendDontHave = false;
                }
                if (m.block != null && m.hasOwnProperty('block')) d.block = o.bytes === String ? $util.base64.encode(m.block, 0, m.block.length) : o.bytes === Array ? Array.prototype.slice.call(m.block) : m.block;
                if (m.priority != null && m.hasOwnProperty('priority')) d.priority = m.priority;
                if (m.cancel != null && m.hasOwnProperty('cancel')) d.cancel = m.cancel;
                if (m.wantType != null && m.hasOwnProperty('wantType')) d.wantType = o.enums === String ? $root.Message.Wantlist.WantType[m.wantType] : m.wantType;
                if (m.sendDontHave != null && m.hasOwnProperty('sendDontHave')) d.sendDontHave = m.sendDontHave;
                return d;
            };
            Entry.prototype.toJSON = function toJSON() {
                return this.constructor.toObject(this, $protobuf__default["default"].util.toJSONOptions);
            };
            return Entry;
        })();
        return Wantlist;
    })();
    Message.Block = (function() {
        function Block(p) {
            if (p) {
                for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
            }
        }
        Block.prototype.prefix = $util.newBuffer([]);
        Block.prototype.data = $util.newBuffer([]);
        Block.encode = function encode(m, w) {
            if (!w) w = $Writer.create();
            if (m.prefix != null && Object.hasOwnProperty.call(m, 'prefix')) w.uint32(10).bytes(m.prefix);
            if (m.data != null && Object.hasOwnProperty.call(m, 'data')) w.uint32(18).bytes(m.data);
            return w;
        };
        Block.decode = function decode(r, l) {
            if (!(r instanceof $Reader)) r = $Reader.create(r);
            var c = l === undefined ? r.len : r.pos + l, m = new $root.Message.Block();
            while(r.pos < c){
                var t = r.uint32();
                switch(t >>> 3){
                    case 1:
                        m.prefix = r.bytes();
                        break;
                    case 2:
                        m.data = r.bytes();
                        break;
                    default:
                        r.skipType(t & 7);
                        break;
                }
            }
            return m;
        };
        Block.fromObject = function fromObject(d) {
            if (d instanceof $root.Message.Block) return d;
            var m = new $root.Message.Block();
            if (d.prefix != null) {
                if (typeof d.prefix === 'string') $util.base64.decode(d.prefix, m.prefix = $util.newBuffer($util.base64.length(d.prefix)), 0);
                else if (d.prefix.length) m.prefix = d.prefix;
            }
            if (d.data != null) {
                if (typeof d.data === 'string') $util.base64.decode(d.data, m.data = $util.newBuffer($util.base64.length(d.data)), 0);
                else if (d.data.length) m.data = d.data;
            }
            return m;
        };
        Block.toObject = function toObject(m, o) {
            if (!o) o = {
            };
            var d = {
            };
            if (o.defaults) {
                if (o.bytes === String) d.prefix = '';
                else {
                    d.prefix = [];
                    if (o.bytes !== Array) d.prefix = $util.newBuffer(d.prefix);
                }
                if (o.bytes === String) d.data = '';
                else {
                    d.data = [];
                    if (o.bytes !== Array) d.data = $util.newBuffer(d.data);
                }
            }
            if (m.prefix != null && m.hasOwnProperty('prefix')) d.prefix = o.bytes === String ? $util.base64.encode(m.prefix, 0, m.prefix.length) : o.bytes === Array ? Array.prototype.slice.call(m.prefix) : m.prefix;
            if (m.data != null && m.hasOwnProperty('data')) d.data = o.bytes === String ? $util.base64.encode(m.data, 0, m.data.length) : o.bytes === Array ? Array.prototype.slice.call(m.data) : m.data;
            return d;
        };
        Block.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf__default["default"].util.toJSONOptions);
        };
        return Block;
    })();
    Message.BlockPresenceType = (function() {
        const valuesById = {
        }, values = Object.create(valuesById);
        values[valuesById[0] = 'Have'] = 0;
        values[valuesById[1] = 'DontHave'] = 1;
        return values;
    })();
    Message.BlockPresence = (function() {
        function BlockPresence(p) {
            if (p) {
                for(var ks = Object.keys(p), i = 0; i < ks.length; ++i)if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
            }
        }
        BlockPresence.prototype.cid = $util.newBuffer([]);
        BlockPresence.prototype.type = 0;
        BlockPresence.encode = function encode(m, w) {
            if (!w) w = $Writer.create();
            if (m.cid != null && Object.hasOwnProperty.call(m, 'cid')) w.uint32(10).bytes(m.cid);
            if (m.type != null && Object.hasOwnProperty.call(m, 'type')) w.uint32(16).int32(m.type);
            return w;
        };
        BlockPresence.decode = function decode(r, l) {
            if (!(r instanceof $Reader)) r = $Reader.create(r);
            var c = l === undefined ? r.len : r.pos + l, m = new $root.Message.BlockPresence();
            while(r.pos < c){
                var t = r.uint32();
                switch(t >>> 3){
                    case 1:
                        m.cid = r.bytes();
                        break;
                    case 2:
                        m.type = r.int32();
                        break;
                    default:
                        r.skipType(t & 7);
                        break;
                }
            }
            return m;
        };
        BlockPresence.fromObject = function fromObject(d) {
            if (d instanceof $root.Message.BlockPresence) return d;
            var m = new $root.Message.BlockPresence();
            if (d.cid != null) {
                if (typeof d.cid === 'string') $util.base64.decode(d.cid, m.cid = $util.newBuffer($util.base64.length(d.cid)), 0);
                else if (d.cid.length) m.cid = d.cid;
            }
            switch(d.type){
                case 'Have':
                case 0:
                    m.type = 0;
                    break;
                case 'DontHave':
                case 1:
                    m.type = 1;
                    break;
            }
            return m;
        };
        BlockPresence.toObject = function toObject(m, o) {
            if (!o) o = {
            };
            var d = {
            };
            if (o.defaults) {
                if (o.bytes === String) d.cid = '';
                else {
                    d.cid = [];
                    if (o.bytes !== Array) d.cid = $util.newBuffer(d.cid);
                }
                d.type = o.enums === String ? 'Have' : 0;
            }
            if (m.cid != null && m.hasOwnProperty('cid')) d.cid = o.bytes === String ? $util.base64.encode(m.cid, 0, m.cid.length) : o.bytes === Array ? Array.prototype.slice.call(m.cid) : m.cid;
            if (m.type != null && m.hasOwnProperty('type')) d.type = o.enums === String ? $root.Message.BlockPresenceType[m.type] : m.type;
            return d;
        };
        BlockPresence.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf__default["default"].util.toJSONOptions);
        };
        return BlockPresence;
    })();
    return Message;
})();
exports.Message = Message1;
exports["default"] = $root;

},{"protobufjs/minimal.js":"9Jmso"}],"28yrY":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
const SECOND = 1000;
const maxProvidersPerRequest = 3;
const providerRequestTimeout = 10 * SECOND;
const hasBlockTimeout = 15 * SECOND;
const provideTimeout = 15 * SECOND;
const kMaxPriority = Math.pow(2, 31) - 1;
const maxListeners = 1000;
const wantlistSendDebounceMs = 1;
exports.hasBlockTimeout = hasBlockTimeout;
exports.kMaxPriority = kMaxPriority;
exports.maxListeners = maxListeners;
exports.maxProvidersPerRequest = maxProvidersPerRequest;
exports.provideTimeout = provideTimeout;
exports.providerRequestTimeout = providerRequestTimeout;
exports.wantlistSendDebounceMs = wantlistSendDebounceMs;

},{}],"beCn1":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var debounce = require('just-debounce-it');
var index$1 = require('../message/index.js');
var index = require('../utils/index.js');
var constants = require('../constants.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var debounce__default = /*#__PURE__*/ _interopDefaultLegacy(debounce);
class MsgQueue {
    constructor(selfPeerId, otherPeerId, network){
        this.peerId = otherPeerId;
        this.network = network;
        this.refcnt = 1;
        this._entries = [];
        this._log = index.logger(selfPeerId, 'msgqueue');
        this.sendEntries = debounce__default["default"](this._sendEntries.bind(this), constants.wantlistSendDebounceMs);
    }
    addMessage(msg) {
        if (msg.empty) return;
        this.send(msg);
    }
    addEntries(entries) {
        this._entries = this._entries.concat(entries);
        this.sendEntries();
    }
    _sendEntries() {
        if (!this._entries.length) return;
        const msg = new index$1.BitswapMessage(false);
        this._entries.forEach((entry)=>{
            if (entry.cancel) msg.cancel(entry.cid);
            else msg.addEntry(entry.cid, entry.priority);
        });
        this._entries = [];
        this.addMessage(msg);
    }
    async send(msg1) {
        try {
            await this.network.connectTo(this.peerId);
        } catch (err1) {
            this._log.error('cant connect to peer %s: %s', this.peerId.toB58String(), err1.message);
            return;
        }
        this._log('sending message to peer %s', this.peerId.toB58String());
        this.network.sendMessage(this.peerId, msg1).catch((err)=>{
            this._log.error('send error: %s', err.message);
        });
    }
}
exports.MsgQueue = MsgQueue;

},{"just-debounce-it":"jGzpD","../message/index.js":"3FcDb","../utils/index.js":"6RuEm","../constants.js":"28yrY"}],"jGzpD":[function(require,module,exports) {
module.exports = debounce;
function debounce(fn, wait, callFirst) {
    var timeout = null;
    var debouncedFn = null;
    var clear = function() {
        if (timeout) {
            clearTimeout(timeout);
            debouncedFn = null;
            timeout = null;
        }
    };
    var flush = function() {
        var call = debouncedFn;
        clear();
        if (call) call();
    };
    var debounceWrapper = function() {
        if (!wait) return fn.apply(this, arguments);
        var context = this;
        var args = arguments;
        var callNow = callFirst && !timeout;
        clear();
        debouncedFn = function() {
            fn.apply(context, args);
        };
        timeout = setTimeout(function() {
            timeout = null;
            if (!callNow) {
                var call = debouncedFn;
                debouncedFn = null;
                return call();
            }
        }, wait);
        if (callNow) return debouncedFn();
    };
    debounceWrapper.cancel = clear;
    debounceWrapper.flush = flush;
    return debounceWrapper;
}

},{}],"eAxqn":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var lp = require('it-length-prefixed');
var itPipe = require('it-pipe');
var MulticodecTopology = require('libp2p-interfaces/src/topology/multicodec-topology.js');
var index$1 = require('./message/index.js');
var constants = require('./constants.js');
var index = require('./utils/index.js');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var lp__default = /*#__PURE__*/ _interopDefaultLegacy(lp);
var MulticodecTopology__default = /*#__PURE__*/ _interopDefaultLegacy(MulticodecTopology);
const BITSWAP100 = '/ipfs/bitswap/1.0.0';
const BITSWAP110 = '/ipfs/bitswap/1.1.0';
const BITSWAP120 = '/ipfs/bitswap/1.2.0';
class Network {
    constructor(libp2p, bitswap, stats, options = {
    }){
        this._log = index.logger(libp2p.peerId, 'network');
        this._libp2p = libp2p;
        this._bitswap = bitswap;
        this._protocols = [
            BITSWAP100
        ];
        if (!options.b100Only) {
            this._protocols.unshift(BITSWAP110);
            this._protocols.unshift(BITSWAP120);
        }
        this._stats = stats;
        this._running = false;
        this._onPeerConnect = this._onPeerConnect.bind(this);
        this._onPeerDisconnect = this._onPeerDisconnect.bind(this);
        this._onConnection = this._onConnection.bind(this);
        this._hashLoader = options.hashLoader;
    }
    start() {
        this._running = true;
        this._libp2p.handle(this._protocols, this._onConnection);
        const topology = new MulticodecTopology__default["default"]({
            multicodecs: this._protocols,
            handlers: {
                onConnect: this._onPeerConnect,
                onDisconnect: this._onPeerDisconnect
            }
        });
        this._registrarId = this._libp2p.registrar.register(topology);
        for (const peer of this._libp2p.peerStore.peers.values()){
            const conn = this._libp2p.connectionManager.get(peer.id);
            conn && this._onPeerConnect(conn.remotePeer);
        }
    }
    stop() {
        this._running = false;
        this._libp2p.unhandle(this._protocols);
        if (this._registrarId != null) this._libp2p.registrar.unregister(this._registrarId);
    }
    async _onConnection({ protocol , stream: stream1 , connection  }) {
        if (!this._running) return;
        this._log('incoming new bitswap %s connection from %s', protocol, connection.remotePeer.toB58String());
        try {
            await itPipe.pipe(stream1, lp__default["default"].decode(), async (source)=>{
                for await (const data of source)try {
                    const message = await index$1.BitswapMessage.deserialize(data.slice(), this._hashLoader);
                    await this._bitswap._receiveMessage(connection.remotePeer, message);
                } catch (err) {
                    this._bitswap._receiveError(err);
                    break;
                }
            });
        } catch (err) {
            this._log(err);
        }
    }
    _onPeerConnect(peerId) {
        this._bitswap._onPeerConnected(peerId);
    }
    _onPeerDisconnect(peerId1) {
        this._bitswap._onPeerDisconnected(peerId1);
    }
    findProviders(cid, maxProviders, options1 = {
    }) {
        return this._libp2p.contentRouting.findProviders(cid, {
            timeout: constants.providerRequestTimeout,
            maxNumProviders: maxProviders
        });
    }
    async findAndConnect(cid1, options2) {
        const connectAttempts = [];
        for await (const provider of this.findProviders(cid1, constants.maxProvidersPerRequest, options2)){
            this._log(`connecting to provider ${provider.id}`);
            connectAttempts.push(this.connectTo(provider.id, options2).catch((err)=>{
                this._log.error(err);
            }));
        }
        await Promise.all(connectAttempts);
    }
    async provide(cid2, options3) {
        await this._libp2p.contentRouting.provide(cid2, options3);
    }
    async sendMessage(peer, msg1) {
        if (!this._running) throw new Error('network isn\'t running');
        const stringId = peer.toB58String();
        this._log('sendMessage to %s', stringId, msg1);
        const connection = await this._libp2p.dial(peer);
        const { stream , protocol  } = await connection.newStream([
            BITSWAP120,
            BITSWAP110,
            BITSWAP100
        ]);
        let serialized;
        switch(protocol){
            case BITSWAP100:
                serialized = msg1.serializeToBitswap100();
                break;
            case BITSWAP110:
            case BITSWAP120:
                serialized = msg1.serializeToBitswap110();
                break;
            default:
                throw new Error('Unknown protocol: ' + protocol);
        }
        writeMessage(stream, serialized, this._log);
        this._updateSentStats(peer, msg1.blocks);
    }
    async connectTo(peer1, options4) {
        if (!this._running) throw new Error('network isn\'t running');
        return this._libp2p.dial(peer1, options4);
    }
    _updateSentStats(peer2, blocks) {
        const peerId = peer2.toB58String();
        if (this._stats) {
            for (const block of blocks.values())this._stats.push(peerId, 'dataSent', block.length);
            this._stats.push(peerId, 'blocksSent', blocks.size);
        }
    }
}
async function writeMessage(stream, msg, log) {
    try {
        await itPipe.pipe([
            msg
        ], lp__default["default"].encode(), stream);
    } catch (err) {
        log(err);
    }
}
exports.Network = Network;

},{"it-length-prefixed":"2cvC1","it-pipe":"4jukm","libp2p-interfaces/src/topology/multicodec-topology.js":"czyip","./message/index.js":"3FcDb","./constants.js":"28yrY","./utils/index.js":"6RuEm"}],"vTfGd":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var cid1 = require('multiformats/cid');
var base58 = require('multiformats/bases/base58');
var index = require('../message/index.js');
var index$2 = require('../wantlist/index.js');
var ledger = require('./ledger.js');
var reqQueue = require('./req-queue.js');
var taskMerger = require('./task-merger.js');
var index$1 = require('../utils/index.js');
const WantType = index.BitswapMessage.WantType;
const TARGET_MESSAGE_SIZE = 16384;
const MAX_SIZE_REPLACE_HAS_WITH_BLOCK = 1024;
class DecisionEngine {
    constructor(peerId, blockstore, network, stats, opts = {
    }){
        this._log = index$1.logger(peerId, 'engine');
        this.blockstore = blockstore;
        this.network = network;
        this._stats = stats;
        this._opts = this._processOpts(opts);
        this.ledgerMap = new Map();
        this._running = false;
        this._requestQueue = new reqQueue.RequestQueue(taskMerger.TaskMerger);
    }
    _processOpts(opts1) {
        return {
            maxSizeReplaceHasWithBlock: MAX_SIZE_REPLACE_HAS_WITH_BLOCK,
            targetMessageSize: TARGET_MESSAGE_SIZE,
            ...opts1
        };
    }
    _scheduleProcessTasks() {
        setTimeout(()=>{
            this._processTasks();
        });
    }
    async _processTasks() {
        if (!this._running) return;
        const { peerId , tasks , pendingSize  } = this._requestQueue.popTasks(this._opts.targetMessageSize);
        if (tasks.length === 0) return;
        const msg = new index.BitswapMessage(false);
        msg.setPendingBytes(pendingSize);
        const blockCids = [];
        const blockTasks = new Map();
        for (const task of tasks){
            const cid$1 = cid1.CID.parse(task.topic);
            if (task.data.haveBlock) {
                if (task.data.isWantBlock) {
                    blockCids.push(cid$1);
                    blockTasks.set(task.topic, task.data);
                } else msg.addHave(cid$1);
            } else msg.addDontHave(cid$1);
        }
        const blocks = await this._getBlocks(blockCids);
        for (const [topic, taskData] of blockTasks){
            const cid$1 = cid1.CID.parse(topic);
            const blk = blocks.get(topic);
            if (blk) msg.addBlock(cid$1, blk);
            else if (taskData.sendDontHave) msg.addDontHave(cid$1);
        }
        if (msg.empty) {
            peerId && this._requestQueue.tasksDone(peerId, tasks);
            this._scheduleProcessTasks();
            return;
        }
        try {
            peerId && await this.network.sendMessage(peerId, msg);
            for (const [cidStr, block] of blocks.entries())peerId && this.messageSent(peerId, cid1.CID.parse(cidStr), block);
        } catch (err) {
            this._log.error(err);
        }
        peerId && this._requestQueue.tasksDone(peerId, tasks);
        this._scheduleProcessTasks();
    }
    wantlistForPeer(peerId1) {
        const peerIdStr = peerId1.toB58String();
        const ledger = this.ledgerMap.get(peerIdStr);
        return ledger ? ledger.wantlist.sortedEntries() : new Map();
    }
    ledgerForPeer(peerId2) {
        const peerIdStr = peerId2.toB58String();
        const ledger = this.ledgerMap.get(peerIdStr);
        if (!ledger) return null;
        return {
            peer: ledger.partner,
            value: ledger.debtRatio(),
            sent: ledger.accounting.bytesSent,
            recv: ledger.accounting.bytesRecv,
            exchanged: ledger.exchangeCount
        };
    }
    peers() {
        return Array.from(this.ledgerMap.values()).map((l)=>l.partner
        );
    }
    receivedBlocks(blocks) {
        if (!blocks.length) return;
        for (const ledger of this.ledgerMap.values())for (const block of blocks){
            const want = ledger.wantlistContains(block.cid);
            if (!want) continue;
            const blockSize = block.data.length;
            const isWantBlock = this._sendAsBlock(want.wantType, blockSize);
            let entrySize = blockSize;
            if (!isWantBlock) entrySize = index.BitswapMessage.blockPresenceSize(want.cid);
            this._requestQueue.pushTasks(ledger.partner, [
                {
                    topic: want.cid.toString(base58.base58btc),
                    priority: want.priority,
                    size: entrySize,
                    data: {
                        blockSize,
                        isWantBlock,
                        haveBlock: true,
                        sendDontHave: false
                    }
                }
            ]);
        }
        this._scheduleProcessTasks();
    }
    async messageReceived(peerId3, msg) {
        const ledger = this._findOrCreate(peerId3);
        if (msg.empty) return;
        if (msg.full) ledger.wantlist = new index$2.Wantlist();
        this._updateBlockAccounting(msg.blocks, ledger);
        if (msg.wantlist.size === 0) {
            this._scheduleProcessTasks();
            return;
        }
        const cancels = [];
        const wants = [];
        msg.wantlist.forEach((entry)=>{
            if (entry.cancel) {
                ledger.cancelWant(entry.cid);
                cancels.push(entry.cid);
            } else {
                ledger.wants(entry.cid, entry.priority, entry.wantType);
                wants.push(entry);
            }
        });
        this._cancelWants(peerId3, cancels);
        await this._addWants(peerId3, wants);
        this._scheduleProcessTasks();
    }
    _cancelWants(peerId4, cids) {
        for (const c of cids)this._requestQueue.remove(c.toString(base58.base58btc), peerId4);
    }
    async _addWants(peerId5, wants) {
        const blockSizes = await this._getBlockSizes(wants.map((w)=>w.cid
        ));
        const tasks = [];
        for (const want of wants){
            const id = want.cid.toString(base58.base58btc);
            const blockSize = blockSizes.get(id);
            if (blockSize == null) {
                if (want.sendDontHave) tasks.push({
                    topic: id,
                    priority: want.priority,
                    size: index.BitswapMessage.blockPresenceSize(want.cid),
                    data: {
                        isWantBlock: want.wantType === WantType.Block,
                        blockSize: 0,
                        haveBlock: false,
                        sendDontHave: want.sendDontHave
                    }
                });
            } else {
                const isWantBlock = this._sendAsBlock(want.wantType, blockSize);
                let entrySize = blockSize;
                if (!isWantBlock) entrySize = index.BitswapMessage.blockPresenceSize(want.cid);
                tasks.push({
                    topic: id,
                    priority: want.priority,
                    size: entrySize,
                    data: {
                        isWantBlock,
                        blockSize,
                        haveBlock: true,
                        sendDontHave: want.sendDontHave
                    }
                });
            }
            this._requestQueue.pushTasks(peerId5, tasks);
        }
    }
    _sendAsBlock(wantType, blockSize) {
        return wantType === WantType.Block || blockSize <= this._opts.maxSizeReplaceHasWithBlock;
    }
    async _getBlockSizes(cids1) {
        const blocks = await this._getBlocks(cids1);
        return new Map([
            ...blocks
        ].map(([k, v])=>[
                k,
                v.length
            ]
        ));
    }
    async _getBlocks(cids2) {
        const res = new Map();
        await Promise.all(cids2.map(async (cid)=>{
            try {
                const block = await this.blockstore.get(cid);
                res.set(cid.toString(base58.base58btc), block);
            } catch (e) {
                if (e.code !== 'ERR_NOT_FOUND') this._log.error('failed to query blockstore for %s: %s', cid, e);
            }
        }));
        return res;
    }
    _updateBlockAccounting(blocksMap, ledger1) {
        for (const block of blocksMap.values()){
            this._log('got block (%s bytes)', block.length);
            ledger1.receivedBytes(block.length);
        }
    }
    messageSent(peerId6, cid, block) {
        const ledger = this._findOrCreate(peerId6);
        ledger.sentBytes(block.length);
        ledger.wantlist.remove(cid);
    }
    numBytesSentTo(peerId7) {
        return this._findOrCreate(peerId7).accounting.bytesSent;
    }
    numBytesReceivedFrom(peerId8) {
        return this._findOrCreate(peerId8).accounting.bytesRecv;
    }
    peerDisconnected(_peerId) {
    }
    _findOrCreate(peerId9) {
        const peerIdStr = peerId9.toB58String();
        const ledger$1 = this.ledgerMap.get(peerIdStr);
        if (ledger$1) return ledger$1;
        const l = new ledger.Ledger(peerId9);
        this.ledgerMap.set(peerIdStr, l);
        if (this._stats) this._stats.push(peerIdStr, 'peerCount', 1);
        return l;
    }
    start() {
        this._running = true;
    }
    stop() {
        this._running = false;
    }
}
exports.DecisionEngine = DecisionEngine;

},{"multiformats/cid":"fJJnW","multiformats/bases/base58":"6Rnqi","../message/index.js":"3FcDb","../wantlist/index.js":"izq7D","./ledger.js":"a6G6P","./req-queue.js":"4i0hq","./task-merger.js":"1oRUJ","../utils/index.js":"6RuEm"}],"a6G6P":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var index = require('../wantlist/index.js');
class Ledger {
    constructor(peerId){
        this.partner = peerId;
        this.wantlist = new index.Wantlist();
        this.exchangeCount = 0;
        this.sentToPeer = new Map();
        this.accounting = {
            bytesSent: 0,
            bytesRecv: 0
        };
    }
    sentBytes(n) {
        this.exchangeCount++;
        this.lastExchange = new Date().getTime();
        this.accounting.bytesSent += n;
    }
    receivedBytes(n1) {
        this.exchangeCount++;
        this.lastExchange = new Date().getTime();
        this.accounting.bytesRecv += n1;
    }
    wants(cid, priority, wantType) {
        this.wantlist.add(cid, priority, wantType);
    }
    cancelWant(cid1) {
        this.wantlist.remove(cid1);
    }
    wantlistContains(cid2) {
        return this.wantlist.get(cid2);
    }
    debtRatio() {
        return this.accounting.bytesSent / (this.accounting.bytesRecv + 1);
    }
}
exports.Ledger = Ledger;

},{"../wantlist/index.js":"izq7D"}],"4i0hq":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var sortedMap = require('../utils/sorted-map.js');
const DefaultTaskMerger = {
    hasNewInfo () {
        return false;
    },
    merge () {
    }
};
class RequestQueue {
    constructor(taskMerger = DefaultTaskMerger){
        this._taskMerger = taskMerger;
        this._byPeer = new sortedMap.SortedMap([], PeerTasks.compare);
    }
    pushTasks(peerId, tasks) {
        let peerTasks = this._byPeer.get(peerId.toB58String());
        if (!peerTasks) peerTasks = new PeerTasks(peerId, this._taskMerger);
        peerTasks.pushTasks(tasks);
        this._byPeer.set(peerId.toB58String(), peerTasks);
    }
    popTasks(targetMinBytes) {
        const peerTasks = this._head();
        if (peerTasks === undefined) return {
            tasks: [],
            pendingSize: 0
        };
        const { tasks , pendingSize  } = peerTasks.popTasks(targetMinBytes);
        if (tasks.length === 0) return {
            tasks,
            pendingSize
        };
        const peerId = peerTasks.peerId;
        if (peerTasks.isIdle()) this._byPeer.delete(peerId.toB58String());
        else this._byPeer.update(0);
        return {
            peerId,
            tasks,
            pendingSize
        };
    }
    _head() {
        if (this._byPeer.size === 0) return undefined;
        for (const [, v] of this._byPeer)return v;
        return undefined;
    }
    remove(topic, peerId1) {
        const peerTasks = this._byPeer.get(peerId1.toB58String());
        peerTasks && peerTasks.remove(topic);
    }
    tasksDone(peerId2, tasks1) {
        const peerTasks = this._byPeer.get(peerId2.toB58String());
        if (!peerTasks) return;
        const i = this._byPeer.indexOf(peerId2.toB58String());
        for (const task of tasks1)peerTasks.taskDone(task);
        this._byPeer.update(i);
    }
}
class PeerTasks {
    constructor(peerId3, taskMerger1){
        this.peerId = peerId3;
        this._taskMerger = taskMerger1;
        this._activeTotalSize = 0;
        this._pending = new PendingTasks();
        this._active = new Set();
    }
    pushTasks(tasks2) {
        for (const t of tasks2)this._pushTask(t);
    }
    _pushTask(task) {
        if (!this._taskHasMoreInfoThanActiveTasks(task)) return;
        const existingTask = this._pending.get(task.topic);
        if (existingTask) {
            if (task.priority > existingTask.priority) this._pending.updatePriority(task.topic, task.priority);
            this._taskMerger.merge(task, existingTask);
            return;
        }
        this._pending.add(task);
    }
    _taskHasMoreInfoThanActiveTasks(task1) {
        const tasksWithTopic = [];
        for (const activeTask of this._active)if (activeTask.topic === task1.topic) tasksWithTopic.push(activeTask);
        if (tasksWithTopic.length === 0) return true;
        return this._taskMerger.hasNewInfo(task1, tasksWithTopic);
    }
    popTasks(targetMinBytes1) {
        let size = 0;
        const tasks = [];
        const pendingTasks = this._pending.tasks();
        for(let i = 0; i < pendingTasks.length && size < targetMinBytes1; i++){
            const task = pendingTasks[i];
            tasks.push(task);
            size += task.size;
            this._pending.delete(task.topic);
            this._activeTotalSize += task.size;
            this._active.add(task);
        }
        return {
            tasks,
            pendingSize: this._pending.totalSize
        };
    }
    taskDone(task2) {
        if (this._active.has(task2)) {
            this._activeTotalSize -= task2.size;
            this._active.delete(task2);
        }
    }
    remove(topic1) {
        this._pending.delete(topic1);
    }
    isIdle() {
        return this._pending.length === 0 && this._active.size === 0;
    }
    static compare(a1, b) {
        if (a1[1]._pending.length === 0) return 1;
        if (b[1]._pending.length === 0) return -1;
        if (a1[1]._activeTotalSize === b[1]._activeTotalSize) return b[1]._pending.length - a1[1]._pending.length;
        return a1[1]._activeTotalSize - b[1]._activeTotalSize;
    }
}
class PendingTasks {
    constructor(){
        this._tasks = new sortedMap.SortedMap([], this._compare);
    }
    get length() {
        return this._tasks.size;
    }
    get totalSize() {
        return [
            ...this._tasks.values()
        ].reduce((a, t)=>a + t.task.size
        , 0);
    }
    get(topic2) {
        return (this._tasks.get(topic2) || {
        }).task;
    }
    add(task3) {
        this._tasks.set(task3.topic, {
            created: Date.now(),
            task: task3
        });
    }
    delete(topic3) {
        this._tasks.delete(topic3);
    }
    tasks() {
        return [
            ...this._tasks.values()
        ].map((i)=>i.task
        );
    }
    updatePriority(topic4, priority) {
        const obj = this._tasks.get(topic4);
        if (!obj) return;
        const i = this._tasks.indexOf(topic4);
        obj.task.priority = priority;
        this._tasks.update(i);
    }
    _compare(a, b1) {
        if (a[1].task.priority === b1[1].task.priority) return a[1].created - b1[1].created;
        return b1[1].task.priority - a[1].task.priority;
    }
}
exports.RequestQueue = RequestQueue;

},{"../utils/sorted-map.js":"3rMeW"}],"3rMeW":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
class SortedMap extends Map {
    constructor(entries, cmp){
        super();
        this._cmp = cmp || this._defaultSort;
        this._keys = [];
        for (const [k, v] of entries || [])this.set(k, v);
    }
    update(i) {
        if (i < 0 || i >= this._keys.length) return;
        const k = this._keys[i];
        this._keys.splice(i, 1);
        const newIdx = this._find(k);
        this._keys.splice(newIdx, 0, k);
    }
    set(k, v) {
        if (this.has(k)) {
            const i = this.indexOf(k);
            this._keys.splice(i, 1);
        }
        super.set(k, v);
        const i = this._find(k);
        this._keys.splice(i, 0, k);
        return this;
    }
    clear() {
        super.clear();
        this._keys = [];
    }
    delete(k1) {
        if (!this.has(k1)) return false;
        const i = this.indexOf(k1);
        this._keys.splice(i, 1);
        return super.delete(k1);
    }
    indexOf(k2) {
        if (!this.has(k2)) return -1;
        const i = this._find(k2);
        if (this._keys[i] === k2) return i;
        for(let j = 1; j < this._keys.length; j++){
            if (this._keys[i + j] === k2) return i + j;
            if (this._keys[i - j] === k2) return i - j;
        }
        return -1;
    }
    _find(k3) {
        let lower = 0;
        let upper = this._keys.length;
        while(lower < upper){
            const pivot = lower + upper >>> 1;
            const cmp = this._kCmp(this._keys[pivot], k3);
            if (cmp < 0) lower = pivot + 1;
            else if (cmp > 0) upper = pivot;
            else return pivot;
        }
        return lower;
    }
    *keys() {
        for (const k of this._keys)yield k;
        return undefined;
    }
    *values() {
        for (const k of this._keys)yield this.get(k);
        return undefined;
    }
    *entries() {
        for (const k of this._keys)yield [
            k,
            this.get(k)
        ];
        return undefined;
    }
    *[Symbol.iterator]() {
        yield* this.entries();
    }
    forEach(cb, thisArg) {
        if (!cb) return;
        for (const k of this._keys)cb.apply(thisArg, [
            [
                k,
                this.get(k)
            ]
        ]);
    }
    _defaultSort(a, b) {
        if (a[0] < b[0]) return -1;
        if (b[0] < a[0]) return 1;
        return 0;
    }
    _kCmp(a1, b1) {
        return this._cmp([
            a1,
            this.get(a1)
        ], [
            b1,
            this.get(b1)
        ]);
    }
}
exports.SortedMap = SortedMap;

},{}],"1oRUJ":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
const TaskMerger = {
    hasNewInfo (task, tasksWithTopic) {
        let haveBlock = false;
        let isWantBlock = false;
        for (const existing of tasksWithTopic){
            if (existing.data.haveBlock) haveBlock = true;
            if (existing.data.isWantBlock) isWantBlock = true;
        }
        if (!isWantBlock && task.data.isWantBlock) return true;
        if (!haveBlock && task.data.haveBlock) return true;
        return false;
    },
    merge (newTask, existingTask) {
        const taskData = newTask.data;
        const existingData = existingTask.data;
        if (!existingData.haveBlock && taskData.haveBlock) {
            existingData.haveBlock = taskData.haveBlock;
            existingData.blockSize = taskData.blockSize;
        }
        if (!existingData.isWantBlock && taskData.isWantBlock) {
            existingData.isWantBlock = true;
            if (!existingData.haveBlock || taskData.haveBlock) {
                existingData.haveBlock = taskData.haveBlock;
                existingTask.size = newTask.size;
            }
        }
        if (existingData.isWantBlock && existingData.haveBlock) existingTask.size = existingData.blockSize;
    }
};
exports.TaskMerger = TaskMerger;

},{}],"gDWR1":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var events = require('events');
var toString = require('uint8arrays/to-string');
var constants = require('./constants.js');
var index = require('./utils/index.js');
const unwantEvent = (cid)=>`unwant:${toString.toString(cid.multihash.bytes, 'base64')}`
;
const blockEvent = (cid)=>`block:${toString.toString(cid.multihash.bytes, 'base64')}`
;
class Notifications extends events.EventEmitter {
    constructor(peerId){
        super();
        this.setMaxListeners(constants.maxListeners);
        this._log = index.logger(peerId, 'notif');
    }
    hasBlock(cid, block) {
        const event = blockEvent(cid);
        this._log(event);
        this.emit(event, block);
    }
    wantBlock(cid1, options = {
    }) {
        if (!cid1) throw new Error('Not a valid cid');
        const blockEvt = blockEvent(cid1);
        const unwantEvt = unwantEvent(cid1);
        this._log(`wantBlock:${cid1}`);
        return new Promise((resolve, reject)=>{
            const onUnwant = ()=>{
                this.removeListener(blockEvt, onBlock);
                reject(new Error(`Block for ${cid1} unwanted`));
            };
            const onBlock = (data)=>{
                this.removeListener(unwantEvt, onUnwant);
                resolve(data);
            };
            this.once(unwantEvt, onUnwant);
            this.once(blockEvt, onBlock);
            if (options && options.signal) options.signal.addEventListener('abort', ()=>{
                this.removeListener(blockEvt, onBlock);
                this.removeListener(unwantEvt, onUnwant);
                reject(new Error(`Want for ${cid1} aborted`));
            });
        });
    }
    unwantBlock(cid2) {
        const event = unwantEvent(cid2);
        this._log(event);
        this.emit(event);
    }
}
exports.Notifications = Notifications;

},{"events":"bHM3D","uint8arrays/to-string":"g3mCQ","./constants.js":"28yrY","./utils/index.js":"6RuEm"}],"enTlZ":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var events = require('events');
var stat = require('./stat.js');
const defaultOptions = {
    enabled: false,
    computeThrottleTimeout: 1000,
    computeThrottleMaxQueueSize: 1000,
    movingAverageIntervals: [
        60000,
        300000,
        900000
    ]
};
class Stats extends events.EventEmitter {
    constructor(initialCounters = [], _options = defaultOptions){
        super();
        const options = Object.assign({
        }, defaultOptions, _options);
        if (typeof options.computeThrottleTimeout !== 'number') throw new Error('need computeThrottleTimeout');
        if (typeof options.computeThrottleMaxQueueSize !== 'number') throw new Error('need computeThrottleMaxQueueSize');
        this._initialCounters = initialCounters;
        this._options = options;
        this._enabled = this._options.enabled;
        this._global = new stat.Stat(initialCounters, options);
        this._global.on('update', (stats)=>this.emit('update', stats)
        );
        this._peers = new Map();
    }
    enable() {
        this._enabled = true;
        this._options.enabled = true;
        this._global.enable();
    }
    disable() {
        this._enabled = false;
        this._options.enabled = false;
        this._global.disable();
    }
    stop() {
        this._enabled = false;
        this._global.stop();
        for (const peerStat of this._peers)peerStat[1].stop();
    }
    get snapshot() {
        return this._global.snapshot;
    }
    get movingAverages() {
        return this._global.movingAverages;
    }
    forPeer(peerId) {
        const peerIdStr = typeof peerId !== 'string' && peerId.toB58String ? peerId.toB58String() : `${peerId}`;
        return this._peers.get(peerIdStr);
    }
    push(peer, counter, inc) {
        if (this._enabled) {
            this._global.push(counter, inc);
            if (peer) {
                let peerStats = this._peers.get(peer);
                if (!peerStats) {
                    peerStats = new stat.Stat(this._initialCounters, this._options);
                    this._peers.set(peer, peerStats);
                }
                peerStats.push(counter, inc);
            }
        }
    }
    disconnected(peer1) {
        const peerId = peer1.toB58String();
        const peerStats = this._peers.get(peerId);
        if (peerStats) {
            peerStats.stop();
            this._peers.delete(peerId);
        }
    }
}
exports.Stats = Stats;

},{"events":"bHM3D","./stat.js":"kR8Li"}],"kR8Li":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var events = require('events');
var MovingAverage = require('@vascosantos/moving-average');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var MovingAverage__default = /*#__PURE__*/ _interopDefaultLegacy(MovingAverage);
class Stat extends events.EventEmitter {
    constructor(initialCounters, options){
        super();
        this._options = options;
        this._queue = [];
        this._stats = {
        };
        this._frequencyLastTime = Date.now();
        this._frequencyAccumulators = {
        };
        this._movingAverages = {
        };
        this._update = this._update.bind(this);
        initialCounters.forEach((key)=>{
            this._stats[key] = BigInt(0);
            this._movingAverages[key] = {
            };
            this._options.movingAverageIntervals.forEach((interval)=>{
                const ma = this._movingAverages[key][interval] = MovingAverage__default["default"](interval);
                ma.push(this._frequencyLastTime, 0);
            });
        });
        this._enabled = this._options.enabled;
    }
    enable() {
        this._enabled = true;
    }
    disable() {
        this._disabled = true;
    }
    stop() {
        if (this._timeout) clearTimeout(this._timeout);
    }
    get snapshot() {
        return Object.assign({
        }, this._stats);
    }
    get movingAverages() {
        return Object.assign({
        }, this._movingAverages);
    }
    push(counter, inc) {
        if (this._enabled) {
            this._queue.push([
                counter,
                inc,
                Date.now()
            ]);
            this._resetComputeTimeout();
        }
    }
    _resetComputeTimeout() {
        if (this._timeout) clearTimeout(this._timeout);
        this._timeout = setTimeout(this._update, this._nextTimeout());
    }
    _nextTimeout() {
        const urgency = this._queue.length / this._options.computeThrottleMaxQueueSize;
        return Math.max(this._options.computeThrottleTimeout * (1 - urgency), 0);
    }
    _update() {
        this._timeout = null;
        if (this._queue.length) {
            let last;
            while(this._queue.length){
                const op = last = this._queue.shift();
                op && this._applyOp(op);
            }
            last && this._updateFrequency(last[2]);
            this.emit('update', this._stats);
        }
    }
    _updateFrequency(latestTime) {
        const timeDiff = latestTime - this._frequencyLastTime;
        if (timeDiff) Object.keys(this._stats).forEach((key)=>{
            this._updateFrequencyFor(key, timeDiff, latestTime);
        });
        this._frequencyLastTime = latestTime;
    }
    _updateFrequencyFor(key, timeDiffMS, latestTime1) {
        const count = this._frequencyAccumulators[key] || 0;
        this._frequencyAccumulators[key] = 0;
        const hz = count / timeDiffMS * 1000;
        let movingAverages = this._movingAverages[key];
        if (!movingAverages) movingAverages = this._movingAverages[key] = {
        };
        this._options.movingAverageIntervals.forEach((movingAverageInterval)=>{
            let movingAverage = movingAverages[movingAverageInterval];
            if (!movingAverage) movingAverage = movingAverages[movingAverageInterval] = MovingAverage__default["default"](movingAverageInterval);
            movingAverage.push(latestTime1, hz);
        });
    }
    _applyOp(op) {
        const key = op[0];
        const inc = op[1];
        if (typeof inc !== 'number') throw new Error(`invalid increment number: ${inc}`);
        if (!Object.prototype.hasOwnProperty.call(this._stats, key)) this._stats[key] = BigInt(0);
        this._stats[key] = BigInt(this._stats[key]) + BigInt(inc);
        if (!this._frequencyAccumulators[key]) this._frequencyAccumulators[key] = 0;
        this._frequencyAccumulators[key] += inc;
    }
}
exports.Stat = Stat;

},{"events":"bHM3D","@vascosantos/moving-average":"fQFY3"}],"f7bgG":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var blockstoreCore = require('blockstore-core');
var merge = require('it-merge');
var pushable = require('it-pushable');
var filter = require('it-filter');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var merge__default = /*#__PURE__*/ _interopDefaultLegacy(merge);
var pushable__default = /*#__PURE__*/ _interopDefaultLegacy(pushable);
var filter__default = /*#__PURE__*/ _interopDefaultLegacy(filter);
class BlockStorage extends blockstoreCore.BaseBlockstore {
    constructor(blockstore, bitswap){
        super();
        this.child = blockstore;
        this.bitswap = bitswap;
    }
    open() {
        return this.child.open();
    }
    close() {
        return this.child.close();
    }
    unwrap() {
        return this.child;
    }
    async put(cid2, block, options = {
    }) {
        if (await this.has(cid2)) return;
        if (this.bitswap.isStarted()) await this.bitswap.put(cid2, block, options);
        else await this.child.put(cid2, block, options);
    }
    async *putMany(blocks, options1 = {
    }) {
        const missingBlocks = filter__default['default'](blocks, async ({ key  })=>{
            return !await this.has(key);
        });
        if (this.bitswap.isStarted()) yield* this.bitswap.putMany(missingBlocks, options1);
        else yield* this.child.putMany(missingBlocks, options1);
    }
    async get(cid1, options2 = {
    }) {
        if (!await this.has(cid1) && this.bitswap.isStarted()) return this.bitswap.get(cid1, options2);
        else return this.child.get(cid1, options2);
    }
    async *getMany(cids, options3 = {
    }) {
        const getFromBitswap = pushable__default['default']();
        const getFromChild = pushable__default['default']();
        Promise.resolve().then(async ()=>{
            for await (const cid of cids)if (!await this.has(cid) && this.bitswap.isStarted()) getFromBitswap.push(cid);
            else getFromChild.push(cid);
            getFromBitswap.end();
            getFromChild.end();
        });
        yield* merge__default['default'](this.bitswap.getMany(getFromBitswap, options3), this.child.getMany(getFromChild, options3));
    }
    async delete(cid, options4) {
        await this.child.delete(cid, options4);
    }
    async *deleteMany(cids1, options5) {
        yield* this.child.deleteMany(cids1, options5);
    }
    async has(cid3, options6 = {
    }) {
        return this.child.has(cid3, options6);
    }
    async *query(q, options7 = {
    }) {
        yield* this.child.query(q, options7);
    }
    async *queryKeys(q1, options8 = {
    }) {
        yield* this.child.queryKeys(q1, options8);
    }
}
exports.BlockStorage = BlockStorage;

},{"blockstore-core":"fxhty","it-merge":"7iKAo","it-pushable":"hRi4l","it-filter":"7NtwB"}],"fxhty":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var errors = require('./errors.js');
var base = require('./base.js');
var memory = require('./memory.js');
const Errors = {
    ...errors
};
exports.BaseBlockstore = base.BaseBlockstore;
exports.MemoryBlockstore = memory.MemoryBlockstore;
exports.Errors = Errors;

},{"./errors.js":"3vkg9","./base.js":"ajjJw","./memory.js":"48vMp"}],"3vkg9":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var errCode = require('err-code');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
function notFoundError(err) {
    err = err || new Error('Not Found');
    return errCode__default['default'](err, 'ERR_NOT_FOUND');
}
function abortedError(err) {
    err = err || new Error('Aborted');
    return errCode__default['default'](err, 'ERR_ABORTED');
}
exports.abortedError = abortedError;
exports.notFoundError = notFoundError;

},{"err-code":"eQvyh"}],"48vMp":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var base = require('./base.js');
var base32 = require('multiformats/bases/base32');
var raw = require('multiformats/codecs/raw');
var cid = require('multiformats/cid');
var Digest = require('multiformats/hashes/digest');
var errors = require('./errors.js');
function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) Object.keys(e).forEach(function(k) {
        if (k !== 'default') {
            var d = Object.getOwnPropertyDescriptor(e, k);
            Object.defineProperty(n, k, d.get ? d : {
                enumerable: true,
                get: function() {
                    return e[k];
                }
            });
        }
    });
    n['default'] = e;
    return Object.freeze(n);
}
var raw__namespace = /*#__PURE__*/ _interopNamespace(raw);
var Digest__namespace = /*#__PURE__*/ _interopNamespace(Digest);
class MemoryBlockstore extends base.BaseBlockstore {
    constructor(){
        super();
        this.data = {
        };
    }
    open() {
        return Promise.resolve();
    }
    close() {
        return Promise.resolve();
    }
    async put(key4, val) {
        this.data[base32.base32.encode(key4.multihash.bytes)] = val;
    }
    async get(key1) {
        const exists = await this.has(key1);
        if (!exists) throw errors.notFoundError();
        return this.data[base32.base32.encode(key1.multihash.bytes)];
    }
    async has(key2) {
        return this.data[base32.base32.encode(key2.multihash.bytes)] !== undefined;
    }
    async delete(key3) {
        delete this.data[base32.base32.encode(key3.multihash.bytes)];
    }
    async *_all() {
        yield* Object.entries(this.data).map(([key, value])=>({
                key: cid.CID.createV1(raw__namespace.code, Digest__namespace.decode(base32.base32.decode(key))),
                value
            })
        );
    }
    async *_allKeys() {
        yield* Object.entries(this.data).map(([key])=>cid.CID.createV1(raw__namespace.code, Digest__namespace.decode(base32.base32.decode(key)))
        );
    }
}
exports.MemoryBlockstore = MemoryBlockstore;

},{"./base.js":"ajjJw","multiformats/bases/base32":"63xDB","multiformats/codecs/raw":"dkcyY","multiformats/cid":"fJJnW","multiformats/hashes/digest":"fkA58","./errors.js":"3vkg9"}],"cYhgJ":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var addrs = require('./addrs.js');
var connect = require('./connect.js');
var disconnect = require('./disconnect.js');
var localAddrs = require('./local-addrs.js');
var peers = require('./peers.js');
class SwarmAPI {
    constructor({ network  }){
        this.addrs = addrs.createAddrs({
            network
        });
        this.connect = connect.createConnect({
            network
        });
        this.disconnect = disconnect.createDisconnect({
            network
        });
        this.localAddrs = localAddrs.createLocalAddrs({
            network
        });
        this.peers = peers.createPeers({
            network
        });
    }
}
exports.SwarmAPI = SwarmAPI;

},{"./addrs.js":"axm3p","./connect.js":"4s2TA","./disconnect.js":"7KELl","./local-addrs.js":"lVBMR","./peers.js":"e0qeE"}],"axm3p":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function createAddrs({ network  }) {
    async function addrs(options = {
    }) {
        const peers = [];
        const { libp2p  } = await network.use(options);
        for (const [peerId, peer] of libp2p.peerStore.peers.entries())peers.push({
            id: peerId,
            addrs: peer.addresses.map((mi)=>mi.multiaddr
            )
        });
        return peers;
    }
    return withTimeoutOption.withTimeoutOption(addrs);
}
exports.createAddrs = createAddrs;

},{"ipfs-core-utils/with-timeout-option":"5AiVw"}],"4s2TA":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function createConnect({ network  }) {
    async function connect(addr, options = {
    }) {
        const { libp2p  } = await network.use(options);
        await libp2p.dial(addr, options);
    }
    return withTimeoutOption.withTimeoutOption(connect);
}
exports.createConnect = createConnect;

},{"ipfs-core-utils/with-timeout-option":"5AiVw"}],"7KELl":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function createDisconnect({ network  }) {
    async function disconnect(addr, options = {
    }) {
        const { libp2p  } = await network.use(options);
        await libp2p.hangUp(addr);
    }
    return withTimeoutOption.withTimeoutOption(disconnect);
}
exports.createDisconnect = createDisconnect;

},{"ipfs-core-utils/with-timeout-option":"5AiVw"}],"lVBMR":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function createLocalAddrs({ network  }) {
    async function localAddrs(options = {
    }) {
        const { libp2p  } = await network.use(options);
        return libp2p.multiaddrs;
    }
    return withTimeoutOption.withTimeoutOption(localAddrs);
}
exports.createLocalAddrs = createLocalAddrs;

},{"ipfs-core-utils/with-timeout-option":"5AiVw"}],"e0qeE":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function createPeers({ network  }) {
    async function peers1(options = {
    }) {
        const { libp2p  } = await network.use(options);
        const peers = [];
        for (const [peerId, connections] of libp2p.connections)for (const connection of connections){
            const peer = {
                addr: connection.remoteAddr,
                peer: peerId
            };
            if (options.verbose || options.direction) peer.direction = connection.stat.direction;
            if (options.verbose) {
                peer.muxer = connection.stat.multiplexer;
                peer.latency = 'n/a';
                peer.streams = [];
            }
            peers.push(peer);
        }
        return peers;
    }
    return withTimeoutOption.withTimeoutOption(peers1);
}
exports.createPeers = createPeers;

},{"ipfs-core-utils/with-timeout-option":"5AiVw"}],"fbyky":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var PeerId = require('peer-id');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var PeerId__default = /*#__PURE__*/ _interopDefaultLegacy(PeerId);
const basePacket = {
    success: true,
    time: 0,
    text: ''
};
function createPing({ network  }) {
    async function* ping(peerId, options = {
    }) {
        const { libp2p  } = await network.use();
        options.count = options.count || 10;
        const peer = PeerId__default['default'].createFromB58String(peerId);
        const storedPeer = libp2p.peerStore.get(peer);
        let id = storedPeer && storedPeer.id;
        if (!id) {
            yield {
                ...basePacket,
                text: `Looking up peer ${peerId}`
            };
            const remotePeer = await libp2p.peerRouting.findPeer(peer);
            id = remotePeer && remotePeer.id;
        }
        if (!id) throw new Error('Peer was not found');
        yield {
            ...basePacket,
            text: `PING ${id.toB58String()}`
        };
        let packetCount = 0;
        let totalTime = 0;
        for(let i = 0; i < options.count; i++)try {
            const time = await libp2p.ping(id);
            totalTime += time;
            packetCount++;
            yield {
                ...basePacket,
                time
            };
        } catch (err) {
            yield {
                ...basePacket,
                success: false,
                text: err.toString()
            };
        }
        if (packetCount) {
            const average = totalTime / packetCount;
            yield {
                ...basePacket,
                text: `Average latency: ${average}ms`
            };
        }
    }
    return withTimeoutOption.withTimeoutOption(ping);
}
exports.createPing = createPing;

},{"peer-id":"4VGWt","ipfs-core-utils/with-timeout-option":"5AiVw"}],"1NaIw":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var PeerId = require('peer-id');
var errCode = require('err-code');
var errors = require('../errors.js');
var get1 = require('dlv');
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var PeerId__default = /*#__PURE__*/ _interopDefaultLegacy(PeerId);
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
var get__default = /*#__PURE__*/ _interopDefaultLegacy(get1);
function createDht({ network , repo  }) {
    const { get , put , findProvs , findPeer , provide , query  } = {
        async get (key, options = {
        }) {
            const { libp2p  } = await use(network, options);
            return libp2p._dht.get(key, options);
        },
        async *put (key, value, options) {
            const { libp2p  } = await use(network, options);
            yield* libp2p._dht.put(key, value);
        },
        async *findProvs (cid, options = {
            numProviders: 20
        }) {
            const { libp2p  } = await use(network, options);
            for await (const peer of libp2p._dht.findProviders(cid, {
                maxNumProviders: options.numProviders,
                signal: options.signal
            }))yield {
                id: peer.id.toB58String(),
                addrs: peer.addrs
            };
        },
        async findPeer (peerId, options) {
            const { libp2p  } = await use(network, options);
            const peer = await libp2p._dht.findPeer(PeerId__default['default'].parse(peerId));
            return {
                id: peer.id.toB58String(),
                addrs: peer.multiaddrs
            };
        },
        async *provide (cids, options = {
            recursive: false
        }) {
            const { libp2p  } = await use(network, options);
            const cidArr = Array.isArray(cids) ? cids : [
                cids
            ];
            const hasCids = await Promise.all(cidArr.map((cid)=>repo.blocks.has(cid)
            ));
            const hasAll = hasCids.every((has)=>has
            );
            if (!hasAll) throw errCode__default['default'](new Error('block(s) not found locally, cannot provide'), 'ERR_BLOCK_NOT_FOUND');
            if (options.recursive) throw errCode__default['default'](new Error('not implemented yet'), 'ERR_NOT_IMPLEMENTED_YET');
            for (const cid1 of cidArr)yield libp2p._dht.provide(cid1);
        },
        async *query (peerId, options) {
            const { libp2p  } = await use(network, options);
            for await (const closerPeerId of libp2p._dht.getClosestPeers(PeerId__default['default'].parse(peerId).toBytes()))yield {
                id: closerPeerId.toB58String(),
                addrs: []
            };
        }
    };
    return {
        get: withTimeoutOption.withTimeoutOption(get),
        put: withTimeoutOption.withTimeoutOption(put),
        findProvs: withTimeoutOption.withTimeoutOption(findProvs),
        findPeer: withTimeoutOption.withTimeoutOption(findPeer),
        provide: withTimeoutOption.withTimeoutOption(provide),
        query: withTimeoutOption.withTimeoutOption(query)
    };
}
const use = async (network, options)=>{
    const net = await network.use(options);
    if (get__default['default'](net.libp2p, '_config.dht.enabled', false)) return net;
    else throw new errors.NotEnabledError('dht not enabled');
};
exports.createDht = createDht;

},{"peer-id":"4VGWt","err-code":"eQvyh","../errors.js":"itpk8","dlv":"3eBmB","ipfs-core-utils/with-timeout-option":"5AiVw"}],"4jVcM":[function(require,module,exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
    value: true
});
var withTimeoutOption = require('ipfs-core-utils/with-timeout-option');
var errCode = require('err-code');
var errors = require('../errors.js');
var get = require('dlv');
function _interopDefaultLegacy(e) {
    return e && typeof e === 'object' && 'default' in e ? e : {
        'default': e
    };
}
var errCode__default = /*#__PURE__*/ _interopDefaultLegacy(errCode);
var get__default = /*#__PURE__*/ _interopDefaultLegacy(get);
function createPubsub({ network , config  }) {
    const isEnabled = get__default['default'](config || {
    }, 'Pubsub.Enabled', true);
    async function subscribe(topic, handler, options = {
    }) {
        const { libp2p  } = await network.use(options);
        return libp2p.pubsub.subscribe(topic, handler, options);
    }
    async function unsubscribe(topic, handler, options = {
    }) {
        const { libp2p  } = await network.use(options);
        libp2p.pubsub.unsubscribe(topic, handler, options);
    }
    async function publish(topic, data, options = {
    }) {
        const { libp2p  } = await network.use(options);
        if (!data) {
            throw errCode__default['default'](new Error('argument "data" is required'), 'ERR_ARG_REQUIRED');
        }
        await libp2p.pubsub.publish(topic, data);
    }
    async function ls(options = {
    }) {
        const { libp2p  } = await network.use(options);
        return libp2p.pubsub.getTopics();
    }
    async function peers(topic, options = {
    }) {
        const { libp2p  } = await network.use(options);
        return libp2p.pubsub.getSubscribers(topic);
    }
    return {
        subscribe: isEnabled ? withTimeoutOption.withTimeoutOption(subscribe) : notEnabled,
        unsubscribe: isEnabled ? withTimeoutOption.withTimeoutOption(unsubscribe) : notEnabled,
        publish: isEnabled ? withTimeoutOption.withTimeoutOption(publish) : notEnabled,
        ls: isEnabled ? withTimeoutOption.withTimeoutOption(ls) : notEnabled,
        peers: isEnabled ? withTimeoutOption.withTimeoutOption(peers) : notEnabled
    };
}
const notEnabled = async ()=>{
    throw new errors.NotEnabledError('pubsub not enabled');
};
exports.createPubsub = createPubsub;

},{"ipfs-core-utils/with-timeout-option":"5AiVw","err-code":"eQvyh","../errors.js":"itpk8","dlv":"3eBmB"}],"lpMGM":[function(require,module,exports) {
typeof window !== "undefined" && (function webpackUniversalModuleDefinition(root, factory) {
    if (typeof exports === 'object' && typeof module === 'object') module.exports = factory();
    else if (typeof define === 'function' && define.amd) define([], factory);
    else if (typeof exports === 'object') exports["Hls"] = factory();
    else root["Hls"] = factory();
})(this, function() {
    return(/******/ (function(modules) {
        /******/ // The module cache
        /******/ var installedModules = {
        };
        /******/ /******/ // The require function
        /******/ function __webpack_require__(moduleId) {
            /******/ /******/ // Check if module is in cache
            /******/ if (installedModules[moduleId]) /******/ return installedModules[moduleId].exports;
            /******/ // Create a new module (and put it into the cache)
            /******/ var module = installedModules[moduleId] = {
                /******/ i: moduleId,
                /******/ l: false,
                /******/ exports: {
                }
            };
            /******/ /******/ // Execute the module function
            /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
            /******/ /******/ // Flag the module as loaded
            /******/ module.l = true;
            /******/ /******/ // Return the exports of the module
            /******/ return module.exports;
        /******/ }
        /******/ /******/ /******/ // expose the modules object (__webpack_modules__)
        /******/ __webpack_require__.m = modules;
        /******/ /******/ // expose the module cache
        /******/ __webpack_require__.c = installedModules;
        /******/ /******/ // define getter function for harmony exports
        /******/ __webpack_require__.d = function(exports, name, getter) {
            /******/ if (!__webpack_require__.o(exports, name)) /******/ Object.defineProperty(exports, name, {
                enumerable: true,
                get: getter
            });
        /******/ };
        /******/ /******/ // define __esModule on exports
        /******/ __webpack_require__.r = function(exports) {
            /******/ if (typeof Symbol !== 'undefined' && Symbol.toStringTag) /******/ Object.defineProperty(exports, Symbol.toStringTag, {
                value: 'Module'
            });
            /******/ Object.defineProperty(exports, '__esModule', {
                value: true
            });
        /******/ };
        /******/ /******/ // create a fake namespace object
        /******/ // mode & 1: value is a module id, require it
        /******/ // mode & 2: merge all properties of value into the ns
        /******/ // mode & 4: return value when already ns object
        /******/ // mode & 8|1: behave like require
        /******/ __webpack_require__.t = function(value, mode) {
            /******/ if (mode & 1) value = __webpack_require__(value);
            /******/ if (mode & 8) return value;
            /******/ if (mode & 4 && typeof value === 'object' && value && value.__esModule) return value;
            /******/ var ns = Object.create(null);
            /******/ __webpack_require__.r(ns);
            /******/ Object.defineProperty(ns, 'default', {
                enumerable: true,
                value: value
            });
            /******/ if (mode & 2 && typeof value != 'string') for(var key in value)__webpack_require__.d(ns, key, (function(key) {
                return value[key];
            }).bind(null, key));
            /******/ return ns;
        /******/ };
        /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules
        /******/ __webpack_require__.n = function(module) {
            /******/ var getter = module && module.__esModule ? /******/ function getDefault() {
                return module['default'];
            } : /******/ function getModuleExports() {
                return module;
            };
            /******/ __webpack_require__.d(getter, 'a', getter);
            /******/ return getter;
        /******/ };
        /******/ /******/ // Object.prototype.hasOwnProperty.call
        /******/ __webpack_require__.o = function(object, property) {
            return Object.prototype.hasOwnProperty.call(object, property);
        };
        /******/ /******/ // __webpack_public_path__
        /******/ __webpack_require__.p = "/dist/";
        /******/ /******/ /******/ // Load entry module and return exports
        /******/ return __webpack_require__(__webpack_require__.s = "./src/hls.ts");
    /******/ })({
        /***/ "./node_modules/eventemitter3/index.js": function(module, exports, __webpack_require__) {
            "use strict";
            var has = Object.prototype.hasOwnProperty, prefix = '~';
            /**
 * Constructor to create a storage for our `EE` objects.
 * An `Events` instance is a plain object whose properties are event names.
 *
 * @constructor
 * @private
 */ function Events() {
            }
            //
            // We try to not inherit from `Object.prototype`. In some engines creating an
            // instance in this way is faster than calling `Object.create(null)` directly.
            // If `Object.create(null)` is not supported we prefix the event names with a
            // character to make sure that the built-in object properties are not
            // overridden or used as an attack vector.
            //
            if (Object.create) {
                Events.prototype = Object.create(null);
                //
                // This hack is needed because the `__proto__` property is still inherited in
                // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.
                //
                if (!new Events().__proto__) prefix = false;
            }
            /**
 * Representation of a single event listener.
 *
 * @param {Function} fn The listener function.
 * @param {*} context The context to invoke the listener with.
 * @param {Boolean} [once=false] Specify if the listener is a one-time listener.
 * @constructor
 * @private
 */ function EE(fn, context, once) {
                this.fn = fn;
                this.context = context;
                this.once = once || false;
            }
            /**
 * Add a listener for a given event.
 *
 * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
 * @param {(String|Symbol)} event The event name.
 * @param {Function} fn The listener function.
 * @param {*} context The context to invoke the listener with.
 * @param {Boolean} once Specify if the listener is a one-time listener.
 * @returns {EventEmitter}
 * @private
 */ function addListener(emitter, event, fn, context, once) {
                if (typeof fn !== 'function') throw new TypeError('The listener must be a function');
                var listener = new EE(fn, context || emitter, once), evt = prefix ? prefix + event : event;
                if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;
                else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);
                else emitter._events[evt] = [
                    emitter._events[evt],
                    listener
                ];
                return emitter;
            }
            /**
 * Clear event by name.
 *
 * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
 * @param {(String|Symbol)} evt The Event name.
 * @private
 */ function clearEvent(emitter, evt) {
                if (--emitter._eventsCount === 0) emitter._events = new Events();
                else delete emitter._events[evt];
            }
            /**
 * Minimal `EventEmitter` interface that is molded against the Node.js
 * `EventEmitter` interface.
 *
 * @constructor
 * @public
 */ function EventEmitter() {
                this._events = new Events();
                this._eventsCount = 0;
            }
            /**
 * Return an array listing the events for which the emitter has registered
 * listeners.
 *
 * @returns {Array}
 * @public
 */ EventEmitter.prototype.eventNames = function eventNames() {
                var names = [], events, name;
                if (this._eventsCount === 0) return names;
                for(name in events = this._events)if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
                if (Object.getOwnPropertySymbols) return names.concat(Object.getOwnPropertySymbols(events));
                return names;
            };
            /**
 * Return the listeners registered for a given event.
 *
 * @param {(String|Symbol)} event The event name.
 * @returns {Array} The registered listeners.
 * @public
 */ EventEmitter.prototype.listeners = function listeners(event) {
                var evt = prefix ? prefix + event : event, handlers = this._events[evt];
                if (!handlers) return [];
                if (handlers.fn) return [
                    handlers.fn
                ];
                for(var i = 0, l = handlers.length, ee = new Array(l); i < l; i++)ee[i] = handlers[i].fn;
                return ee;
            };
            /**
 * Return the number of listeners listening to a given event.
 *
 * @param {(String|Symbol)} event The event name.
 * @returns {Number} The number of listeners.
 * @public
 */ EventEmitter.prototype.listenerCount = function listenerCount(event) {
                var evt = prefix ? prefix + event : event, listeners = this._events[evt];
                if (!listeners) return 0;
                if (listeners.fn) return 1;
                return listeners.length;
            };
            /**
 * Calls each of the listeners registered for a given event.
 *
 * @param {(String|Symbol)} event The event name.
 * @returns {Boolean} `true` if the event had listeners, else `false`.
 * @public
 */ EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
                var evt = prefix ? prefix + event : event;
                if (!this._events[evt]) return false;
                var listeners = this._events[evt], len = arguments.length, args, i;
                if (listeners.fn) {
                    if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);
                    switch(len){
                        case 1:
                            return listeners.fn.call(listeners.context), true;
                        case 2:
                            return listeners.fn.call(listeners.context, a1), true;
                        case 3:
                            return listeners.fn.call(listeners.context, a1, a2), true;
                        case 4:
                            return listeners.fn.call(listeners.context, a1, a2, a3), true;
                        case 5:
                            return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
                        case 6:
                            return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
                    }
                    for(i = 1, args = new Array(len - 1); i < len; i++)args[i - 1] = arguments[i];
                    listeners.fn.apply(listeners.context, args);
                } else {
                    var length = listeners.length, j;
                    for(i = 0; i < length; i++){
                        if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);
                        switch(len){
                            case 1:
                                listeners[i].fn.call(listeners[i].context);
                                break;
                            case 2:
                                listeners[i].fn.call(listeners[i].context, a1);
                                break;
                            case 3:
                                listeners[i].fn.call(listeners[i].context, a1, a2);
                                break;
                            case 4:
                                listeners[i].fn.call(listeners[i].context, a1, a2, a3);
                                break;
                            default:
                                if (!args) for(j = 1, args = new Array(len - 1); j < len; j++)args[j - 1] = arguments[j];
                                listeners[i].fn.apply(listeners[i].context, args);
                        }
                    }
                }
                return true;
            };
            /**
 * Add a listener for a given event.
 *
 * @param {(String|Symbol)} event The event name.
 * @param {Function} fn The listener function.
 * @param {*} [context=this] The context to invoke the listener with.
 * @returns {EventEmitter} `this`.
 * @public
 */ EventEmitter.prototype.on = function on(event, fn, context) {
                return addListener(this, event, fn, context, false);
            };
            /**
 * Add a one-time listener for a given event.
 *
 * @param {(String|Symbol)} event The event name.
 * @param {Function} fn The listener function.
 * @param {*} [context=this] The context to invoke the listener with.
 * @returns {EventEmitter} `this`.
 * @public
 */ EventEmitter.prototype.once = function once(event, fn, context) {
                return addListener(this, event, fn, context, true);
            };
            /**
 * Remove the listeners of a given event.
 *
 * @param {(String|Symbol)} event The event name.
 * @param {Function} fn Only remove the listeners that match this function.
 * @param {*} context Only remove the listeners that have this context.
 * @param {Boolean} once Only remove one-time listeners.
 * @returns {EventEmitter} `this`.
 * @public
 */ EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
                var evt = prefix ? prefix + event : event;
                if (!this._events[evt]) return this;
                if (!fn) {
                    clearEvent(this, evt);
                    return this;
                }
                var listeners = this._events[evt];
                if (listeners.fn) {
                    if (listeners.fn === fn && (!once || listeners.once) && (!context || listeners.context === context)) clearEvent(this, evt);
                } else {
                    for(var i = 0, events = [], length = listeners.length; i < length; i++)if (listeners[i].fn !== fn || once && !listeners[i].once || context && listeners[i].context !== context) events.push(listeners[i]);
                    //
                    // Reset the array, or remove it completely if we have no more listeners.
                    //
                    if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;
                    else clearEvent(this, evt);
                }
                return this;
            };
            /**
 * Remove all listeners, or those of the specified event.
 *
 * @param {(String|Symbol)} [event] The event name.
 * @returns {EventEmitter} `this`.
 * @public
 */ EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
                var evt;
                if (event) {
                    evt = prefix ? prefix + event : event;
                    if (this._events[evt]) clearEvent(this, evt);
                } else {
                    this._events = new Events();
                    this._eventsCount = 0;
                }
                return this;
            };
            //
            // Alias methods names because people roll like that.
            //
            EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
            EventEmitter.prototype.addListener = EventEmitter.prototype.on;
            //
            // Expose the prefix.
            //
            EventEmitter.prefixed = prefix;
            //
            // Allow `EventEmitter` to be imported as module namespace.
            //
            EventEmitter.EventEmitter = EventEmitter;
            module.exports = EventEmitter;
        /***/ },
        /***/ "./node_modules/url-toolkit/src/url-toolkit.js": function(module, exports, __webpack_require__) {
            // see https://tools.ietf.org/html/rfc1808
            (function(root) {
                var URL_REGEX = /^((?:[a-zA-Z0-9+\-.]+:)?)(\/\/[^\/?#]*)?((?:[^\/?#]*\/)*[^;?#]*)?(;[^?#]*)?(\?[^#]*)?(#.*)?$/;
                var FIRST_SEGMENT_REGEX = /^([^\/?#]*)(.*)$/;
                var SLASH_DOT_REGEX = /(?:\/|^)\.(?=\/)/g;
                var SLASH_DOT_DOT_REGEX = /(?:\/|^)\.\.\/(?!\.\.\/)[^\/]*(?=\/)/g;
                var URLToolkit = {
                    // If opts.alwaysNormalize is true then the path will always be normalized even when it starts with / or //
                    // E.g
                    // With opts.alwaysNormalize = false (default, spec compliant)
                    // http://a.com/b/cd + /e/f/../g => http://a.com/e/f/../g
                    // With opts.alwaysNormalize = true (not spec compliant)
                    // http://a.com/b/cd + /e/f/../g => http://a.com/e/g
                    buildAbsoluteURL: function(baseURL, relativeURL, opts) {
                        opts = opts || {
                        };
                        // remove any remaining space and CRLF
                        baseURL = baseURL.trim();
                        relativeURL = relativeURL.trim();
                        if (!relativeURL) {
                            // 2a) If the embedded URL is entirely empty, it inherits the
                            // entire base URL (i.e., is set equal to the base URL)
                            // and we are done.
                            if (!opts.alwaysNormalize) return baseURL;
                            var basePartsForNormalise = URLToolkit.parseURL(baseURL);
                            if (!basePartsForNormalise) throw new Error('Error trying to parse base URL.');
                            basePartsForNormalise.path = URLToolkit.normalizePath(basePartsForNormalise.path);
                            return URLToolkit.buildURLFromParts(basePartsForNormalise);
                        }
                        var relativeParts = URLToolkit.parseURL(relativeURL);
                        if (!relativeParts) throw new Error('Error trying to parse relative URL.');
                        if (relativeParts.scheme) {
                            // 2b) If the embedded URL starts with a scheme name, it is
                            // interpreted as an absolute URL and we are done.
                            if (!opts.alwaysNormalize) return relativeURL;
                            relativeParts.path = URLToolkit.normalizePath(relativeParts.path);
                            return URLToolkit.buildURLFromParts(relativeParts);
                        }
                        var baseParts = URLToolkit.parseURL(baseURL);
                        if (!baseParts) throw new Error('Error trying to parse base URL.');
                        if (!baseParts.netLoc && baseParts.path && baseParts.path[0] !== '/') {
                            // If netLoc missing and path doesn't start with '/', assume everthing before the first '/' is the netLoc
                            // This causes 'example.com/a' to be handled as '//example.com/a' instead of '/example.com/a'
                            var pathParts = FIRST_SEGMENT_REGEX.exec(baseParts.path);
                            baseParts.netLoc = pathParts[1];
                            baseParts.path = pathParts[2];
                        }
                        if (baseParts.netLoc && !baseParts.path) baseParts.path = '/';
                        var builtParts = {
                            // 2c) Otherwise, the embedded URL inherits the scheme of
                            // the base URL.
                            scheme: baseParts.scheme,
                            netLoc: relativeParts.netLoc,
                            path: null,
                            params: relativeParts.params,
                            query: relativeParts.query,
                            fragment: relativeParts.fragment
                        };
                        if (!relativeParts.netLoc) {
                            // 3) If the embedded URL's <net_loc> is non-empty, we skip to
                            // Step 7.  Otherwise, the embedded URL inherits the <net_loc>
                            // (if any) of the base URL.
                            builtParts.netLoc = baseParts.netLoc;
                            // 4) If the embedded URL path is preceded by a slash "/", the
                            // path is not relative and we skip to Step 7.
                            if (relativeParts.path[0] !== '/') {
                                if (!relativeParts.path) {
                                    // 5) If the embedded URL path is empty (and not preceded by a
                                    // slash), then the embedded URL inherits the base URL path
                                    builtParts.path = baseParts.path;
                                    // 5a) if the embedded URL's <params> is non-empty, we skip to
                                    // step 7; otherwise, it inherits the <params> of the base
                                    // URL (if any) and
                                    if (!relativeParts.params) {
                                        builtParts.params = baseParts.params;
                                        // 5b) if the embedded URL's <query> is non-empty, we skip to
                                        // step 7; otherwise, it inherits the <query> of the base
                                        // URL (if any) and we skip to step 7.
                                        if (!relativeParts.query) builtParts.query = baseParts.query;
                                    }
                                } else {
                                    // 6) The last segment of the base URL's path (anything
                                    // following the rightmost slash "/", or the entire path if no
                                    // slash is present) is removed and the embedded URL's path is
                                    // appended in its place.
                                    var baseURLPath = baseParts.path;
                                    var newPath = baseURLPath.substring(0, baseURLPath.lastIndexOf('/') + 1) + relativeParts.path;
                                    builtParts.path = URLToolkit.normalizePath(newPath);
                                }
                            }
                        }
                        if (builtParts.path === null) builtParts.path = opts.alwaysNormalize ? URLToolkit.normalizePath(relativeParts.path) : relativeParts.path;
                        return URLToolkit.buildURLFromParts(builtParts);
                    },
                    parseURL: function(url) {
                        var parts = URL_REGEX.exec(url);
                        if (!parts) return null;
                        return {
                            scheme: parts[1] || '',
                            netLoc: parts[2] || '',
                            path: parts[3] || '',
                            params: parts[4] || '',
                            query: parts[5] || '',
                            fragment: parts[6] || ''
                        };
                    },
                    normalizePath: function(path) {
                        // The following operations are
                        // then applied, in order, to the new path:
                        // 6a) All occurrences of "./", where "." is a complete path
                        // segment, are removed.
                        // 6b) If the path ends with "." as a complete path segment,
                        // that "." is removed.
                        path = path.split('').reverse().join('').replace(SLASH_DOT_REGEX, '');
                        // 6c) All occurrences of "<segment>/../", where <segment> is a
                        // complete path segment not equal to "..", are removed.
                        // Removal of these path segments is performed iteratively,
                        // removing the leftmost matching pattern on each iteration,
                        // until no matching pattern remains.
                        // 6d) If the path ends with "<segment>/..", where <segment> is a
                        // complete path segment not equal to "..", that
                        // "<segment>/.." is removed.
                        while(path.length !== (path = path.replace(SLASH_DOT_DOT_REGEX, '')).length);
                        return path.split('').reverse().join('');
                    },
                    buildURLFromParts: function(parts) {
                        return parts.scheme + parts.netLoc + parts.path + parts.params + parts.query + parts.fragment;
                    }
                };
                module.exports = URLToolkit;
            })(this);
        /***/ },
        /***/ "./node_modules/webworkify-webpack/index.js": function(module1, exports1, __webpack_require__1) {
            function webpackBootstrapFunc(modules) {
                /******/ // The module cache
                /******/ var installedModules = {
                };
                /******/ // The require function
                /******/ function __webpack_require__(moduleId) {
                    /******/ // Check if module is in cache
                    /******/ if (installedModules[moduleId]) /******/ return installedModules[moduleId].exports;
                    /******/ // Create a new module (and put it into the cache)
                    /******/ var module = installedModules[moduleId] = {
                        /******/ i: moduleId,
                        /******/ l: false,
                        /******/ exports: {
                        }
                    };
                    /******/ // Execute the module function
                    /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
                    /******/ // Flag the module as loaded
                    /******/ module.l = true;
                    /******/ // Return the exports of the module
                    /******/ return module.exports;
                /******/ }
                /******/ // expose the modules object (__webpack_modules__)
                /******/ __webpack_require__.m = modules;
                /******/ // expose the module cache
                /******/ __webpack_require__.c = installedModules;
                /******/ // identity function for calling harmony imports with the correct context
                /******/ __webpack_require__.i = function(value) {
                    return value;
                };
                /******/ // define getter function for harmony exports
                /******/ __webpack_require__.d = function(exports, name, getter) {
                    /******/ if (!__webpack_require__.o(exports, name)) /******/ Object.defineProperty(exports, name, {
                        /******/ configurable: false,
                        /******/ enumerable: true,
                        /******/ get: getter
                    });
                /******/ };
                /******/ // define __esModule on exports
                /******/ __webpack_require__.r = function(exports) {
                    /******/ Object.defineProperty(exports, '__esModule', {
                        value: true
                    });
                /******/ };
                /******/ // getDefaultExport function for compatibility with non-harmony modules
                /******/ __webpack_require__.n = function(module) {
                    /******/ var getter = module && module.__esModule ? /******/ function getDefault() {
                        return module['default'];
                    } : /******/ function getModuleExports() {
                        return module;
                    };
                    /******/ __webpack_require__.d(getter, 'a', getter);
                    /******/ return getter;
                /******/ };
                /******/ // Object.prototype.hasOwnProperty.call
                /******/ __webpack_require__.o = function(object, property) {
                    return Object.prototype.hasOwnProperty.call(object, property);
                };
                /******/ // __webpack_public_path__
                /******/ __webpack_require__.p = "/";
                /******/ // on error function for async loading
                /******/ __webpack_require__.oe = function(err) {
                    console.error(err);
                    throw err;
                };
                var f = __webpack_require__(__webpack_require__.s = ENTRY_MODULE);
                return f.default || f // try to call default if defined to also support babel esmodule exports
                ;
            }
            var moduleNameReqExp = '[\\.|\\-|\\+|\\w|\/|@]+';
            var dependencyRegExp = '\\(\\s*(\/\\*.*?\\*\/)?\\s*.*?(' + moduleNameReqExp + ').*?\\)' // additional chars when output.pathinfo is true
            ;
            // http://stackoverflow.com/a/2593661/130442
            function quoteRegExp(str) {
                return (str + '').replace(/[.?*+^$[\]\\(){}|-]/g, '\\$&');
            }
            function isNumeric(n) {
                return !isNaN(1 * n); // 1 * n converts integers, integers as string ("123"), 1e3 and "1e3" to integers and strings to NaN
            }
            function getModuleDependencies(sources, module, queueName) {
                var retval = {
                };
                retval[queueName] = [];
                var fnString = module.toString();
                var wrapperSignature = fnString.match(/^function\s?\w*\(\w+,\s*\w+,\s*(\w+)\)/);
                if (!wrapperSignature) return retval;
                var webpackRequireName = wrapperSignature[1];
                // main bundle deps
                var re = new RegExp('(\\\\n|\\W)' + quoteRegExp(webpackRequireName) + dependencyRegExp, 'g');
                var match;
                while(match = re.exec(fnString)){
                    if (match[3] === 'dll-reference') continue;
                    retval[queueName].push(match[3]);
                }
                // dll deps
                re = new RegExp('\\(' + quoteRegExp(webpackRequireName) + '\\("(dll-reference\\s(' + moduleNameReqExp + '))"\\)\\)' + dependencyRegExp, 'g');
                while(match = re.exec(fnString)){
                    if (!sources[match[2]]) {
                        retval[queueName].push(match[1]);
                        sources[match[2]] = __webpack_require__1(match[1]).m;
                    }
                    retval[match[2]] = retval[match[2]] || [];
                    retval[match[2]].push(match[4]);
                }
                // convert 1e3 back to 1000 - this can be important after uglify-js converted 1000 to 1e3
                var keys = Object.keys(retval);
                for(var i = 0; i < keys.length; i++){
                    for(var j = 0; j < retval[keys[i]].length; j++)if (isNumeric(retval[keys[i]][j])) retval[keys[i]][j] = 1 * retval[keys[i]][j];
                }
                return retval;
            }
            function hasValuesInQueues(queues) {
                var keys = Object.keys(queues);
                return keys.reduce(function(hasValues, key) {
                    return hasValues || queues[key].length > 0;
                }, false);
            }
            function getRequiredModules(sources, moduleId) {
                var modulesQueue = {
                    main: [
                        moduleId
                    ]
                };
                var requiredModules = {
                    main: []
                };
                var seenModules = {
                    main: {
                    }
                };
                while(hasValuesInQueues(modulesQueue)){
                    var queues = Object.keys(modulesQueue);
                    for(var i = 0; i < queues.length; i++){
                        var queueName = queues[i];
                        var queue = modulesQueue[queueName];
                        var moduleToCheck = queue.pop();
                        seenModules[queueName] = seenModules[queueName] || {
                        };
                        if (seenModules[queueName][moduleToCheck] || !sources[queueName][moduleToCheck]) continue;
                        seenModules[queueName][moduleToCheck] = true;
                        requiredModules[queueName] = requiredModules[queueName] || [];
                        requiredModules[queueName].push(moduleToCheck);
                        var newModules = getModuleDependencies(sources, sources[queueName][moduleToCheck], queueName);
                        var newModulesKeys = Object.keys(newModules);
                        for(var j = 0; j < newModulesKeys.length; j++){
                            modulesQueue[newModulesKeys[j]] = modulesQueue[newModulesKeys[j]] || [];
                            modulesQueue[newModulesKeys[j]] = modulesQueue[newModulesKeys[j]].concat(newModules[newModulesKeys[j]]);
                        }
                    }
                }
                return requiredModules;
            }
            module1.exports = function(moduleId, options) {
                options = options || {
                };
                var sources = {
                    main: __webpack_require__1.m
                };
                var requiredModules = options.all ? {
                    main: Object.keys(sources.main)
                } : getRequiredModules(sources, moduleId);
                var src = '';
                Object.keys(requiredModules).filter(function(m) {
                    return m !== 'main';
                }).forEach(function(module) {
                    var entryModule = 0;
                    while(requiredModules[module][entryModule])entryModule++;
                    requiredModules[module].push(entryModule);
                    sources[module][entryModule] = '(function(module, exports, __webpack_require__) { module.exports = __webpack_require__; })';
                    src = src + 'var ' + module + ' = (' + webpackBootstrapFunc.toString().replace('ENTRY_MODULE', JSON.stringify(entryModule)) + ')({' + requiredModules[module].map(function(id) {
                        return '' + JSON.stringify(id) + ': ' + sources[module][id].toString();
                    }).join(',') + '});\n';
                });
                src = src + 'new ((' + webpackBootstrapFunc.toString().replace('ENTRY_MODULE', JSON.stringify(moduleId)) + ')({' + requiredModules.main.map(function(id) {
                    return '' + JSON.stringify(id) + ': ' + sources.main[id].toString();
                }).join(',') + '}))(self);';
                var blob = new window.Blob([
                    src
                ], {
                    type: 'text/javascript'
                });
                if (options.bare) return blob;
                var URL = window.URL || window.webkitURL || window.mozURL || window.msURL;
                var workerUrl = URL.createObjectURL(blob);
                var worker = new window.Worker(workerUrl);
                worker.objectURL = workerUrl;
                return worker;
            };
        /***/ },
        /***/ "./src/crypt/decrypter.js": function(module, __webpack_exports__, __webpack_require__) {
            "use strict";
            // ESM COMPAT FLAG
            __webpack_require__.r(__webpack_exports__);
            // CONCATENATED MODULE: ./src/crypt/aes-crypto.js
            var AESCrypto1 = /*#__PURE__*/ function() {
                function AESCrypto(subtle, iv) {
                    this.subtle = subtle;
                    this.aesIV = iv;
                }
                var _proto = AESCrypto.prototype;
                _proto.decrypt = function decrypt(data, key) {
                    return this.subtle.decrypt({
                        name: 'AES-CBC',
                        iv: this.aesIV
                    }, key, data);
                };
                return AESCrypto;
            }();
            // CONCATENATED MODULE: ./src/crypt/fast-aes-key.js
            var FastAESKey1 = /*#__PURE__*/ function() {
                function FastAESKey(subtle, key) {
                    this.subtle = subtle;
                    this.key = key;
                }
                var _proto = FastAESKey.prototype;
                _proto.expandKey = function expandKey() {
                    return this.subtle.importKey('raw', this.key, {
                        name: 'AES-CBC'
                    }, false, [
                        'encrypt',
                        'decrypt'
                    ]);
                };
                return FastAESKey;
            }();
            /* harmony default export */ var fast_aes_key = FastAESKey1;
            // CONCATENATED MODULE: ./src/crypt/aes-decryptor.js
            // PKCS7
            function removePadding(buffer) {
                var outputBytes = buffer.byteLength;
                var paddingBytes = outputBytes && new DataView(buffer).getUint8(outputBytes - 1);
                if (paddingBytes) return buffer.slice(0, outputBytes - paddingBytes);
                else return buffer;
            }
            var AESDecryptor1 = /*#__PURE__*/ function() {
                function AESDecryptor() {
                    // Static after running initTable
                    this.rcon = [
                        0,
                        1,
                        2,
                        4,
                        8,
                        16,
                        32,
                        64,
                        128,
                        27,
                        54
                    ];
                    this.subMix = [
                        new Uint32Array(256),
                        new Uint32Array(256),
                        new Uint32Array(256),
                        new Uint32Array(256)
                    ];
                    this.invSubMix = [
                        new Uint32Array(256),
                        new Uint32Array(256),
                        new Uint32Array(256),
                        new Uint32Array(256)
                    ];
                    this.sBox = new Uint32Array(256);
                    this.invSBox = new Uint32Array(256); // Changes during runtime
                    this.key = new Uint32Array(0);
                    this.initTable();
                } // Using view.getUint32() also swaps the byte order.
                var _proto = AESDecryptor.prototype;
                _proto.uint8ArrayToUint32Array_ = function uint8ArrayToUint32Array_(arrayBuffer) {
                    var view = new DataView(arrayBuffer);
                    var newArray = new Uint32Array(4);
                    for(var i = 0; i < 4; i++)newArray[i] = view.getUint32(i * 4);
                    return newArray;
                };
                _proto.initTable = function initTable() {
                    var sBox = this.sBox;
                    var invSBox = this.invSBox;
                    var subMix = this.subMix;
                    var subMix0 = subMix[0];
                    var subMix1 = subMix[1];
                    var subMix2 = subMix[2];
                    var subMix3 = subMix[3];
                    var invSubMix = this.invSubMix;
                    var invSubMix0 = invSubMix[0];
                    var invSubMix1 = invSubMix[1];
                    var invSubMix2 = invSubMix[2];
                    var invSubMix3 = invSubMix[3];
                    var d = new Uint32Array(256);
                    var x = 0;
                    var xi = 0;
                    var i = 0;
                    for(i = 0; i < 256; i++)if (i < 128) d[i] = i << 1;
                    else d[i] = i << 1 ^ 283;
                    for(i = 0; i < 256; i++){
                        var sx = xi ^ xi << 1 ^ xi << 2 ^ xi << 3 ^ xi << 4;
                        sx = sx >>> 8 ^ sx & 255 ^ 99;
                        sBox[x] = sx;
                        invSBox[sx] = x; // Compute multiplication
                        var x2 = d[x];
                        var x4 = d[x2];
                        var x8 = d[x4]; // Compute sub/invSub bytes, mix columns tables
                        var t = d[sx] * 257 ^ sx * 16843008;
                        subMix0[x] = t << 24 | t >>> 8;
                        subMix1[x] = t << 16 | t >>> 16;
                        subMix2[x] = t << 8 | t >>> 24;
                        subMix3[x] = t; // Compute inv sub bytes, inv mix columns tables
                        t = x8 * 16843009 ^ x4 * 65537 ^ x2 * 257 ^ x * 16843008;
                        invSubMix0[sx] = t << 24 | t >>> 8;
                        invSubMix1[sx] = t << 16 | t >>> 16;
                        invSubMix2[sx] = t << 8 | t >>> 24;
                        invSubMix3[sx] = t; // Compute next counter
                        if (!x) x = xi = 1;
                        else {
                            x = x2 ^ d[d[d[x8 ^ x2]]];
                            xi ^= d[d[xi]];
                        }
                    }
                };
                _proto.expandKey = function expandKey(keyBuffer) {
                    // convert keyBuffer to Uint32Array
                    var key = this.uint8ArrayToUint32Array_(keyBuffer);
                    var sameKey = true;
                    var offset = 0;
                    while(offset < key.length && sameKey){
                        sameKey = key[offset] === this.key[offset];
                        offset++;
                    }
                    if (sameKey) return;
                    this.key = key;
                    var keySize = this.keySize = key.length;
                    if (keySize !== 4 && keySize !== 6 && keySize !== 8) throw new Error('Invalid aes key size=' + keySize);
                    var ksRows = this.ksRows = (keySize + 6 + 1) * 4;
                    var ksRow;
                    var invKsRow;
                    var keySchedule = this.keySchedule = new Uint32Array(ksRows);
                    var invKeySchedule = this.invKeySchedule = new Uint32Array(ksRows);
                    var sbox = this.sBox;
                    var rcon = this.rcon;
                    var invSubMix = this.invSubMix;
                    var invSubMix0 = invSubMix[0];
                    var invSubMix1 = invSubMix[1];
                    var invSubMix2 = invSubMix[2];
                    var invSubMix3 = invSubMix[3];
                    var prev;
                    var t;
                    for(ksRow = 0; ksRow < ksRows; ksRow++){
                        if (ksRow < keySize) {
                            prev = keySchedule[ksRow] = key[ksRow];
                            continue;
                        }
                        t = prev;
                        if (ksRow % keySize === 0) {
                            // Rot word
                            t = t << 8 | t >>> 24; // Sub word
                            t = sbox[t >>> 24] << 24 | sbox[t >>> 16 & 255] << 16 | sbox[t >>> 8 & 255] << 8 | sbox[t & 255]; // Mix Rcon
                            t ^= rcon[ksRow / keySize | 0] << 24;
                        } else if (keySize > 6 && ksRow % keySize === 4) // Sub word
                        t = sbox[t >>> 24] << 24 | sbox[t >>> 16 & 255] << 16 | sbox[t >>> 8 & 255] << 8 | sbox[t & 255];
                        keySchedule[ksRow] = prev = (keySchedule[ksRow - keySize] ^ t) >>> 0;
                    }
                    for(invKsRow = 0; invKsRow < ksRows; invKsRow++){
                        ksRow = ksRows - invKsRow;
                        if (invKsRow & 3) t = keySchedule[ksRow];
                        else t = keySchedule[ksRow - 4];
                        if (invKsRow < 4 || ksRow <= 4) invKeySchedule[invKsRow] = t;
                        else invKeySchedule[invKsRow] = invSubMix0[sbox[t >>> 24]] ^ invSubMix1[sbox[t >>> 16 & 255]] ^ invSubMix2[sbox[t >>> 8 & 255]] ^ invSubMix3[sbox[t & 255]];
                        invKeySchedule[invKsRow] = invKeySchedule[invKsRow] >>> 0;
                    }
                } // Adding this as a method greatly improves performance.
                ;
                _proto.networkToHostOrderSwap = function networkToHostOrderSwap(word) {
                    return word << 24 | (word & 65280) << 8 | (word & 16711680) >> 8 | word >>> 24;
                };
                _proto.decrypt = function decrypt(inputArrayBuffer, offset, aesIV, removePKCS7Padding) {
                    var nRounds = this.keySize + 6;
                    var invKeySchedule = this.invKeySchedule;
                    var invSBOX = this.invSBox;
                    var invSubMix = this.invSubMix;
                    var invSubMix0 = invSubMix[0];
                    var invSubMix1 = invSubMix[1];
                    var invSubMix2 = invSubMix[2];
                    var invSubMix3 = invSubMix[3];
                    var initVector = this.uint8ArrayToUint32Array_(aesIV);
                    var initVector0 = initVector[0];
                    var initVector1 = initVector[1];
                    var initVector2 = initVector[2];
                    var initVector3 = initVector[3];
                    var inputInt32 = new Int32Array(inputArrayBuffer);
                    var outputInt32 = new Int32Array(inputInt32.length);
                    var t0, t1, t2, t3;
                    var s0, s1, s2, s3;
                    var inputWords0, inputWords1, inputWords2, inputWords3;
                    var ksRow, i;
                    var swapWord = this.networkToHostOrderSwap;
                    while(offset < inputInt32.length){
                        inputWords0 = swapWord(inputInt32[offset]);
                        inputWords1 = swapWord(inputInt32[offset + 1]);
                        inputWords2 = swapWord(inputInt32[offset + 2]);
                        inputWords3 = swapWord(inputInt32[offset + 3]);
                        s0 = inputWords0 ^ invKeySchedule[0];
                        s1 = inputWords3 ^ invKeySchedule[1];
                        s2 = inputWords2 ^ invKeySchedule[2];
                        s3 = inputWords1 ^ invKeySchedule[3];
                        ksRow = 4; // Iterate through the rounds of decryption
                        for(i = 1; i < nRounds; i++){
                            t0 = invSubMix0[s0 >>> 24] ^ invSubMix1[s1 >> 16 & 255] ^ invSubMix2[s2 >> 8 & 255] ^ invSubMix3[s3 & 255] ^ invKeySchedule[ksRow];
                            t1 = invSubMix0[s1 >>> 24] ^ invSubMix1[s2 >> 16 & 255] ^ invSubMix2[s3 >> 8 & 255] ^ invSubMix3[s0 & 255] ^ invKeySchedule[ksRow + 1];
                            t2 = invSubMix0[s2 >>> 24] ^ invSubMix1[s3 >> 16 & 255] ^ invSubMix2[s0 >> 8 & 255] ^ invSubMix3[s1 & 255] ^ invKeySchedule[ksRow + 2];
                            t3 = invSubMix0[s3 >>> 24] ^ invSubMix1[s0 >> 16 & 255] ^ invSubMix2[s1 >> 8 & 255] ^ invSubMix3[s2 & 255] ^ invKeySchedule[ksRow + 3]; // Update state
                            s0 = t0;
                            s1 = t1;
                            s2 = t2;
                            s3 = t3;
                            ksRow = ksRow + 4;
                        } // Shift rows, sub bytes, add round key
                        t0 = invSBOX[s0 >>> 24] << 24 ^ invSBOX[s1 >> 16 & 255] << 16 ^ invSBOX[s2 >> 8 & 255] << 8 ^ invSBOX[s3 & 255] ^ invKeySchedule[ksRow];
                        t1 = invSBOX[s1 >>> 24] << 24 ^ invSBOX[s2 >> 16 & 255] << 16 ^ invSBOX[s3 >> 8 & 255] << 8 ^ invSBOX[s0 & 255] ^ invKeySchedule[ksRow + 1];
                        t2 = invSBOX[s2 >>> 24] << 24 ^ invSBOX[s3 >> 16 & 255] << 16 ^ invSBOX[s0 >> 8 & 255] << 8 ^ invSBOX[s1 & 255] ^ invKeySchedule[ksRow + 2];
                        t3 = invSBOX[s3 >>> 24] << 24 ^ invSBOX[s0 >> 16 & 255] << 16 ^ invSBOX[s1 >> 8 & 255] << 8 ^ invSBOX[s2 & 255] ^ invKeySchedule[ksRow + 3];
                        ksRow = ksRow + 3; // Write
                        outputInt32[offset] = swapWord(t0 ^ initVector0);
                        outputInt32[offset + 1] = swapWord(t3 ^ initVector1);
                        outputInt32[offset + 2] = swapWord(t2 ^ initVector2);
                        outputInt32[offset + 3] = swapWord(t1 ^ initVector3); // reset initVector to last 4 unsigned int
                        initVector0 = inputWords0;
                        initVector1 = inputWords1;
                        initVector2 = inputWords2;
                        initVector3 = inputWords3;
                        offset = offset + 4;
                    }
                    return removePKCS7Padding ? removePadding(outputInt32.buffer) : outputInt32.buffer;
                };
                _proto.destroy = function destroy() {
                    this.key = undefined;
                    this.keySize = undefined;
                    this.ksRows = undefined;
                    this.sBox = undefined;
                    this.invSBox = undefined;
                    this.subMix = undefined;
                    this.invSubMix = undefined;
                    this.keySchedule = undefined;
                    this.invKeySchedule = undefined;
                    this.rcon = undefined;
                };
                return AESDecryptor;
            }();
            /* harmony default export */ var aes_decryptor = AESDecryptor1;
            // EXTERNAL MODULE: ./src/errors.ts
            var errors = __webpack_require__("./src/errors.ts");
            // EXTERNAL MODULE: ./src/utils/logger.js
            var logger = __webpack_require__("./src/utils/logger.js");
            // EXTERNAL MODULE: ./src/events.js
            var events = __webpack_require__("./src/events.js");
            // EXTERNAL MODULE: ./src/utils/get-self-scope.js
            var get_self_scope = __webpack_require__("./src/utils/get-self-scope.js");
            // CONCATENATED MODULE: ./src/crypt/decrypter.js
            // see https://stackoverflow.com/a/11237259/589493
            var global = Object(get_self_scope["getSelfScope"])(); // safeguard for code that might run both on worker and main thread
            var decrypter_Decrypter = /*#__PURE__*/ function() {
                function Decrypter(observer, config, _temp) {
                    var _ref = _temp === void 0 ? {
                    } : _temp, _ref$removePKCS7Paddi = _ref.removePKCS7Padding, removePKCS7Padding = _ref$removePKCS7Paddi === void 0 ? true : _ref$removePKCS7Paddi;
                    this.logEnabled = true;
                    this.observer = observer;
                    this.config = config;
                    this.removePKCS7Padding = removePKCS7Padding; // built in decryptor expects PKCS7 padding
                    if (removePKCS7Padding) try {
                        var browserCrypto = global.crypto;
                        if (browserCrypto) this.subtle = browserCrypto.subtle || browserCrypto.webkitSubtle;
                    } catch (e) {
                    }
                    this.disableWebCrypto = !this.subtle;
                }
                var _proto = Decrypter.prototype;
                _proto.isSync = function isSync() {
                    return this.disableWebCrypto && this.config.enableSoftwareAES;
                };
                _proto.decrypt = function decrypt(data, key, iv, callback) {
                    var _this = this;
                    if (this.disableWebCrypto && this.config.enableSoftwareAES) {
                        if (this.logEnabled) {
                            logger["logger"].log('JS AES decrypt');
                            this.logEnabled = false;
                        }
                        var decryptor = this.decryptor;
                        if (!decryptor) this.decryptor = decryptor = new aes_decryptor();
                        decryptor.expandKey(key);
                        callback(decryptor.decrypt(data, 0, iv, this.removePKCS7Padding));
                    } else {
                        if (this.logEnabled) {
                            logger["logger"].log('WebCrypto AES decrypt');
                            this.logEnabled = false;
                        }
                        var subtle = this.subtle;
                        if (this.key !== key) {
                            this.key = key;
                            this.fastAesKey = new fast_aes_key(subtle, key);
                        }
                        this.fastAesKey.expandKey().then(function(aesKey) {
                            // decrypt using web crypto
                            var crypto = new AESCrypto1(subtle, iv);
                            crypto.decrypt(data, aesKey).catch(function(err) {
                                _this.onWebCryptoError(err, data, key, iv, callback);
                            }).then(function(result) {
                                callback(result);
                            });
                        }).catch(function(err) {
                            _this.onWebCryptoError(err, data, key, iv, callback);
                        });
                    }
                };
                _proto.onWebCryptoError = function onWebCryptoError(err, data, key, iv, callback) {
                    if (this.config.enableSoftwareAES) {
                        logger["logger"].log('WebCrypto Error, disable WebCrypto API');
                        this.disableWebCrypto = true;
                        this.logEnabled = true;
                        this.decrypt(data, key, iv, callback);
                    } else {
                        logger["logger"].error("decrypting error : " + err.message);
                        this.observer.trigger(events["default"].ERROR, {
                            type: errors["ErrorTypes"].MEDIA_ERROR,
                            details: errors["ErrorDetails"].FRAG_DECRYPT_ERROR,
                            fatal: true,
                            reason: err.message
                        });
                    }
                };
                _proto.destroy = function destroy() {
                    var decryptor = this.decryptor;
                    if (decryptor) {
                        decryptor.destroy();
                        this.decryptor = undefined;
                    }
                };
                return Decrypter;
            }();
            /* harmony default export */ var decrypter = __webpack_exports__["default"] = decrypter_Decrypter;
        /***/ },
        /***/ "./src/demux/demuxer-inline.js": function(module, __webpack_exports__, __webpack_require__) {
            "use strict";
            // ESM COMPAT FLAG
            __webpack_require__.r(__webpack_exports__);
            // EXTERNAL MODULE: ./src/events.js
            var events = __webpack_require__("./src/events.js");
            // EXTERNAL MODULE: ./src/errors.ts
            var errors = __webpack_require__("./src/errors.ts");
            // EXTERNAL MODULE: ./src/crypt/decrypter.js + 3 modules
            var crypt_decrypter = __webpack_require__("./src/crypt/decrypter.js");
            // EXTERNAL MODULE: ./src/polyfills/number.js
            var number = __webpack_require__("./src/polyfills/number.js");
            // EXTERNAL MODULE: ./src/utils/logger.js
            var logger = __webpack_require__("./src/utils/logger.js");
            // EXTERNAL MODULE: ./src/utils/get-self-scope.js
            var get_self_scope = __webpack_require__("./src/utils/get-self-scope.js");
            // CONCATENATED MODULE: ./src/demux/adts.js
            /**
 * ADTS parser helper
 * @link https://wiki.multimedia.cx/index.php?title=ADTS
 */ function getAudioConfig(observer, data, offset, audioCodec) {
                var adtsObjectType, // :int
                adtsSampleingIndex, // :int
                adtsExtensionSampleingIndex, // :int
                adtsChanelConfig, // :int
                config, userAgent = navigator.userAgent.toLowerCase(), manifestCodec = audioCodec, adtsSampleingRates = [
                    96000,
                    88200,
                    64000,
                    48000,
                    44100,
                    32000,
                    24000,
                    22050,
                    16000,
                    12000,
                    11025,
                    8000,
                    7350
                ]; // byte 2
                adtsObjectType = ((data[offset + 2] & 192) >>> 6) + 1;
                adtsSampleingIndex = (data[offset + 2] & 60) >>> 2;
                if (adtsSampleingIndex > adtsSampleingRates.length - 1) {
                    observer.trigger(events["default"].ERROR, {
                        type: errors["ErrorTypes"].MEDIA_ERROR,
                        details: errors["ErrorDetails"].FRAG_PARSING_ERROR,
                        fatal: true,
                        reason: "invalid ADTS sampling index:" + adtsSampleingIndex
                    });
                    return;
                }
                adtsChanelConfig = (data[offset + 2] & 1) << 2; // byte 3
                adtsChanelConfig |= (data[offset + 3] & 192) >>> 6;
                logger["logger"].log("manifest codec:" + audioCodec + ",ADTS data:type:" + adtsObjectType + ",sampleingIndex:" + adtsSampleingIndex + "[" + adtsSampleingRates[adtsSampleingIndex] + "Hz],channelConfig:" + adtsChanelConfig); // firefox: freq less than 24kHz = AAC SBR (HE-AAC)
                if (/firefox/i.test(userAgent)) {
                    if (adtsSampleingIndex >= 6) {
                        adtsObjectType = 5;
                        config = new Array(4); // HE-AAC uses SBR (Spectral Band Replication) , high frequencies are constructed from low frequencies
                        // there is a factor 2 between frame sample rate and output sample rate
                        // multiply frequency by 2 (see table below, equivalent to substract 3)
                        adtsExtensionSampleingIndex = adtsSampleingIndex - 3;
                    } else {
                        adtsObjectType = 2;
                        config = new Array(2);
                        adtsExtensionSampleingIndex = adtsSampleingIndex;
                    } // Android : always use AAC
                } else if (userAgent.indexOf('android') !== -1) {
                    adtsObjectType = 2;
                    config = new Array(2);
                    adtsExtensionSampleingIndex = adtsSampleingIndex;
                } else {
                    /*  for other browsers (Chrome/Vivaldi/Opera ...)
        always force audio type to be HE-AAC SBR, as some browsers do not support audio codec switch properly (like Chrome ...)
    */ adtsObjectType = 5;
                    config = new Array(4); // if (manifest codec is HE-AAC or HE-AACv2) OR (manifest codec not specified AND frequency less than 24kHz)
                    if (audioCodec && (audioCodec.indexOf('mp4a.40.29') !== -1 || audioCodec.indexOf('mp4a.40.5') !== -1) || !audioCodec && adtsSampleingIndex >= 6) // HE-AAC uses SBR (Spectral Band Replication) , high frequencies are constructed from low frequencies
                    // there is a factor 2 between frame sample rate and output sample rate
                    // multiply frequency by 2 (see table below, equivalent to substract 3)
                    adtsExtensionSampleingIndex = adtsSampleingIndex - 3;
                    else {
                        // if (manifest codec is AAC) AND (frequency less than 24kHz AND nb channel is 1) OR (manifest codec not specified and mono audio)
                        // Chrome fails to play back with low frequency AAC LC mono when initialized with HE-AAC.  This is not a problem with stereo.
                        if (audioCodec && audioCodec.indexOf('mp4a.40.2') !== -1 && (adtsSampleingIndex >= 6 && adtsChanelConfig === 1 || /vivaldi/i.test(userAgent)) || !audioCodec && adtsChanelConfig === 1) {
                            adtsObjectType = 2;
                            config = new Array(2);
                        }
                        adtsExtensionSampleingIndex = adtsSampleingIndex;
                    }
                }
                /* refer to http://wiki.multimedia.cx/index.php?title=MPEG-4_Audio#Audio_Specific_Config
      ISO 14496-3 (AAC).pdf - Table 1.13 — Syntax of AudioSpecificConfig()
    Audio Profile / Audio Object Type
    0: Null
    1: AAC Main
    2: AAC LC (Low Complexity)
    3: AAC SSR (Scalable Sample Rate)
    4: AAC LTP (Long Term Prediction)
    5: SBR (Spectral Band Replication)
    6: AAC Scalable
   sampling freq
    0: 96000 Hz
    1: 88200 Hz
    2: 64000 Hz
    3: 48000 Hz
    4: 44100 Hz
    5: 32000 Hz
    6: 24000 Hz
    7: 22050 Hz
    8: 16000 Hz
    9: 12000 Hz
    10: 11025 Hz
    11: 8000 Hz
    12: 7350 Hz
    13: Reserved
    14: Reserved
    15: frequency is written explictly
    Channel Configurations
    These are the channel configurations:
    0: Defined in AOT Specifc Config
    1: 1 channel: front-center
    2: 2 channels: front-left, front-right
  */ // audioObjectType = profile => profile, the MPEG-4 Audio Object Type minus 1
                config[0] = adtsObjectType << 3; // samplingFrequencyIndex
                config[0] |= (adtsSampleingIndex & 14) >> 1;
                config[1] |= (adtsSampleingIndex & 1) << 7; // channelConfiguration
                config[1] |= adtsChanelConfig << 3;
                if (adtsObjectType === 5) {
                    // adtsExtensionSampleingIndex
                    config[1] |= (adtsExtensionSampleingIndex & 14) >> 1;
                    config[2] = (adtsExtensionSampleingIndex & 1) << 7; // adtsObjectType (force to 2, chrome is checking that object type is less than 5 ???
                    //    https://chromium.googlesource.com/chromium/src.git/+/master/media/formats/mp4/aac.cc
                    config[2] |= 8;
                    config[3] = 0;
                }
                return {
                    config: config,
                    samplerate: adtsSampleingRates[adtsSampleingIndex],
                    channelCount: adtsChanelConfig,
                    codec: 'mp4a.40.' + adtsObjectType,
                    manifestCodec: manifestCodec
                };
            }
            function isHeaderPattern(data, offset) {
                return data[offset] === 255 && (data[offset + 1] & 246) === 240;
            }
            function getHeaderLength(data, offset) {
                return data[offset + 1] & 1 ? 7 : 9;
            }
            function getFullFrameLength(data, offset) {
                return (data[offset + 3] & 3) << 11 | data[offset + 4] << 3 | (data[offset + 5] & 224) >>> 5;
            }
            function isHeader(data, offset) {
                // Look for ADTS header | 1111 1111 | 1111 X00X | where X can be either 0 or 1
                // Layer bits (position 14 and 15) in header should be always 0 for ADTS
                // More info https://wiki.multimedia.cx/index.php?title=ADTS
                if (offset + 1 < data.length && isHeaderPattern(data, offset)) return true;
                return false;
            }
            function adts_probe(data, offset) {
                // same as isHeader but we also check that ADTS frame follows last ADTS frame
                // or end of data is reached
                if (isHeader(data, offset)) {
                    // ADTS header Length
                    var headerLength = getHeaderLength(data, offset);
                    if (offset + headerLength >= data.length) return false;
                     // ADTS frame Length
                    var frameLength = getFullFrameLength(data, offset);
                    if (frameLength <= headerLength) return false;
                    var newOffset = offset + frameLength;
                    if (newOffset === data.length || newOffset + 1 < data.length && isHeaderPattern(data, newOffset)) return true;
                }
                return false;
            }
            function initTrackConfig(track, observer, data, offset, audioCodec) {
                if (!track.samplerate) {
                    var config = getAudioConfig(observer, data, offset, audioCodec);
                    track.config = config.config;
                    track.samplerate = config.samplerate;
                    track.channelCount = config.channelCount;
                    track.codec = config.codec;
                    track.manifestCodec = config.manifestCodec;
                    logger["logger"].log("parsed codec:" + track.codec + ",rate:" + config.samplerate + ",nb channel:" + config.channelCount);
                }
            }
            function getFrameDuration(samplerate) {
                return 92160000 / samplerate;
            }
            function parseFrameHeader(data, offset, pts, frameIndex, frameDuration) {
                var headerLength, frameLength, stamp;
                var length = data.length; // The protection skip bit tells us if we have 2 bytes of CRC data at the end of the ADTS header
                headerLength = getHeaderLength(data, offset); // retrieve frame size
                frameLength = getFullFrameLength(data, offset);
                frameLength -= headerLength;
                if (frameLength > 0 && offset + headerLength + frameLength <= length) {
                    stamp = pts + frameIndex * frameDuration; // logger.log(`AAC frame, offset/length/total/pts:${offset+headerLength}/${frameLength}/${data.byteLength}/${(stamp/90).toFixed(0)}`);
                    return {
                        headerLength: headerLength,
                        frameLength: frameLength,
                        stamp: stamp
                    };
                }
                return undefined;
            }
            function appendFrame(track, data, offset, pts, frameIndex) {
                var frameDuration = getFrameDuration(track.samplerate);
                var header = parseFrameHeader(data, offset, pts, frameIndex, frameDuration);
                if (header) {
                    var stamp = header.stamp;
                    var headerLength = header.headerLength;
                    var frameLength = header.frameLength; // logger.log(`AAC frame, offset/length/total/pts:${offset+headerLength}/${frameLength}/${data.byteLength}/${(stamp/90).toFixed(0)}`);
                    var aacSample = {
                        unit: data.subarray(offset + headerLength, offset + headerLength + frameLength),
                        pts: stamp,
                        dts: stamp
                    };
                    track.samples.push(aacSample);
                    return {
                        sample: aacSample,
                        length: frameLength + headerLength
                    };
                }
                return undefined;
            }
            // EXTERNAL MODULE: ./src/demux/id3.js
            var id3 = __webpack_require__("./src/demux/id3.js");
            // CONCATENATED MODULE: ./src/demux/aacdemuxer.js
            /**
 * AAC demuxer
 */ var aacdemuxer_AACDemuxer = /*#__PURE__*/ function() {
                function AACDemuxer(observer, remuxer, config) {
                    this.observer = observer;
                    this.config = config;
                    this.remuxer = remuxer;
                }
                var _proto = AACDemuxer.prototype;
                _proto.resetInitSegment = function resetInitSegment(initSegment, audioCodec, videoCodec, duration) {
                    this._audioTrack = {
                        container: 'audio/adts',
                        type: 'audio',
                        id: 0,
                        sequenceNumber: 0,
                        isAAC: true,
                        samples: [],
                        len: 0,
                        manifestCodec: audioCodec,
                        duration: duration,
                        inputTimeScale: 90000
                    };
                };
                _proto.resetTimeStamp = function resetTimeStamp() {
                };
                AACDemuxer.probe = function probe(data) {
                    if (!data) return false;
                     // Check for the ADTS sync word
                    // Look for ADTS header | 1111 1111 | 1111 X00X | where X can be either 0 or 1
                    // Layer bits (position 14 and 15) in header should be always 0 for ADTS
                    // More info https://wiki.multimedia.cx/index.php?title=ADTS
                    var id3Data = id3["default"].getID3Data(data, 0) || [];
                    var offset = id3Data.length;
                    for(var length = data.length; offset < length; offset++)if (adts_probe(data, offset)) {
                        logger["logger"].log('ADTS sync word found !');
                        return true;
                    }
                    return false;
                } // feed incoming data to the front of the parsing pipeline
                ;
                _proto.append = function append(data, timeOffset, contiguous, accurateTimeOffset) {
                    var track = this._audioTrack;
                    var id3Data = id3["default"].getID3Data(data, 0) || [];
                    var timestamp = id3["default"].getTimeStamp(id3Data);
                    var pts = Object(number["isFiniteNumber"])(timestamp) ? timestamp * 90 : timeOffset * 90000;
                    var frameIndex = 0;
                    var stamp = pts;
                    var length = data.length;
                    var offset = id3Data.length;
                    var id3Samples = [
                        {
                            pts: stamp,
                            dts: stamp,
                            data: id3Data
                        }
                    ];
                    while(offset < length - 1){
                        if (isHeader(data, offset) && offset + 5 < length) {
                            initTrackConfig(track, this.observer, data, offset, track.manifestCodec);
                            var frame = appendFrame(track, data, offset, pts, frameIndex);
                            if (frame) {
                                offset += frame.length;
                                stamp = frame.sample.pts;
                                frameIndex++;
                            } else {
                                logger["logger"].log('Unable to parse AAC frame');
                                break;
                            }
                        } else if (id3["default"].isHeader(data, offset)) {
                            id3Data = id3["default"].getID3Data(data, offset);
                            id3Samples.push({
                                pts: stamp,
                                dts: stamp,
                                data: id3Data
                            });
                            offset += id3Data.length;
                        } else // nothing found, keep looking
                        offset++;
                    }
                    this.remuxer.remux(track, {
                        samples: []
                    }, {
                        samples: id3Samples,
                        inputTimeScale: 90000
                    }, {
                        samples: []
                    }, timeOffset, contiguous, accurateTimeOffset);
                };
                _proto.destroy = function destroy() {
                };
                return AACDemuxer;
            }();
            /* harmony default export */ var aacdemuxer = aacdemuxer_AACDemuxer;
            // EXTERNAL MODULE: ./src/demux/mp4demuxer.js
            var mp4demuxer = __webpack_require__("./src/demux/mp4demuxer.js");
            // CONCATENATED MODULE: ./src/demux/mpegaudio.js
            /**
 *  MPEG parser helper
 */ var MpegAudio = {
                BitratesMap: [
                    32,
                    64,
                    96,
                    128,
                    160,
                    192,
                    224,
                    256,
                    288,
                    320,
                    352,
                    384,
                    416,
                    448,
                    32,
                    48,
                    56,
                    64,
                    80,
                    96,
                    112,
                    128,
                    160,
                    192,
                    224,
                    256,
                    320,
                    384,
                    32,
                    40,
                    48,
                    56,
                    64,
                    80,
                    96,
                    112,
                    128,
                    160,
                    192,
                    224,
                    256,
                    320,
                    32,
                    48,
                    56,
                    64,
                    80,
                    96,
                    112,
                    128,
                    144,
                    160,
                    176,
                    192,
                    224,
                    256,
                    8,
                    16,
                    24,
                    32,
                    40,
                    48,
                    56,
                    64,
                    80,
                    96,
                    112,
                    128,
                    144,
                    160
                ],
                SamplingRateMap: [
                    44100,
                    48000,
                    32000,
                    22050,
                    24000,
                    16000,
                    11025,
                    12000,
                    8000
                ],
                SamplesCoefficients: [
                    [
                        0,
                        72,
                        144,
                        12 // Layer1
                    ],
                    [
                        0,
                        0,
                        0,
                        0 // Layer1
                    ],
                    [
                        0,
                        72,
                        144,
                        12 // Layer1
                    ],
                    [
                        0,
                        144,
                        144,
                        12 // Layer1
                    ]
                ],
                BytesInSlot: [
                    0,
                    1,
                    1,
                    4 // Layer1
                ],
                appendFrame: function appendFrame(track, data, offset, pts, frameIndex) {
                    // Using http://www.datavoyage.com/mpgscript/mpeghdr.htm as a reference
                    if (offset + 24 > data.length) return undefined;
                    var header = this.parseHeader(data, offset);
                    if (header && offset + header.frameLength <= data.length) {
                        var frameDuration = header.samplesPerFrame * 90000 / header.sampleRate;
                        var stamp = pts + frameIndex * frameDuration;
                        var sample = {
                            unit: data.subarray(offset, offset + header.frameLength),
                            pts: stamp,
                            dts: stamp
                        };
                        track.config = [];
                        track.channelCount = header.channelCount;
                        track.samplerate = header.sampleRate;
                        track.samples.push(sample);
                        return {
                            sample: sample,
                            length: header.frameLength
                        };
                    }
                    return undefined;
                },
                parseHeader: function parseHeader(data, offset) {
                    var headerB = data[offset + 1] >> 3 & 3;
                    var headerC = data[offset + 1] >> 1 & 3;
                    var headerE = data[offset + 2] >> 4 & 15;
                    var headerF = data[offset + 2] >> 2 & 3;
                    var headerG = data[offset + 2] >> 1 & 1;
                    if (headerB !== 1 && headerE !== 0 && headerE !== 15 && headerF !== 3) {
                        var columnInBitrates = headerB === 3 ? 3 - headerC : headerC === 3 ? 3 : 4;
                        var bitRate = MpegAudio.BitratesMap[columnInBitrates * 14 + headerE - 1] * 1000;
                        var columnInSampleRates = headerB === 3 ? 0 : headerB === 2 ? 1 : 2;
                        var sampleRate = MpegAudio.SamplingRateMap[columnInSampleRates * 3 + headerF];
                        var channelCount = data[offset + 3] >> 6 === 3 ? 1 : 2; // If bits of channel mode are `11` then it is a single channel (Mono)
                        var sampleCoefficient = MpegAudio.SamplesCoefficients[headerB][headerC];
                        var bytesInSlot = MpegAudio.BytesInSlot[headerC];
                        var samplesPerFrame = sampleCoefficient * 8 * bytesInSlot;
                        var frameLength = parseInt(sampleCoefficient * bitRate / sampleRate + headerG, 10) * bytesInSlot;
                        return {
                            sampleRate: sampleRate,
                            channelCount: channelCount,
                            frameLength: frameLength,
                            samplesPerFrame: samplesPerFrame
                        };
                    }
                    return undefined;
                },
                isHeaderPattern: function isHeaderPattern(data, offset) {
                    return data[offset] === 255 && (data[offset + 1] & 224) === 224 && (data[offset + 1] & 6) !== 0;
                },
                isHeader: function isHeader(data, offset) {
                    // Look for MPEG header | 1111 1111 | 111X XYZX | where X can be either 0 or 1 and Y or Z should be 1
                    // Layer bits (position 14 and 15) in header should be always different from 0 (Layer I or Layer II or Layer III)
                    // More info http://www.mp3-tech.org/programmer/frame_header.html
                    if (offset + 1 < data.length && this.isHeaderPattern(data, offset)) return true;
                    return false;
                },
                probe: function probe(data, offset) {
                    // same as isHeader but we also check that MPEG frame follows last MPEG frame
                    // or end of data is reached
                    if (offset + 1 < data.length && this.isHeaderPattern(data, offset)) {
                        // MPEG header Length
                        var headerLength = 4; // MPEG frame Length
                        var header = this.parseHeader(data, offset);
                        var frameLength = headerLength;
                        if (header && header.frameLength) frameLength = header.frameLength;
                        var newOffset = offset + frameLength;
                        if (newOffset === data.length || newOffset + 1 < data.length && this.isHeaderPattern(data, newOffset)) return true;
                    }
                    return false;
                }
            };
            /* harmony default export */ var mpegaudio = MpegAudio;
            // CONCATENATED MODULE: ./src/demux/exp-golomb.js
            /**
 * Parser for exponential Golomb codes, a variable-bitwidth number encoding scheme used by h264.
*/ var exp_golomb_ExpGolomb = /*#__PURE__*/ function() {
                function ExpGolomb(data) {
                    this.data = data; // the number of bytes left to examine in this.data
                    this.bytesAvailable = data.byteLength; // the current word being examined
                    this.word = 0; // :uint
                    // the number of bits left to examine in the current word
                    this.bitsAvailable = 0; // :uint
                } // ():void
                var _proto = ExpGolomb.prototype;
                _proto.loadWord = function loadWord() {
                    var data = this.data, bytesAvailable = this.bytesAvailable, position = data.byteLength - bytesAvailable, workingBytes = new Uint8Array(4), availableBytes = Math.min(4, bytesAvailable);
                    if (availableBytes === 0) throw new Error('no bytes available');
                    workingBytes.set(data.subarray(position, position + availableBytes));
                    this.word = new DataView(workingBytes.buffer).getUint32(0); // track the amount of this.data that has been processed
                    this.bitsAvailable = availableBytes * 8;
                    this.bytesAvailable -= availableBytes;
                } // (count:int):void
                ;
                _proto.skipBits = function skipBits(count) {
                    var skipBytes; // :int
                    if (this.bitsAvailable > count) {
                        this.word <<= count;
                        this.bitsAvailable -= count;
                    } else {
                        count -= this.bitsAvailable;
                        skipBytes = count >> 3;
                        count -= skipBytes >> 3;
                        this.bytesAvailable -= skipBytes;
                        this.loadWord();
                        this.word <<= count;
                        this.bitsAvailable -= count;
                    }
                } // (size:int):uint
                ;
                _proto.readBits = function readBits(size) {
                    var bits = Math.min(this.bitsAvailable, size), // :uint
                    valu = this.word >>> 32 - bits; // :uint
                    if (size > 32) logger["logger"].error('Cannot read more than 32 bits at a time');
                    this.bitsAvailable -= bits;
                    if (this.bitsAvailable > 0) this.word <<= bits;
                    else if (this.bytesAvailable > 0) this.loadWord();
                    bits = size - bits;
                    if (bits > 0 && this.bitsAvailable) return valu << bits | this.readBits(bits);
                    else return valu;
                } // ():uint
                ;
                _proto.skipLZ = function skipLZ() {
                    var leadingZeroCount; // :uint
                    for(leadingZeroCount = 0; leadingZeroCount < this.bitsAvailable; ++leadingZeroCount)if ((this.word & 2147483648 >>> leadingZeroCount) !== 0) {
                        // the first bit of working word is 1
                        this.word <<= leadingZeroCount;
                        this.bitsAvailable -= leadingZeroCount;
                        return leadingZeroCount;
                    }
                     // we exhausted word and still have not found a 1
                    this.loadWord();
                    return leadingZeroCount + this.skipLZ();
                } // ():void
                ;
                _proto.skipUEG = function skipUEG() {
                    this.skipBits(1 + this.skipLZ());
                } // ():void
                ;
                _proto.skipEG = function skipEG() {
                    this.skipBits(1 + this.skipLZ());
                } // ():uint
                ;
                _proto.readUEG = function readUEG() {
                    var clz = this.skipLZ(); // :uint
                    return this.readBits(clz + 1) - 1;
                } // ():int
                ;
                _proto.readEG = function readEG() {
                    var valu = this.readUEG(); // :int
                    if (1 & valu) // the number is odd if the low order bit is set
                    return 1 + valu >>> 1; // add 1 to make it even, and divide by 2
                    else return -1 * (valu >>> 1); // divide by two then make it negative
                } // Some convenience functions
                ;
                _proto.readBoolean = function readBoolean() {
                    return this.readBits(1) === 1;
                } // ():int
                ;
                _proto.readUByte = function readUByte() {
                    return this.readBits(8);
                } // ():int
                ;
                _proto.readUShort = function readUShort() {
                    return this.readBits(16);
                } // ():int
                ;
                _proto.readUInt = function readUInt() {
                    return this.readBits(32);
                };
                _proto.skipScalingList = function skipScalingList(count) {
                    var lastScale = 8, nextScale = 8, j, deltaScale;
                    for(j = 0; j < count; j++){
                        if (nextScale !== 0) {
                            deltaScale = this.readEG();
                            nextScale = (lastScale + deltaScale + 256) % 256;
                        }
                        lastScale = nextScale === 0 ? lastScale : nextScale;
                    }
                };
                _proto.readSPS = function readSPS() {
                    var frameCropLeftOffset = 0, frameCropRightOffset = 0, frameCropTopOffset = 0, frameCropBottomOffset = 0, profileIdc, profileCompat, levelIdc, numRefFramesInPicOrderCntCycle, picWidthInMbsMinus1, picHeightInMapUnitsMinus1, frameMbsOnlyFlag, scalingListCount, i, readUByte = this.readUByte.bind(this), readBits = this.readBits.bind(this), readUEG = this.readUEG.bind(this), readBoolean = this.readBoolean.bind(this), skipBits = this.skipBits.bind(this), skipEG = this.skipEG.bind(this), skipUEG = this.skipUEG.bind(this), skipScalingList = this.skipScalingList.bind(this);
                    readUByte();
                    profileIdc = readUByte(); // profile_idc
                    profileCompat = readBits(5); // constraint_set[0-4]_flag, u(5)
                    skipBits(3); // reserved_zero_3bits u(3),
                    levelIdc = readUByte(); // level_idc u(8)
                    skipUEG(); // seq_parameter_set_id
                    // some profiles have more optional data we don't need
                    if (profileIdc === 100 || profileIdc === 110 || profileIdc === 122 || profileIdc === 244 || profileIdc === 44 || profileIdc === 83 || profileIdc === 86 || profileIdc === 118 || profileIdc === 128) {
                        var chromaFormatIdc = readUEG();
                        if (chromaFormatIdc === 3) skipBits(1);
                         // separate_colour_plane_flag
                        skipUEG(); // bit_depth_luma_minus8
                        skipUEG(); // bit_depth_chroma_minus8
                        skipBits(1); // qpprime_y_zero_transform_bypass_flag
                        if (readBoolean()) {
                            // seq_scaling_matrix_present_flag
                            scalingListCount = chromaFormatIdc !== 3 ? 8 : 12;
                            for(i = 0; i < scalingListCount; i++)if (readBoolean()) {
                                // seq_scaling_list_present_flag[ i ]
                                if (i < 6) skipScalingList(16);
                                else skipScalingList(64);
                            }
                        }
                    }
                    skipUEG(); // log2_max_frame_num_minus4
                    var picOrderCntType = readUEG();
                    if (picOrderCntType === 0) readUEG(); // log2_max_pic_order_cnt_lsb_minus4
                    else if (picOrderCntType === 1) {
                        skipBits(1); // delta_pic_order_always_zero_flag
                        skipEG(); // offset_for_non_ref_pic
                        skipEG(); // offset_for_top_to_bottom_field
                        numRefFramesInPicOrderCntCycle = readUEG();
                        for(i = 0; i < numRefFramesInPicOrderCntCycle; i++)skipEG();
                         // offset_for_ref_frame[ i ]
                    }
                    skipUEG(); // max_num_ref_frames
                    skipBits(1); // gaps_in_frame_num_value_allowed_flag
                    picWidthInMbsMinus1 = readUEG();
                    picHeightInMapUnitsMinus1 = readUEG();
                    frameMbsOnlyFlag = readBits(1);
                    if (frameMbsOnlyFlag === 0) skipBits(1);
                     // mb_adaptive_frame_field_flag
                    skipBits(1); // direct_8x8_inference_flag
                    if (readBoolean()) {
                        // frame_cropping_flag
                        frameCropLeftOffset = readUEG();
                        frameCropRightOffset = readUEG();
                        frameCropTopOffset = readUEG();
                        frameCropBottomOffset = readUEG();
                    }
                    var pixelRatio = [
                        1,
                        1
                    ];
                    if (readBoolean()) // vui_parameters_present_flag
                    {
                        if (readBoolean()) {
                            // aspect_ratio_info_present_flag
                            var aspectRatioIdc = readUByte();
                            switch(aspectRatioIdc){
                                case 1:
                                    pixelRatio = [
                                        1,
                                        1
                                    ];
                                    break;
                                case 2:
                                    pixelRatio = [
                                        12,
                                        11
                                    ];
                                    break;
                                case 3:
                                    pixelRatio = [
                                        10,
                                        11
                                    ];
                                    break;
                                case 4:
                                    pixelRatio = [
                                        16,
                                        11
                                    ];
                                    break;
                                case 5:
                                    pixelRatio = [
                                        40,
                                        33
                                    ];
                                    break;
                                case 6:
                                    pixelRatio = [
                                        24,
                                        11
                                    ];
                                    break;
                                case 7:
                                    pixelRatio = [
                                        20,
                                        11
                                    ];
                                    break;
                                case 8:
                                    pixelRatio = [
                                        32,
                                        11
                                    ];
                                    break;
                                case 9:
                                    pixelRatio = [
                                        80,
                                        33
                                    ];
                                    break;
                                case 10:
                                    pixelRatio = [
                                        18,
                                        11
                                    ];
                                    break;
                                case 11:
                                    pixelRatio = [
                                        15,
                                        11
                                    ];
                                    break;
                                case 12:
                                    pixelRatio = [
                                        64,
                                        33
                                    ];
                                    break;
                                case 13:
                                    pixelRatio = [
                                        160,
                                        99
                                    ];
                                    break;
                                case 14:
                                    pixelRatio = [
                                        4,
                                        3
                                    ];
                                    break;
                                case 15:
                                    pixelRatio = [
                                        3,
                                        2
                                    ];
                                    break;
                                case 16:
                                    pixelRatio = [
                                        2,
                                        1
                                    ];
                                    break;
                                case 255:
                                    pixelRatio = [
                                        readUByte() << 8 | readUByte(),
                                        readUByte() << 8 | readUByte()
                                    ];
                                    break;
                            }
                        }
                    }
                    return {
                        width: Math.ceil((picWidthInMbsMinus1 + 1) * 16 - frameCropLeftOffset * 2 - frameCropRightOffset * 2),
                        height: (2 - frameMbsOnlyFlag) * (picHeightInMapUnitsMinus1 + 1) * 16 - (frameMbsOnlyFlag ? 2 : 4) * (frameCropTopOffset + frameCropBottomOffset),
                        pixelRatio: pixelRatio
                    };
                };
                _proto.readSliceType = function readSliceType() {
                    // skip NALu type
                    this.readUByte(); // discard first_mb_in_slice
                    this.readUEG(); // return slice_type
                    return this.readUEG();
                };
                return ExpGolomb;
            }();
            /* harmony default export */ var exp_golomb = exp_golomb_ExpGolomb;
            // CONCATENATED MODULE: ./src/demux/sample-aes.js
            /**
 * SAMPLE-AES decrypter
*/ var sample_aes_SampleAesDecrypter = /*#__PURE__*/ function() {
                function SampleAesDecrypter(observer, config, decryptdata, discardEPB) {
                    this.decryptdata = decryptdata;
                    this.discardEPB = discardEPB;
                    this.decrypter = new crypt_decrypter["default"](observer, config, {
                        removePKCS7Padding: false
                    });
                }
                var _proto = SampleAesDecrypter.prototype;
                _proto.decryptBuffer = function decryptBuffer(encryptedData, callback) {
                    this.decrypter.decrypt(encryptedData, this.decryptdata.key.buffer, this.decryptdata.iv.buffer, callback);
                } // AAC - encrypt all full 16 bytes blocks starting from offset 16
                ;
                _proto.decryptAacSample = function decryptAacSample(samples, sampleIndex, callback, sync) {
                    var curUnit = samples[sampleIndex].unit;
                    var encryptedData = curUnit.subarray(16, curUnit.length - curUnit.length % 16);
                    var encryptedBuffer = encryptedData.buffer.slice(encryptedData.byteOffset, encryptedData.byteOffset + encryptedData.length);
                    var localthis = this;
                    this.decryptBuffer(encryptedBuffer, function(decryptedData) {
                        decryptedData = new Uint8Array(decryptedData);
                        curUnit.set(decryptedData, 16);
                        if (!sync) localthis.decryptAacSamples(samples, sampleIndex + 1, callback);
                    });
                };
                _proto.decryptAacSamples = function decryptAacSamples(samples, sampleIndex, callback) {
                    for(;; sampleIndex++){
                        if (sampleIndex >= samples.length) {
                            callback();
                            return;
                        }
                        if (samples[sampleIndex].unit.length < 32) continue;
                        var sync = this.decrypter.isSync();
                        this.decryptAacSample(samples, sampleIndex, callback, sync);
                        if (!sync) return;
                    }
                } // AVC - encrypt one 16 bytes block out of ten, starting from offset 32
                ;
                _proto.getAvcEncryptedData = function getAvcEncryptedData(decodedData) {
                    var encryptedDataLen = Math.floor((decodedData.length - 48) / 160) * 16 + 16;
                    var encryptedData = new Int8Array(encryptedDataLen);
                    var outputPos = 0;
                    for(var inputPos = 32; inputPos <= decodedData.length - 16; inputPos += 160, outputPos += 16)encryptedData.set(decodedData.subarray(inputPos, inputPos + 16), outputPos);
                    return encryptedData;
                };
                _proto.getAvcDecryptedUnit = function getAvcDecryptedUnit(decodedData, decryptedData) {
                    decryptedData = new Uint8Array(decryptedData);
                    var inputPos = 0;
                    for(var outputPos = 32; outputPos <= decodedData.length - 16; outputPos += 160, inputPos += 16)decodedData.set(decryptedData.subarray(inputPos, inputPos + 16), outputPos);
                    return decodedData;
                };
                _proto.decryptAvcSample = function decryptAvcSample(samples, sampleIndex, unitIndex, callback, curUnit, sync) {
                    var decodedData = this.discardEPB(curUnit.data);
                    var encryptedData = this.getAvcEncryptedData(decodedData);
                    var localthis = this;
                    this.decryptBuffer(encryptedData.buffer, function(decryptedData) {
                        curUnit.data = localthis.getAvcDecryptedUnit(decodedData, decryptedData);
                        if (!sync) localthis.decryptAvcSamples(samples, sampleIndex, unitIndex + 1, callback);
                    });
                };
                _proto.decryptAvcSamples = function decryptAvcSamples(samples, sampleIndex, unitIndex, callback) {
                    for(;; sampleIndex++, unitIndex = 0){
                        if (sampleIndex >= samples.length) {
                            callback();
                            return;
                        }
                        var curUnits = samples[sampleIndex].units;
                        for(;; unitIndex++){
                            if (unitIndex >= curUnits.length) break;
                            var curUnit = curUnits[unitIndex];
                            if (curUnit.data.length <= 48 || curUnit.type !== 1 && curUnit.type !== 5) continue;
                            var sync = this.decrypter.isSync();
                            this.decryptAvcSample(samples, sampleIndex, unitIndex, callback, curUnit, sync);
                            if (!sync) return;
                        }
                    }
                };
                return SampleAesDecrypter;
            }();
            /* harmony default export */ var sample_aes = sample_aes_SampleAesDecrypter;
            // CONCATENATED MODULE: ./src/demux/tsdemuxer.js
            /**
 * highly optimized TS demuxer:
 * parse PAT, PMT
 * extract PES packet from audio and video PIDs
 * extract AVC/H264 NAL units and AAC/ADTS samples from PES packet
 * trigger the remuxer upon parsing completion
 * it also tries to workaround as best as it can audio codec switch (HE-AAC to AAC and vice versa), without having to restart the MediaSource.
 * it also controls the remuxing process :
 * upon discontinuity or level switch detection, it will also notifies the remuxer so that it can reset its state.
*/ // import Hex from '../utils/hex';
            // We are using fixed track IDs for driving the MP4 remuxer
            // instead of following the TS PIDs.
            // There is no reason not to do this and some browsers/SourceBuffer-demuxers
            // may not like if there are TrackID "switches"
            // See https://github.com/video-dev/hls.js/issues/1331
            // Here we are mapping our internal track types to constant MP4 track IDs
            // With MSE currently one can only have one track of each, and we are muxing
            // whatever video/audio rendition in them.
            var RemuxerTrackIdConfig = {
                video: 1,
                audio: 2,
                id3: 3,
                text: 4
            };
            var tsdemuxer_TSDemuxer = /*#__PURE__*/ function() {
                function TSDemuxer(observer, remuxer, config, typeSupported) {
                    this.observer = observer;
                    this.config = config;
                    this.typeSupported = typeSupported;
                    this.remuxer = remuxer;
                    this.sampleAes = null;
                    this.pmtUnknownTypes = {
                    };
                }
                var _proto = TSDemuxer.prototype;
                _proto.setDecryptData = function setDecryptData(decryptdata) {
                    if (decryptdata != null && decryptdata.key != null && decryptdata.method === 'SAMPLE-AES') this.sampleAes = new sample_aes(this.observer, this.config, decryptdata, this.discardEPB);
                    else this.sampleAes = null;
                };
                TSDemuxer.probe = function probe(data) {
                    var syncOffset = TSDemuxer._syncOffset(data);
                    if (syncOffset < 0) return false;
                    else {
                        if (syncOffset) logger["logger"].warn("MPEG2-TS detected but first sync word found @ offset " + syncOffset + ", junk ahead ?");
                        return true;
                    }
                };
                TSDemuxer._syncOffset = function _syncOffset(data) {
                    // scan 1000 first bytes
                    var scanwindow = Math.min(1000, data.length - 564);
                    var i = 0;
                    while(i < scanwindow){
                        // a TS fragment should contain at least 3 TS packets, a PAT, a PMT, and one PID, each starting with 0x47
                        if (data[i] === 71 && data[i + 188] === 71 && data[i + 376] === 71) return i;
                        else i++;
                    }
                    return -1;
                };
                TSDemuxer.createTrack = function createTrack(type, duration) {
                    return {
                        container: type === 'video' || type === 'audio' ? 'video/mp2t' : undefined,
                        type: type,
                        id: RemuxerTrackIdConfig[type],
                        pid: -1,
                        inputTimeScale: 90000,
                        sequenceNumber: 0,
                        samples: [],
                        dropped: type === 'video' ? 0 : undefined,
                        isAAC: type === 'audio' ? true : undefined,
                        duration: type === 'audio' ? duration : undefined
                    };
                };
                _proto.resetInitSegment = function resetInitSegment(initSegment, audioCodec, videoCodec, duration) {
                    this.pmtParsed = false;
                    this._pmtId = -1;
                    this.pmtUnknownTypes = {
                    };
                    this._avcTrack = TSDemuxer.createTrack('video', duration);
                    this._audioTrack = TSDemuxer.createTrack('audio', duration);
                    this._id3Track = TSDemuxer.createTrack('id3', duration);
                    this._txtTrack = TSDemuxer.createTrack('text', duration); // flush any partial content
                    this.aacOverFlow = null;
                    this.aacLastPTS = null;
                    this.avcSample = null;
                    this.audioCodec = audioCodec;
                    this.videoCodec = videoCodec;
                    this._duration = duration;
                };
                _proto.resetTimeStamp = function resetTimeStamp() {
                } // feed incoming data to the front of the parsing pipeline
                ;
                _proto.append = function append(data, timeOffset, contiguous, accurateTimeOffset) {
                    var start, len = data.length, stt, pid, atf, offset, pes, unknownPIDs = false;
                    this.pmtUnknownTypes = {
                    };
                    this.contiguous = contiguous;
                    var pmtParsed = this.pmtParsed, avcTrack = this._avcTrack, audioTrack = this._audioTrack, id3Track = this._id3Track, avcId = avcTrack.pid, audioId = audioTrack.pid, id3Id = id3Track.pid, pmtId = this._pmtId, avcData = avcTrack.pesData, audioData = audioTrack.pesData, id3Data = id3Track.pesData, parsePAT = this._parsePAT, parsePMT = this._parsePMT.bind(this), parsePES = this._parsePES, parseAVCPES = this._parseAVCPES.bind(this), parseAACPES = this._parseAACPES.bind(this), parseMPEGPES = this._parseMPEGPES.bind(this), parseID3PES = this._parseID3PES.bind(this);
                    var syncOffset = TSDemuxer._syncOffset(data); // don't parse last TS packet if incomplete
                    len -= (len + syncOffset) % 188; // loop through TS packets
                    for(start = syncOffset; start < len; start += 188)if (data[start] === 71) {
                        stt = !!(data[start + 1] & 64); // pid is a 13-bit field starting at the last bit of TS[1]
                        pid = ((data[start + 1] & 31) << 8) + data[start + 2];
                        atf = (data[start + 3] & 48) >> 4; // if an adaption field is present, its length is specified by the fifth byte of the TS packet header.
                        if (atf > 1) {
                            offset = start + 5 + data[start + 4]; // continue if there is only adaptation field
                            if (offset === start + 188) continue;
                        } else offset = start + 4;
                        switch(pid){
                            case avcId:
                                if (stt) {
                                    if (avcData && (pes = parsePES(avcData))) parseAVCPES(pes, false);
                                    avcData = {
                                        data: [],
                                        size: 0
                                    };
                                }
                                if (avcData) {
                                    avcData.data.push(data.subarray(offset, start + 188));
                                    avcData.size += start + 188 - offset;
                                }
                                break;
                            case audioId:
                                if (stt) {
                                    if (audioData && (pes = parsePES(audioData))) {
                                        if (audioTrack.isAAC) parseAACPES(pes);
                                        else parseMPEGPES(pes);
                                    }
                                    audioData = {
                                        data: [],
                                        size: 0
                                    };
                                }
                                if (audioData) {
                                    audioData.data.push(data.subarray(offset, start + 188));
                                    audioData.size += start + 188 - offset;
                                }
                                break;
                            case id3Id:
                                if (stt) {
                                    if (id3Data && (pes = parsePES(id3Data))) parseID3PES(pes);
                                    id3Data = {
                                        data: [],
                                        size: 0
                                    };
                                }
                                if (id3Data) {
                                    id3Data.data.push(data.subarray(offset, start + 188));
                                    id3Data.size += start + 188 - offset;
                                }
                                break;
                            case 0:
                                if (stt) offset += data[offset] + 1;
                                pmtId = this._pmtId = parsePAT(data, offset);
                                break;
                            case pmtId:
                                if (stt) offset += data[offset] + 1;
                                var parsedPIDs = parsePMT(data, offset, this.typeSupported.mpeg === true || this.typeSupported.mp3 === true, this.sampleAes != null); // only update track id if track PID found while parsing PMT
                                // this is to avoid resetting the PID to -1 in case
                                // track PID transiently disappears from the stream
                                // this could happen in case of transient missing audio samples for example
                                // NOTE this is only the PID of the track as found in TS,
                                // but we are not using this for MP4 track IDs.
                                avcId = parsedPIDs.avc;
                                if (avcId > 0) avcTrack.pid = avcId;
                                audioId = parsedPIDs.audio;
                                if (audioId > 0) {
                                    audioTrack.pid = audioId;
                                    audioTrack.isAAC = parsedPIDs.isAAC;
                                }
                                id3Id = parsedPIDs.id3;
                                if (id3Id > 0) id3Track.pid = id3Id;
                                if (unknownPIDs && !pmtParsed) {
                                    logger["logger"].log('reparse from beginning');
                                    unknownPIDs = false; // we set it to -188, the += 188 in the for loop will reset start to 0
                                    start = syncOffset - 188;
                                }
                                pmtParsed = this.pmtParsed = true;
                                break;
                            case 17:
                            case 8191:
                                break;
                            default:
                                unknownPIDs = true;
                                break;
                        }
                    } else this.observer.trigger(events["default"].ERROR, {
                        type: errors["ErrorTypes"].MEDIA_ERROR,
                        details: errors["ErrorDetails"].FRAG_PARSING_ERROR,
                        fatal: false,
                        reason: 'TS packet did not start with 0x47'
                    });
                     // try to parse last PES packets
                    if (avcData && (pes = parsePES(avcData))) {
                        parseAVCPES(pes, true);
                        avcTrack.pesData = null;
                    } else // either avcData null or PES truncated, keep it for next frag parsing
                    avcTrack.pesData = avcData;
                    if (audioData && (pes = parsePES(audioData))) {
                        if (audioTrack.isAAC) parseAACPES(pes);
                        else parseMPEGPES(pes);
                        audioTrack.pesData = null;
                    } else {
                        if (audioData && audioData.size) logger["logger"].log('last AAC PES packet truncated,might overlap between fragments');
                         // either audioData null or PES truncated, keep it for next frag parsing
                        audioTrack.pesData = audioData;
                    }
                    if (id3Data && (pes = parsePES(id3Data))) {
                        parseID3PES(pes);
                        id3Track.pesData = null;
                    } else // either id3Data null or PES truncated, keep it for next frag parsing
                    id3Track.pesData = id3Data;
                    if (this.sampleAes == null) this.remuxer.remux(audioTrack, avcTrack, id3Track, this._txtTrack, timeOffset, contiguous, accurateTimeOffset);
                    else this.decryptAndRemux(audioTrack, avcTrack, id3Track, this._txtTrack, timeOffset, contiguous, accurateTimeOffset);
                };
                _proto.decryptAndRemux = function decryptAndRemux(audioTrack, videoTrack, id3Track, textTrack, timeOffset, contiguous, accurateTimeOffset) {
                    if (audioTrack.samples && audioTrack.isAAC) {
                        var localthis = this;
                        this.sampleAes.decryptAacSamples(audioTrack.samples, 0, function() {
                            localthis.decryptAndRemuxAvc(audioTrack, videoTrack, id3Track, textTrack, timeOffset, contiguous, accurateTimeOffset);
                        });
                    } else this.decryptAndRemuxAvc(audioTrack, videoTrack, id3Track, textTrack, timeOffset, contiguous, accurateTimeOffset);
                };
                _proto.decryptAndRemuxAvc = function decryptAndRemuxAvc(audioTrack, videoTrack, id3Track, textTrack, timeOffset, contiguous, accurateTimeOffset) {
                    if (videoTrack.samples) {
                        var localthis = this;
                        this.sampleAes.decryptAvcSamples(videoTrack.samples, 0, 0, function() {
                            localthis.remuxer.remux(audioTrack, videoTrack, id3Track, textTrack, timeOffset, contiguous, accurateTimeOffset);
                        });
                    } else this.remuxer.remux(audioTrack, videoTrack, id3Track, textTrack, timeOffset, contiguous, accurateTimeOffset);
                };
                _proto.destroy = function destroy() {
                    this._initPTS = this._initDTS = undefined;
                    this._duration = 0;
                };
                _proto._parsePAT = function _parsePAT(data, offset) {
                    // skip the PSI header and parse the first PMT entry
                    return (data[offset + 10] & 31) << 8 | data[offset + 11]; // logger.log('PMT PID:'  + this._pmtId);
                };
                _proto._trackUnknownPmt = function _trackUnknownPmt(type, logLevel, message) {
                    // Only log unknown and unsupported stream types once per append or stream (by resetting this.pmtUnknownTypes)
                    // For more information on elementary stream types see:
                    // https://en.wikipedia.org/wiki/Program-specific_information#Elementary_stream_types
                    var result = this.pmtUnknownTypes[type] || 0;
                    if (result === 0) {
                        this.pmtUnknownTypes[type] = 0;
                        logLevel.call(logger["logger"], message);
                    }
                    this.pmtUnknownTypes[type]++;
                    return result;
                };
                _proto._parsePMT = function _parsePMT(data, offset, mpegSupported, isSampleAes) {
                    var sectionLength, tableEnd, programInfoLength, pid, result = {
                        audio: -1,
                        avc: -1,
                        id3: -1,
                        isAAC: true
                    };
                    sectionLength = (data[offset + 1] & 15) << 8 | data[offset + 2];
                    tableEnd = offset + 3 + sectionLength - 4; // to determine where the table is, we have to figure out how
                    // long the program info descriptors are
                    programInfoLength = (data[offset + 10] & 15) << 8 | data[offset + 11]; // advance the offset to the first entry in the mapping table
                    offset += 12 + programInfoLength;
                    while(offset < tableEnd){
                        pid = (data[offset + 1] & 31) << 8 | data[offset + 2];
                        switch(data[offset]){
                            case 207:
                                // SAMPLE-AES AAC
                                if (!isSampleAes) {
                                    this._trackUnknownPmt(data[offset], logger["logger"].warn, 'ADTS AAC with AES-128-CBC frame encryption found in unencrypted stream');
                                    break;
                                }
                            /* falls through */ // ISO/IEC 13818-7 ADTS AAC (MPEG-2 lower bit-rate audio)
                            case 15:
                                // logger.log('AAC PID:'  + pid);
                                if (result.audio === -1) result.audio = pid;
                                break;
                            // Packetized metadata (ID3)
                            case 21:
                                // logger.log('ID3 PID:'  + pid);
                                if (result.id3 === -1) result.id3 = pid;
                                break;
                            case 219:
                                // SAMPLE-AES AVC
                                if (!isSampleAes) {
                                    this._trackUnknownPmt(data[offset], logger["logger"].warn, 'H.264 with AES-128-CBC slice encryption found in unencrypted stream');
                                    break;
                                }
                            /* falls through */ // ITU-T Rec. H.264 and ISO/IEC 14496-10 (lower bit-rate video)
                            case 27:
                                // logger.log('AVC PID:'  + pid);
                                if (result.avc === -1) result.avc = pid;
                                break;
                            // ISO/IEC 11172-3 (MPEG-1 audio)
                            // or ISO/IEC 13818-3 (MPEG-2 halved sample rate audio)
                            case 3:
                            case 4:
                                // logger.log('MPEG PID:'  + pid);
                                if (!mpegSupported) this._trackUnknownPmt(data[offset], logger["logger"].warn, 'MPEG audio found, not supported in this browser');
                                else if (result.audio === -1) {
                                    result.audio = pid;
                                    result.isAAC = false;
                                }
                                break;
                            case 36:
                                this._trackUnknownPmt(data[offset], logger["logger"].warn, 'Unsupported HEVC stream type found');
                                break;
                            default:
                                this._trackUnknownPmt(data[offset], logger["logger"].log, 'Unknown stream type:' + data[offset]);
                                break;
                        } // move to the next table entry
                        // skip past the elementary stream descriptors, if present
                        offset += ((data[offset + 3] & 15) << 8 | data[offset + 4]) + 5;
                    }
                    return result;
                };
                _proto._parsePES = function _parsePES(stream) {
                    var i = 0, frag, pesFlags, pesPrefix, pesLen, pesHdrLen, pesData, pesPts, pesDts, payloadStartOffset, data = stream.data; // safety check
                    if (!stream || stream.size === 0) return null;
                     // we might need up to 19 bytes to read PES header
                    // if first chunk of data is less than 19 bytes, let's merge it with following ones until we get 19 bytes
                    // usually only one merge is needed (and this is rare ...)
                    while(data[0].length < 19 && data.length > 1){
                        var newData = new Uint8Array(data[0].length + data[1].length);
                        newData.set(data[0]);
                        newData.set(data[1], data[0].length);
                        data[0] = newData;
                        data.splice(1, 1);
                    } // retrieve PTS/DTS from first fragment
                    frag = data[0];
                    pesPrefix = (frag[0] << 16) + (frag[1] << 8) + frag[2];
                    if (pesPrefix === 1) {
                        pesLen = (frag[4] << 8) + frag[5]; // if PES parsed length is not zero and greater than total received length, stop parsing. PES might be truncated
                        // minus 6 : PES header size
                        if (pesLen && pesLen > stream.size - 6) return null;
                        pesFlags = frag[7];
                        if (pesFlags & 192) {
                            /* PES header described here : http://dvd.sourceforge.net/dvdinfo/pes-hdr.html
            as PTS / DTS is 33 bit we cannot use bitwise operator in JS,
            as Bitwise operators treat their operands as a sequence of 32 bits */ pesPts = (frag[9] & 14) * 536870912 + (frag[10] & 255) * 4194304 + (frag[11] & 254) * 16384 + (frag[12] & 255) * 128 + (frag[13] & 254) / 2;
                            if (pesFlags & 64) {
                                pesDts = (frag[14] & 14) * 536870912 + (frag[15] & 255) * 4194304 + (frag[16] & 254) * 16384 + (frag[17] & 255) * 128 + (frag[18] & 254) / 2;
                                if (pesPts - pesDts > 5400000) {
                                    logger["logger"].warn(Math.round((pesPts - pesDts) / 90000) + "s delta between PTS and DTS, align them");
                                    pesPts = pesDts;
                                }
                            } else pesDts = pesPts;
                        }
                        pesHdrLen = frag[8]; // 9 bytes : 6 bytes for PES header + 3 bytes for PES extension
                        payloadStartOffset = pesHdrLen + 9;
                        if (stream.size <= payloadStartOffset) return null;
                        stream.size -= payloadStartOffset; // reassemble PES packet
                        pesData = new Uint8Array(stream.size);
                        for(var j = 0, dataLen = data.length; j < dataLen; j++){
                            frag = data[j];
                            var len = frag.byteLength;
                            if (payloadStartOffset) {
                                if (payloadStartOffset > len) {
                                    // trim full frag if PES header bigger than frag
                                    payloadStartOffset -= len;
                                    continue;
                                } else {
                                    // trim partial frag if PES header smaller than frag
                                    frag = frag.subarray(payloadStartOffset);
                                    len -= payloadStartOffset;
                                    payloadStartOffset = 0;
                                }
                            }
                            pesData.set(frag, i);
                            i += len;
                        }
                        if (pesLen) // payload size : remove PES header + PES extension
                        pesLen -= pesHdrLen + 3;
                        return {
                            data: pesData,
                            pts: pesPts,
                            dts: pesDts,
                            len: pesLen
                        };
                    } else return null;
                };
                _proto.pushAccesUnit = function pushAccesUnit(avcSample, avcTrack) {
                    if (avcSample.units.length && avcSample.frame) {
                        var samples = avcTrack.samples;
                        var nbSamples = samples.length; // if sample does not have PTS/DTS, patch with last sample PTS/DTS
                        if (isNaN(avcSample.pts)) {
                            if (nbSamples) {
                                var lastSample = samples[nbSamples - 1];
                                avcSample.pts = lastSample.pts;
                                avcSample.dts = lastSample.dts;
                            } else {
                                // dropping samples, no timestamp found
                                avcTrack.dropped++;
                                return;
                            }
                        } // only push AVC sample if starting with a keyframe is not mandatory OR
                        //    if keyframe already found in this fragment OR
                        //       keyframe found in last fragment (track.sps) AND
                        //          samples already appended (we already found a keyframe in this fragment) OR fragment is contiguous
                        if (!this.config.forceKeyFrameOnDiscontinuity || avcSample.key === true || avcTrack.sps && (nbSamples || this.contiguous)) {
                            avcSample.id = nbSamples;
                            samples.push(avcSample);
                        } else // dropped samples, track it
                        avcTrack.dropped++;
                    }
                    if (avcSample.debug.length) logger["logger"].log(avcSample.pts + '/' + avcSample.dts + ':' + avcSample.debug);
                };
                _proto._parseAVCPES = function _parseAVCPES(pes, last) {
                    var _this = this;
                    // logger.log('parse new PES');
                    var track = this._avcTrack, units = this._parseAVCNALu(pes.data), debug1 = false, expGolombDecoder, avcSample = this.avcSample, push, spsfound = false, i, pushAccesUnit = this.pushAccesUnit.bind(this), createAVCSample = function createAVCSample(key, pts, dts, debug) {
                        return {
                            key: key,
                            pts: pts,
                            dts: dts,
                            units: [],
                            debug: debug
                        };
                    }; // free pes.data to save up some memory
                    pes.data = null; // if new NAL units found and last sample still there, let's push ...
                    // this helps parsing streams with missing AUD (only do this if AUD never found)
                    if (avcSample && units.length && !track.audFound) {
                        pushAccesUnit(avcSample, track);
                        avcSample = this.avcSample = createAVCSample(false, pes.pts, pes.dts, '');
                    }
                    units.forEach(function(unit) {
                        switch(unit.type){
                            // NDR
                            case 1:
                                push = true;
                                if (!avcSample) avcSample = _this.avcSample = createAVCSample(true, pes.pts, pes.dts, '');
                                if (debug1) avcSample.debug += 'NDR ';
                                avcSample.frame = true;
                                var data = unit.data; // only check slice type to detect KF in case SPS found in same packet (any keyframe is preceded by SPS ...)
                                if (spsfound && data.length > 4) {
                                    // retrieve slice type by parsing beginning of NAL unit (follow H264 spec, slice_header definition) to detect keyframe embedded in NDR
                                    var sliceType = new exp_golomb(data).readSliceType(); // 2 : I slice, 4 : SI slice, 7 : I slice, 9: SI slice
                                    // SI slice : A slice that is coded using intra prediction only and using quantisation of the prediction samples.
                                    // An SI slice can be coded such that its decoded samples can be constructed identically to an SP slice.
                                    // I slice: A slice that is not an SI slice that is decoded using intra prediction only.
                                    // if (sliceType === 2 || sliceType === 7) {
                                    if (sliceType === 2 || sliceType === 4 || sliceType === 7 || sliceType === 9) avcSample.key = true;
                                }
                                break;
                            // IDR
                            case 5:
                                push = true; // handle PES not starting with AUD
                                if (!avcSample) avcSample = _this.avcSample = createAVCSample(true, pes.pts, pes.dts, '');
                                if (debug1) avcSample.debug += 'IDR ';
                                avcSample.key = true;
                                avcSample.frame = true;
                                break;
                            // SEI
                            case 6:
                                push = true;
                                if (debug1 && avcSample) avcSample.debug += 'SEI ';
                                expGolombDecoder = new exp_golomb(_this.discardEPB(unit.data)); // skip frameType
                                expGolombDecoder.readUByte();
                                var payloadType = 0;
                                var payloadSize = 0;
                                var endOfCaptions = false;
                                var b = 0;
                                while(!endOfCaptions && expGolombDecoder.bytesAvailable > 1){
                                    payloadType = 0;
                                    do {
                                        b = expGolombDecoder.readUByte();
                                        payloadType += b;
                                    }while (b === 255) // Parse payload size.
                                    payloadSize = 0;
                                    do {
                                        b = expGolombDecoder.readUByte();
                                        payloadSize += b;
                                    }while (b === 255) // TODO: there can be more than one payload in an SEI packet...
                                    // TODO: need to read type and size in a while loop to get them all
                                    if (payloadType === 4 && expGolombDecoder.bytesAvailable !== 0) {
                                        endOfCaptions = true;
                                        var countryCode = expGolombDecoder.readUByte();
                                        if (countryCode === 181) {
                                            var providerCode = expGolombDecoder.readUShort();
                                            if (providerCode === 49) {
                                                var userStructure = expGolombDecoder.readUInt();
                                                if (userStructure === 1195456820) {
                                                    var userDataType = expGolombDecoder.readUByte(); // Raw CEA-608 bytes wrapped in CEA-708 packet
                                                    if (userDataType === 3) {
                                                        var firstByte = expGolombDecoder.readUByte();
                                                        var secondByte = expGolombDecoder.readUByte();
                                                        var totalCCs = 31 & firstByte;
                                                        var byteArray = [
                                                            firstByte,
                                                            secondByte
                                                        ];
                                                        for(i = 0; i < totalCCs; i++){
                                                            // 3 bytes per CC
                                                            byteArray.push(expGolombDecoder.readUByte());
                                                            byteArray.push(expGolombDecoder.readUByte());
                                                            byteArray.push(expGolombDecoder.readUByte());
                                                        }
                                                        _this._insertSampleInOrder(_this._txtTrack.samples, {
                                                            type: 3,
                                                            pts: pes.pts,
                                                            bytes: byteArray
                                                        });
                                                    }
                                                }
                                            }
                                        }
                                    } else if (payloadType === 5 && expGolombDecoder.bytesAvailable !== 0) {
                                        endOfCaptions = true;
                                        if (payloadSize > 16) {
                                            var uuidStrArray = [];
                                            for(i = 0; i < 16; i++){
                                                uuidStrArray.push(expGolombDecoder.readUByte().toString(16));
                                                if (i === 3 || i === 5 || i === 7 || i === 9) uuidStrArray.push('-');
                                            }
                                            var length = payloadSize - 16;
                                            var userDataPayloadBytes = new Uint8Array(length);
                                            for(i = 0; i < length; i++)userDataPayloadBytes[i] = expGolombDecoder.readUByte();
                                            _this._insertSampleInOrder(_this._txtTrack.samples, {
                                                pts: pes.pts,
                                                payloadType: payloadType,
                                                uuid: uuidStrArray.join(''),
                                                userDataBytes: userDataPayloadBytes,
                                                userData: Object(id3["utf8ArrayToStr"])(userDataPayloadBytes.buffer)
                                            });
                                        }
                                    } else if (payloadSize < expGolombDecoder.bytesAvailable) for(i = 0; i < payloadSize; i++)expGolombDecoder.readUByte();
                                }
                                break;
                            // SPS
                            case 7:
                                push = true;
                                spsfound = true;
                                if (debug1 && avcSample) avcSample.debug += 'SPS ';
                                if (!track.sps) {
                                    expGolombDecoder = new exp_golomb(unit.data);
                                    var config = expGolombDecoder.readSPS();
                                    track.width = config.width;
                                    track.height = config.height;
                                    track.pixelRatio = config.pixelRatio;
                                    track.sps = [
                                        unit.data
                                    ];
                                    track.duration = _this._duration;
                                    var codecarray = unit.data.subarray(1, 4);
                                    var codecstring = 'avc1.';
                                    for(i = 0; i < 3; i++){
                                        var h = codecarray[i].toString(16);
                                        if (h.length < 2) h = '0' + h;
                                        codecstring += h;
                                    }
                                    track.codec = codecstring;
                                }
                                break;
                            // PPS
                            case 8:
                                push = true;
                                if (debug1 && avcSample) avcSample.debug += 'PPS ';
                                if (!track.pps) track.pps = [
                                    unit.data
                                ];
                                break;
                            // AUD
                            case 9:
                                push = false;
                                track.audFound = true;
                                if (avcSample) pushAccesUnit(avcSample, track);
                                avcSample = _this.avcSample = createAVCSample(false, pes.pts, pes.dts, debug1 ? 'AUD ' : '');
                                break;
                            // Filler Data
                            case 12:
                                push = false;
                                break;
                            default:
                                push = false;
                                if (avcSample) avcSample.debug += 'unknown NAL ' + unit.type + ' ';
                                break;
                        }
                        if (avcSample && push) {
                            var _units = avcSample.units;
                            _units.push(unit);
                        }
                    }); // if last PES packet, push samples
                    if (last && avcSample) {
                        pushAccesUnit(avcSample, track);
                        this.avcSample = null;
                    }
                };
                _proto._insertSampleInOrder = function _insertSampleInOrder(arr, data) {
                    var len = arr.length;
                    if (len > 0) {
                        if (data.pts >= arr[len - 1].pts) arr.push(data);
                        else {
                            for(var pos = len - 1; pos >= 0; pos--)if (data.pts < arr[pos].pts) {
                                arr.splice(pos, 0, data);
                                break;
                            }
                        }
                    } else arr.push(data);
                };
                _proto._getLastNalUnit = function _getLastNalUnit() {
                    var avcSample = this.avcSample, lastUnit; // try to fallback to previous sample if current one is empty
                    if (!avcSample || avcSample.units.length === 0) {
                        var track = this._avcTrack, samples = track.samples;
                        avcSample = samples[samples.length - 1];
                    }
                    if (avcSample) {
                        var units = avcSample.units;
                        lastUnit = units[units.length - 1];
                    }
                    return lastUnit;
                };
                _proto._parseAVCNALu = function _parseAVCNALu(array) {
                    var i = 0, len = array.byteLength, value, overflow, track = this._avcTrack, state = track.naluState || 0, lastState = state;
                    var units = [], unit, unitType, lastUnitStart = -1, lastUnitType; // logger.log('PES:' + Hex.hexDump(array));
                    if (state === -1) {
                        // special use case where we found 3 or 4-byte start codes exactly at the end of previous PES packet
                        lastUnitStart = 0; // NALu type is value read from offset 0
                        lastUnitType = array[0] & 31;
                        state = 0;
                        i = 1;
                    }
                    while(i < len){
                        value = array[i++]; // optimization. state 0 and 1 are the predominant case. let's handle them outside of the switch/case
                        if (!state) {
                            state = value ? 0 : 1;
                            continue;
                        }
                        if (state === 1) {
                            state = value ? 0 : 2;
                            continue;
                        } // here we have state either equal to 2 or 3
                        if (!value) state = 3;
                        else if (value === 1) {
                            if (lastUnitStart >= 0) {
                                unit = {
                                    data: array.subarray(lastUnitStart, i - state - 1),
                                    type: lastUnitType
                                }; // logger.log('pushing NALU, type/size:' + unit.type + '/' + unit.data.byteLength);
                                units.push(unit);
                            } else {
                                // lastUnitStart is undefined => this is the first start code found in this PES packet
                                // first check if start code delimiter is overlapping between 2 PES packets,
                                // ie it started in last packet (lastState not zero)
                                // and ended at the beginning of this PES packet (i <= 4 - lastState)
                                var lastUnit = this._getLastNalUnit();
                                if (lastUnit) {
                                    if (lastState && i <= 4 - lastState) // start delimiter overlapping between PES packets
                                    // strip start delimiter bytes from the end of last NAL unit
                                    // check if lastUnit had a state different from zero
                                    {
                                        if (lastUnit.state) // strip last bytes
                                        lastUnit.data = lastUnit.data.subarray(0, lastUnit.data.byteLength - lastState);
                                    } // If NAL units are not starting right at the beginning of the PES packet, push preceding data into previous NAL unit.
                                    overflow = i - state - 1;
                                    if (overflow > 0) {
                                        // logger.log('first NALU found with overflow:' + overflow);
                                        var tmp = new Uint8Array(lastUnit.data.byteLength + overflow);
                                        tmp.set(lastUnit.data, 0);
                                        tmp.set(array.subarray(0, overflow), lastUnit.data.byteLength);
                                        lastUnit.data = tmp;
                                    }
                                }
                            } // check if we can read unit type
                            if (i < len) {
                                unitType = array[i] & 31; // logger.log('find NALU @ offset:' + i + ',type:' + unitType);
                                lastUnitStart = i;
                                lastUnitType = unitType;
                                state = 0;
                            } else // not enough byte to read unit type. let's read it on next PES parsing
                            state = -1;
                        } else state = 0;
                    }
                    if (lastUnitStart >= 0 && state >= 0) {
                        unit = {
                            data: array.subarray(lastUnitStart, len),
                            type: lastUnitType,
                            state: state
                        };
                        units.push(unit); // logger.log('pushing NALU, type/size/state:' + unit.type + '/' + unit.data.byteLength + '/' + state);
                    } // no NALu found
                    if (units.length === 0) {
                        // append pes.data to previous NAL unit
                        var _lastUnit = this._getLastNalUnit();
                        if (_lastUnit) {
                            var _tmp = new Uint8Array(_lastUnit.data.byteLength + array.byteLength);
                            _tmp.set(_lastUnit.data, 0);
                            _tmp.set(array, _lastUnit.data.byteLength);
                            _lastUnit.data = _tmp;
                        }
                    }
                    track.naluState = state;
                    return units;
                };
                _proto.discardEPB = function discardEPB(data) {
                    var length = data.byteLength, EPBPositions = [], i = 1, newLength, newData; // Find all `Emulation Prevention Bytes`
                    while(i < length - 2)if (data[i] === 0 && data[i + 1] === 0 && data[i + 2] === 3) {
                        EPBPositions.push(i + 2);
                        i += 2;
                    } else i++;
                     // If no Emulation Prevention Bytes were found just return the original
                    // array
                    if (EPBPositions.length === 0) return data;
                     // Create a new array to hold the NAL unit data
                    newLength = length - EPBPositions.length;
                    newData = new Uint8Array(newLength);
                    var sourceIndex = 0;
                    for(i = 0; i < newLength; sourceIndex++, i++){
                        if (sourceIndex === EPBPositions[0]) {
                            // Skip this byte
                            sourceIndex++; // Remove this position index
                            EPBPositions.shift();
                        }
                        newData[i] = data[sourceIndex];
                    }
                    return newData;
                };
                _proto._parseAACPES = function _parseAACPES(pes) {
                    var track = this._audioTrack, data = pes.data, pts = pes.pts, startOffset = 0, aacOverFlow = this.aacOverFlow, aacLastPTS = this.aacLastPTS, frameDuration, frameIndex, offset, stamp, len;
                    if (aacOverFlow) {
                        var tmp = new Uint8Array(aacOverFlow.byteLength + data.byteLength);
                        tmp.set(aacOverFlow, 0);
                        tmp.set(data, aacOverFlow.byteLength); // logger.log(`AAC: append overflowing ${aacOverFlow.byteLength} bytes to beginning of new PES`);
                        data = tmp;
                    } // look for ADTS header (0xFFFx)
                    for(offset = startOffset, len = data.length; offset < len - 1; offset++){
                        if (isHeader(data, offset)) break;
                    } // if ADTS header does not start straight from the beginning of the PES payload, raise an error
                    if (offset) {
                        var reason, fatal;
                        if (offset < len - 1) {
                            reason = "AAC PES did not start with ADTS header,offset:" + offset;
                            fatal = false;
                        } else {
                            reason = 'no ADTS header found in AAC PES';
                            fatal = true;
                        }
                        logger["logger"].warn("parsing error:" + reason);
                        this.observer.trigger(events["default"].ERROR, {
                            type: errors["ErrorTypes"].MEDIA_ERROR,
                            details: errors["ErrorDetails"].FRAG_PARSING_ERROR,
                            fatal: fatal,
                            reason: reason
                        });
                        if (fatal) return;
                    }
                    initTrackConfig(track, this.observer, data, offset, this.audioCodec);
                    frameIndex = 0;
                    frameDuration = getFrameDuration(track.samplerate); // if last AAC frame is overflowing, we should ensure timestamps are contiguous:
                    // first sample PTS should be equal to last sample PTS + frameDuration
                    if (aacOverFlow && aacLastPTS) {
                        var newPTS = aacLastPTS + frameDuration;
                        if (Math.abs(newPTS - pts) > 1) {
                            logger["logger"].log("AAC: align PTS for overlapping frames by " + Math.round((newPTS - pts) / 90));
                            pts = newPTS;
                        }
                    } // scan for aac samples
                    while(offset < len)if (isHeader(data, offset)) {
                        if (offset + 5 < len) {
                            var frame = appendFrame(track, data, offset, pts, frameIndex);
                            if (frame) {
                                offset += frame.length;
                                stamp = frame.sample.pts;
                                frameIndex++;
                                continue;
                            }
                        } // We are at an ADTS header, but do not have enough data for a frame
                        break;
                    } else // nothing found, keep looking
                    offset++;
                    if (offset < len) aacOverFlow = data.subarray(offset, len); // logger.log(`AAC: overflow detected:${len-offset}`);
                    else aacOverFlow = null;
                    this.aacOverFlow = aacOverFlow;
                    this.aacLastPTS = stamp;
                };
                _proto._parseMPEGPES = function _parseMPEGPES(pes) {
                    var data = pes.data;
                    var length = data.length;
                    var frameIndex = 0;
                    var offset = 0;
                    var pts = pes.pts;
                    while(offset < length)if (mpegaudio.isHeader(data, offset)) {
                        var frame = mpegaudio.appendFrame(this._audioTrack, data, offset, pts, frameIndex);
                        if (frame) {
                            offset += frame.length;
                            frameIndex++;
                        } else break;
                    } else // nothing found, keep looking
                    offset++;
                };
                _proto._parseID3PES = function _parseID3PES(pes) {
                    this._id3Track.samples.push(pes);
                };
                return TSDemuxer;
            }();
            /* harmony default export */ var tsdemuxer = tsdemuxer_TSDemuxer;
            // CONCATENATED MODULE: ./src/demux/mp3demuxer.js
            /**
 * MP3 demuxer
 */ var mp3demuxer_MP3Demuxer = /*#__PURE__*/ function() {
                function MP3Demuxer(observer, remuxer, config) {
                    this.observer = observer;
                    this.config = config;
                    this.remuxer = remuxer;
                }
                var _proto = MP3Demuxer.prototype;
                _proto.resetInitSegment = function resetInitSegment(initSegment, audioCodec, videoCodec, duration) {
                    this._audioTrack = {
                        container: 'audio/mpeg',
                        type: 'audio',
                        id: -1,
                        sequenceNumber: 0,
                        isAAC: false,
                        samples: [],
                        len: 0,
                        manifestCodec: audioCodec,
                        duration: duration,
                        inputTimeScale: 90000
                    };
                };
                _proto.resetTimeStamp = function resetTimeStamp() {
                };
                MP3Demuxer.probe = function probe(data) {
                    // check if data contains ID3 timestamp and MPEG sync word
                    var offset, length;
                    var id3Data = id3["default"].getID3Data(data, 0);
                    if (id3Data && id3["default"].getTimeStamp(id3Data) !== undefined) {
                        // Look for MPEG header | 1111 1111 | 111X XYZX | where X can be either 0 or 1 and Y or Z should be 1
                        // Layer bits (position 14 and 15) in header should be always different from 0 (Layer I or Layer II or Layer III)
                        // More info http://www.mp3-tech.org/programmer/frame_header.html
                        for(offset = id3Data.length, length = Math.min(data.length - 1, offset + 100); offset < length; offset++)if (mpegaudio.probe(data, offset)) {
                            logger["logger"].log('MPEG Audio sync word found !');
                            return true;
                        }
                    }
                    return false;
                } // feed incoming data to the front of the parsing pipeline
                ;
                _proto.append = function append(data, timeOffset, contiguous, accurateTimeOffset) {
                    var id3Data = id3["default"].getID3Data(data, 0) || [];
                    var timestamp = id3["default"].getTimeStamp(id3Data);
                    var pts = timestamp !== undefined ? 90 * timestamp : timeOffset * 90000;
                    var offset = id3Data.length;
                    var length = data.length;
                    var frameIndex = 0, stamp = 0;
                    var track = this._audioTrack;
                    var id3Samples = [
                        {
                            pts: pts,
                            dts: pts,
                            data: id3Data
                        }
                    ];
                    while(offset < length){
                        if (mpegaudio.isHeader(data, offset)) {
                            var frame = mpegaudio.appendFrame(track, data, offset, pts, frameIndex);
                            if (frame) {
                                offset += frame.length;
                                stamp = frame.sample.pts;
                                frameIndex++;
                            } else break;
                        } else if (id3["default"].isHeader(data, offset)) {
                            id3Data = id3["default"].getID3Data(data, offset);
                            id3Samples.push({
                                pts: stamp,
                                dts: stamp,
                                data: id3Data
                            });
                            offset += id3Data.length;
                        } else // nothing found, keep looking
                        offset++;
                    }
                    this.remuxer.remux(track, {
                        samples: []
                    }, {
                        samples: id3Samples,
                        inputTimeScale: 90000
                    }, {
                        samples: []
                    }, timeOffset, contiguous, accurateTimeOffset);
                };
                _proto.destroy = function destroy() {
                };
                return MP3Demuxer;
            }();
            /* harmony default export */ var mp3demuxer = mp3demuxer_MP3Demuxer;
            // CONCATENATED MODULE: ./src/remux/aac-helper.js
            /**
 *  AAC helper
 */ var AAC1 = /*#__PURE__*/ function() {
                function AAC() {
                }
                AAC.getSilentFrame = function getSilentFrame(codec, channelCount) {
                    switch(codec){
                        case 'mp4a.40.2':
                            if (channelCount === 1) return new Uint8Array([
                                0,
                                200,
                                0,
                                128,
                                35,
                                128
                            ]);
                            else if (channelCount === 2) return new Uint8Array([
                                33,
                                0,
                                73,
                                144,
                                2,
                                25,
                                0,
                                35,
                                128
                            ]);
                            else if (channelCount === 3) return new Uint8Array([
                                0,
                                200,
                                0,
                                128,
                                32,
                                132,
                                1,
                                38,
                                64,
                                8,
                                100,
                                0,
                                142
                            ]);
                            else if (channelCount === 4) return new Uint8Array([
                                0,
                                200,
                                0,
                                128,
                                32,
                                132,
                                1,
                                38,
                                64,
                                8,
                                100,
                                0,
                                128,
                                44,
                                128,
                                8,
                                2,
                                56
                            ]);
                            else if (channelCount === 5) return new Uint8Array([
                                0,
                                200,
                                0,
                                128,
                                32,
                                132,
                                1,
                                38,
                                64,
                                8,
                                100,
                                0,
                                130,
                                48,
                                4,
                                153,
                                0,
                                33,
                                144,
                                2,
                                56
                            ]);
                            else if (channelCount === 6) return new Uint8Array([
                                0,
                                200,
                                0,
                                128,
                                32,
                                132,
                                1,
                                38,
                                64,
                                8,
                                100,
                                0,
                                130,
                                48,
                                4,
                                153,
                                0,
                                33,
                                144,
                                2,
                                0,
                                178,
                                0,
                                32,
                                8,
                                224
                            ]);
                            break;
                        // handle HE-AAC below (mp4a.40.5 / mp4a.40.29)
                        default:
                            if (channelCount === 1) // ffmpeg -y -f lavfi -i "aevalsrc=0:d=0.05" -c:a libfdk_aac -profile:a aac_he -b:a 4k output.aac && hexdump -v -e '16/1 "0x%x," "\n"' -v output.aac
                            return new Uint8Array([
                                1,
                                64,
                                34,
                                128,
                                163,
                                78,
                                230,
                                128,
                                186,
                                8,
                                0,
                                0,
                                0,
                                28,
                                6,
                                241,
                                193,
                                10,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                94
                            ]);
                            else if (channelCount === 2) // ffmpeg -y -f lavfi -i "aevalsrc=0|0:d=0.05" -c:a libfdk_aac -profile:a aac_he_v2 -b:a 4k output.aac && hexdump -v -e '16/1 "0x%x," "\n"' -v output.aac
                            return new Uint8Array([
                                1,
                                64,
                                34,
                                128,
                                163,
                                94,
                                230,
                                128,
                                186,
                                8,
                                0,
                                0,
                                0,
                                0,
                                149,
                                0,
                                6,
                                241,
                                161,
                                10,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                94
                            ]);
                            else if (channelCount === 3) // ffmpeg -y -f lavfi -i "aevalsrc=0|0|0:d=0.05" -c:a libfdk_aac -profile:a aac_he_v2 -b:a 4k output.aac && hexdump -v -e '16/1 "0x%x," "\n"' -v output.aac
                            return new Uint8Array([
                                1,
                                64,
                                34,
                                128,
                                163,
                                94,
                                230,
                                128,
                                186,
                                8,
                                0,
                                0,
                                0,
                                0,
                                149,
                                0,
                                6,
                                241,
                                161,
                                10,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                90,
                                94
                            ]);
                            break;
                    }
                    return null;
                };
                return AAC;
            }();
            /* harmony default export */ var aac_helper = AAC1;
            // CONCATENATED MODULE: ./src/remux/mp4-generator.js
            /**
 * Generate MP4 Box
*/ var UINT32_MAX = Math.pow(2, 32) - 1;
            var MP41 = /*#__PURE__*/ function() {
                function MP4() {
                }
                MP4.init = function init() {
                    MP4.types = {
                        avc1: [],
                        // codingname
                        avcC: [],
                        btrt: [],
                        dinf: [],
                        dref: [],
                        esds: [],
                        ftyp: [],
                        hdlr: [],
                        mdat: [],
                        mdhd: [],
                        mdia: [],
                        mfhd: [],
                        minf: [],
                        moof: [],
                        moov: [],
                        mp4a: [],
                        '.mp3': [],
                        mvex: [],
                        mvhd: [],
                        pasp: [],
                        sdtp: [],
                        stbl: [],
                        stco: [],
                        stsc: [],
                        stsd: [],
                        stsz: [],
                        stts: [],
                        tfdt: [],
                        tfhd: [],
                        traf: [],
                        trak: [],
                        trun: [],
                        trex: [],
                        tkhd: [],
                        vmhd: [],
                        smhd: []
                    };
                    var i;
                    for(i in MP4.types)if (MP4.types.hasOwnProperty(i)) MP4.types[i] = [
                        i.charCodeAt(0),
                        i.charCodeAt(1),
                        i.charCodeAt(2),
                        i.charCodeAt(3)
                    ];
                    var videoHdlr = new Uint8Array([
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        118,
                        105,
                        100,
                        101,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        86,
                        105,
                        100,
                        101,
                        111,
                        72,
                        97,
                        110,
                        100,
                        108,
                        101,
                        114,
                        0 // name: 'VideoHandler'
                    ]);
                    var audioHdlr = new Uint8Array([
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        115,
                        111,
                        117,
                        110,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        83,
                        111,
                        117,
                        110,
                        100,
                        72,
                        97,
                        110,
                        100,
                        108,
                        101,
                        114,
                        0 // name: 'SoundHandler'
                    ]);
                    MP4.HDLR_TYPES = {
                        'video': videoHdlr,
                        'audio': audioHdlr
                    };
                    var dref = new Uint8Array([
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        1,
                        0,
                        0,
                        0,
                        12,
                        117,
                        114,
                        108,
                        32,
                        0,
                        0,
                        0,
                        1 // entry_flags
                    ]);
                    var stco = new Uint8Array([
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0 // entry_count
                    ]);
                    MP4.STTS = MP4.STSC = MP4.STCO = stco;
                    MP4.STSZ = new Uint8Array([
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0 // sample_count
                    ]);
                    MP4.VMHD = new Uint8Array([
                        0,
                        0,
                        0,
                        1,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0 // opcolor
                    ]);
                    MP4.SMHD = new Uint8Array([
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0 // reserved
                    ]);
                    MP4.STSD = new Uint8Array([
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        1
                    ]); // entry_count
                    var majorBrand = new Uint8Array([
                        105,
                        115,
                        111,
                        109
                    ]); // isom
                    var avc1Brand = new Uint8Array([
                        97,
                        118,
                        99,
                        49
                    ]); // avc1
                    var minorVersion = new Uint8Array([
                        0,
                        0,
                        0,
                        1
                    ]);
                    MP4.FTYP = MP4.box(MP4.types.ftyp, majorBrand, minorVersion, majorBrand, avc1Brand);
                    MP4.DINF = MP4.box(MP4.types.dinf, MP4.box(MP4.types.dref, dref));
                };
                MP4.box = function box(type) {
                    var payload = Array.prototype.slice.call(arguments, 1), size = 8, i = payload.length, len = i, result; // calculate the total size we need to allocate
                    while(i--)size += payload[i].byteLength;
                    result = new Uint8Array(size);
                    result[0] = size >> 24 & 255;
                    result[1] = size >> 16 & 255;
                    result[2] = size >> 8 & 255;
                    result[3] = size & 255;
                    result.set(type, 4); // copy the payload into the result
                    for(i = 0, size = 8; i < len; i++){
                        // copy payload[i] array @ offset size
                        result.set(payload[i], size);
                        size += payload[i].byteLength;
                    }
                    return result;
                };
                MP4.hdlr = function hdlr(type) {
                    return MP4.box(MP4.types.hdlr, MP4.HDLR_TYPES[type]);
                };
                MP4.mdat = function mdat(data) {
                    return MP4.box(MP4.types.mdat, data);
                };
                MP4.mdhd = function mdhd(timescale, duration) {
                    duration *= timescale;
                    var upperWordDuration = Math.floor(duration / (UINT32_MAX + 1));
                    var lowerWordDuration = Math.floor(duration % (UINT32_MAX + 1));
                    return MP4.box(MP4.types.mdhd, new Uint8Array([
                        1,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        2,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        3,
                        timescale >> 24 & 255,
                        timescale >> 16 & 255,
                        timescale >> 8 & 255,
                        timescale & 255,
                        upperWordDuration >> 24,
                        upperWordDuration >> 16 & 255,
                        upperWordDuration >> 8 & 255,
                        upperWordDuration & 255,
                        lowerWordDuration >> 24,
                        lowerWordDuration >> 16 & 255,
                        lowerWordDuration >> 8 & 255,
                        lowerWordDuration & 255,
                        85,
                        196,
                        0,
                        0
                    ]));
                };
                MP4.mdia = function mdia(track) {
                    return MP4.box(MP4.types.mdia, MP4.mdhd(track.timescale, track.duration), MP4.hdlr(track.type), MP4.minf(track));
                };
                MP4.mfhd = function mfhd(sequenceNumber) {
                    return MP4.box(MP4.types.mfhd, new Uint8Array([
                        0,
                        0,
                        0,
                        0,
                        sequenceNumber >> 24,
                        sequenceNumber >> 16 & 255,
                        sequenceNumber >> 8 & 255,
                        sequenceNumber & 255 // sequence_number
                    ]));
                };
                MP4.minf = function minf(track) {
                    if (track.type === 'audio') return MP4.box(MP4.types.minf, MP4.box(MP4.types.smhd, MP4.SMHD), MP4.DINF, MP4.stbl(track));
                    else return MP4.box(MP4.types.minf, MP4.box(MP4.types.vmhd, MP4.VMHD), MP4.DINF, MP4.stbl(track));
                };
                MP4.moof = function moof(sn, baseMediaDecodeTime, track) {
                    return MP4.box(MP4.types.moof, MP4.mfhd(sn), MP4.traf(track, baseMediaDecodeTime));
                };
                MP4.moov = function moov(tracks) {
                    var i = tracks.length, boxes = [];
                    while(i--)boxes[i] = MP4.trak(tracks[i]);
                    return MP4.box.apply(null, [
                        MP4.types.moov,
                        MP4.mvhd(tracks[0].timescale, tracks[0].duration)
                    ].concat(boxes).concat(MP4.mvex(tracks)));
                };
                MP4.mvex = function mvex(tracks) {
                    var i = tracks.length, boxes = [];
                    while(i--)boxes[i] = MP4.trex(tracks[i]);
                    return MP4.box.apply(null, [
                        MP4.types.mvex
                    ].concat(boxes));
                };
                MP4.mvhd = function mvhd(timescale, duration) {
                    duration *= timescale;
                    var upperWordDuration = Math.floor(duration / (UINT32_MAX + 1));
                    var lowerWordDuration = Math.floor(duration % (UINT32_MAX + 1));
                    var bytes = new Uint8Array([
                        1,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        2,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        3,
                        timescale >> 24 & 255,
                        timescale >> 16 & 255,
                        timescale >> 8 & 255,
                        timescale & 255,
                        upperWordDuration >> 24,
                        upperWordDuration >> 16 & 255,
                        upperWordDuration >> 8 & 255,
                        upperWordDuration & 255,
                        lowerWordDuration >> 24,
                        lowerWordDuration >> 16 & 255,
                        lowerWordDuration >> 8 & 255,
                        lowerWordDuration & 255,
                        0,
                        1,
                        0,
                        0,
                        1,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        1,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        1,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        64,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        255,
                        255,
                        255,
                        255 // next_track_ID
                    ]);
                    return MP4.box(MP4.types.mvhd, bytes);
                };
                MP4.sdtp = function sdtp(track) {
                    var samples = track.samples || [], bytes = new Uint8Array(4 + samples.length), flags, i; // leave the full box header (4 bytes) all zero
                    // write the sample table
                    for(i = 0; i < samples.length; i++){
                        flags = samples[i].flags;
                        bytes[i + 4] = flags.dependsOn << 4 | flags.isDependedOn << 2 | flags.hasRedundancy;
                    }
                    return MP4.box(MP4.types.sdtp, bytes);
                };
                MP4.stbl = function stbl(track) {
                    return MP4.box(MP4.types.stbl, MP4.stsd(track), MP4.box(MP4.types.stts, MP4.STTS), MP4.box(MP4.types.stsc, MP4.STSC), MP4.box(MP4.types.stsz, MP4.STSZ), MP4.box(MP4.types.stco, MP4.STCO));
                };
                MP4.avc1 = function avc1(track) {
                    var sps = [], pps = [], i, data, len; // assemble the SPSs
                    for(i = 0; i < track.sps.length; i++){
                        data = track.sps[i];
                        len = data.byteLength;
                        sps.push(len >>> 8 & 255);
                        sps.push(len & 255); // SPS
                        sps = sps.concat(Array.prototype.slice.call(data));
                    } // assemble the PPSs
                    for(i = 0; i < track.pps.length; i++){
                        data = track.pps[i];
                        len = data.byteLength;
                        pps.push(len >>> 8 & 255);
                        pps.push(len & 255);
                        pps = pps.concat(Array.prototype.slice.call(data));
                    }
                    var avcc = MP4.box(MP4.types.avcC, new Uint8Array([
                        1,
                        sps[3],
                        sps[4],
                        sps[5],
                        255,
                        224 | track.sps.length // 3bit reserved (111) + numOfSequenceParameterSets
                    ].concat(sps).concat([
                        track.pps.length // numOfPictureParameterSets
                    ]).concat(pps))), // "PPS"
                    width = track.width, height = track.height, hSpacing = track.pixelRatio[0], vSpacing = track.pixelRatio[1];
                    return MP4.box(MP4.types.avc1, new Uint8Array([
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        1,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        width >> 8 & 255,
                        width & 255,
                        height >> 8 & 255,
                        height & 255,
                        0,
                        72,
                        0,
                        0,
                        0,
                        72,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        1,
                        18,
                        100,
                        97,
                        105,
                        108,
                        121,
                        109,
                        111,
                        116,
                        105,
                        111,
                        110,
                        47,
                        104,
                        108,
                        115,
                        46,
                        106,
                        115,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        24,
                        17,
                        17
                    ]), avcc, MP4.box(MP4.types.btrt, new Uint8Array([
                        0,
                        28,
                        156,
                        128,
                        0,
                        45,
                        198,
                        192,
                        0,
                        45,
                        198,
                        192
                    ])), MP4.box(MP4.types.pasp, new Uint8Array([
                        hSpacing >> 24,
                        hSpacing >> 16 & 255,
                        hSpacing >> 8 & 255,
                        hSpacing & 255,
                        vSpacing >> 24,
                        vSpacing >> 16 & 255,
                        vSpacing >> 8 & 255,
                        vSpacing & 255
                    ])));
                };
                MP4.esds = function esds(track) {
                    var configlen = track.config.length;
                    return new Uint8Array([
                        0,
                        0,
                        0,
                        0,
                        3,
                        23 + configlen,
                        0,
                        1,
                        0,
                        4,
                        15 + configlen,
                        64,
                        21,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        5 // descriptor_type
                    ].concat([
                        configlen
                    ]).concat(track.config).concat([
                        6,
                        1,
                        2
                    ])); // GASpecificConfig)); // length + audio config descriptor
                };
                MP4.mp4a = function mp4a(track) {
                    var samplerate = track.samplerate;
                    return MP4.box(MP4.types.mp4a, new Uint8Array([
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        1,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        track.channelCount,
                        0,
                        16,
                        0,
                        0,
                        0,
                        0,
                        samplerate >> 8 & 255,
                        samplerate & 255,
                        0,
                        0
                    ]), MP4.box(MP4.types.esds, MP4.esds(track)));
                };
                MP4.mp3 = function mp3(track) {
                    var samplerate = track.samplerate;
                    return MP4.box(MP4.types['.mp3'], new Uint8Array([
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        1,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        track.channelCount,
                        0,
                        16,
                        0,
                        0,
                        0,
                        0,
                        samplerate >> 8 & 255,
                        samplerate & 255,
                        0,
                        0
                    ]));
                };
                MP4.stsd = function stsd(track) {
                    if (track.type === 'audio') {
                        if (!track.isAAC && track.codec === 'mp3') return MP4.box(MP4.types.stsd, MP4.STSD, MP4.mp3(track));
                        return MP4.box(MP4.types.stsd, MP4.STSD, MP4.mp4a(track));
                    } else return MP4.box(MP4.types.stsd, MP4.STSD, MP4.avc1(track));
                };
                MP4.tkhd = function tkhd(track) {
                    var id = track.id, duration = track.duration * track.timescale, width = track.width, height = track.height, upperWordDuration = Math.floor(duration / (UINT32_MAX + 1)), lowerWordDuration = Math.floor(duration % (UINT32_MAX + 1));
                    return MP4.box(MP4.types.tkhd, new Uint8Array([
                        1,
                        0,
                        0,
                        7,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        2,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        3,
                        id >> 24 & 255,
                        id >> 16 & 255,
                        id >> 8 & 255,
                        id & 255,
                        0,
                        0,
                        0,
                        0,
                        upperWordDuration >> 24,
                        upperWordDuration >> 16 & 255,
                        upperWordDuration >> 8 & 255,
                        upperWordDuration & 255,
                        lowerWordDuration >> 24,
                        lowerWordDuration >> 16 & 255,
                        lowerWordDuration >> 8 & 255,
                        lowerWordDuration & 255,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        1,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        1,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        64,
                        0,
                        0,
                        0,
                        width >> 8 & 255,
                        width & 255,
                        0,
                        0,
                        height >> 8 & 255,
                        height & 255,
                        0,
                        0 // height
                    ]));
                };
                MP4.traf = function traf(track, baseMediaDecodeTime) {
                    var sampleDependencyTable = MP4.sdtp(track), id = track.id, upperWordBaseMediaDecodeTime = Math.floor(baseMediaDecodeTime / (UINT32_MAX + 1)), lowerWordBaseMediaDecodeTime = Math.floor(baseMediaDecodeTime % (UINT32_MAX + 1));
                    return MP4.box(MP4.types.traf, MP4.box(MP4.types.tfhd, new Uint8Array([
                        0,
                        0,
                        0,
                        0,
                        id >> 24,
                        id >> 16 & 255,
                        id >> 8 & 255,
                        id & 255 // track_ID
                    ])), MP4.box(MP4.types.tfdt, new Uint8Array([
                        1,
                        0,
                        0,
                        0,
                        upperWordBaseMediaDecodeTime >> 24,
                        upperWordBaseMediaDecodeTime >> 16 & 255,
                        upperWordBaseMediaDecodeTime >> 8 & 255,
                        upperWordBaseMediaDecodeTime & 255,
                        lowerWordBaseMediaDecodeTime >> 24,
                        lowerWordBaseMediaDecodeTime >> 16 & 255,
                        lowerWordBaseMediaDecodeTime >> 8 & 255,
                        lowerWordBaseMediaDecodeTime & 255
                    ])), MP4.trun(track, sampleDependencyTable.length + 16 + 20 + 8 + 16 + 8 + 8), sampleDependencyTable);
                };
                MP4.trak = function trak(track) {
                    track.duration = track.duration || 4294967295;
                    return MP4.box(MP4.types.trak, MP4.tkhd(track), MP4.mdia(track));
                };
                MP4.trex = function trex(track) {
                    var id = track.id;
                    return MP4.box(MP4.types.trex, new Uint8Array([
                        0,
                        0,
                        0,
                        0,
                        id >> 24,
                        id >> 16 & 255,
                        id >> 8 & 255,
                        id & 255,
                        0,
                        0,
                        0,
                        1,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        1,
                        0,
                        1 // default_sample_flags
                    ]));
                };
                MP4.trun = function trun(track, offset) {
                    var samples = track.samples || [], len = samples.length, arraylen = 12 + 16 * len, array = new Uint8Array(arraylen), i, sample, duration, size, flags, cts;
                    offset += 8 + arraylen;
                    array.set([
                        0,
                        0,
                        15,
                        1,
                        len >>> 24 & 255,
                        len >>> 16 & 255,
                        len >>> 8 & 255,
                        len & 255,
                        offset >>> 24 & 255,
                        offset >>> 16 & 255,
                        offset >>> 8 & 255,
                        offset & 255 // data_offset
                    ], 0);
                    for(i = 0; i < len; i++){
                        sample = samples[i];
                        duration = sample.duration;
                        size = sample.size;
                        flags = sample.flags;
                        cts = sample.cts;
                        array.set([
                            duration >>> 24 & 255,
                            duration >>> 16 & 255,
                            duration >>> 8 & 255,
                            duration & 255,
                            size >>> 24 & 255,
                            size >>> 16 & 255,
                            size >>> 8 & 255,
                            size & 255,
                            flags.isLeading << 2 | flags.dependsOn,
                            flags.isDependedOn << 6 | flags.hasRedundancy << 4 | flags.paddingValue << 1 | flags.isNonSync,
                            flags.degradPrio & 61440,
                            flags.degradPrio & 15,
                            cts >>> 24 & 255,
                            cts >>> 16 & 255,
                            cts >>> 8 & 255,
                            cts & 255 // sample_composition_time_offset
                        ], 12 + 16 * i);
                    }
                    return MP4.box(MP4.types.trun, array);
                };
                MP4.initSegment = function initSegment(tracks) {
                    if (!MP4.types) MP4.init();
                    var movie = MP4.moov(tracks), result;
                    result = new Uint8Array(MP4.FTYP.byteLength + movie.byteLength);
                    result.set(MP4.FTYP);
                    result.set(movie, MP4.FTYP.byteLength);
                    return result;
                };
                return MP4;
            }();
            /* harmony default export */ var mp4_generator = MP41;
            // CONCATENATED MODULE: ./src/utils/timescale-conversion.ts
            var MPEG_TS_CLOCK_FREQ_HZ = 90000;
            function toTimescaleFromScale(value, destScale, srcScale, round) {
                if (srcScale === void 0) srcScale = 1;
                if (round === void 0) round = false;
                return toTimescaleFromBase(value, destScale, 1 / srcScale);
            }
            function toTimescaleFromBase(value, destScale, srcBase, round) {
                if (srcBase === void 0) srcBase = 1;
                if (round === void 0) round = false;
                var result = value * destScale * srcBase; // equivalent to `(value * scale) / (1 / base)`
                return round ? Math.round(result) : result;
            }
            function toMsFromMpegTsClock(value, round) {
                if (round === void 0) round = false;
                return toTimescaleFromBase(value, 1000, 1 / MPEG_TS_CLOCK_FREQ_HZ, round);
            }
            function toMpegTsClockFromTimescale(value, srcScale) {
                if (srcScale === void 0) srcScale = 1;
                return toTimescaleFromBase(value, MPEG_TS_CLOCK_FREQ_HZ, 1 / srcScale);
            }
            // CONCATENATED MODULE: ./src/remux/mp4-remuxer.js
            /**
 * fMP4 remuxer
*/ var MAX_SILENT_FRAME_DURATION_90KHZ = toMpegTsClockFromTimescale(10);
            var PTS_DTS_SHIFT_TOLERANCE_90KHZ = toMpegTsClockFromTimescale(0.2);
            var chromeVersion = null;
            var mp4_remuxer_MP4Remuxer = /*#__PURE__*/ function() {
                function MP4Remuxer(observer, config, typeSupported, vendor) {
                    this.observer = observer;
                    this.config = config;
                    this.typeSupported = typeSupported;
                    this.ISGenerated = false;
                    if (chromeVersion === null) {
                        var result = navigator.userAgent.match(/Chrome\/(\d+)/i);
                        chromeVersion = result ? parseInt(result[1]) : 0;
                    }
                }
                var _proto = MP4Remuxer.prototype;
                _proto.destroy = function destroy() {
                };
                _proto.resetTimeStamp = function resetTimeStamp(defaultTimeStamp) {
                    this._initPTS = this._initDTS = defaultTimeStamp;
                };
                _proto.resetInitSegment = function resetInitSegment() {
                    this.ISGenerated = false;
                };
                _proto.getVideoStartPts = function getVideoStartPts(videoSamples) {
                    var rolloverDetected = false;
                    var startPTS = videoSamples.reduce(function(minPTS, sample) {
                        var delta = sample.pts - minPTS;
                        if (delta < -4294967296) {
                            // 2^32, see PTSNormalize for reasoning, but we're hitting a rollover here, and we don't want that to impact the timeOffset calculation
                            rolloverDetected = true;
                            return PTSNormalize(minPTS, sample.pts);
                        } else if (delta > 0) return minPTS;
                        else return sample.pts;
                    }, videoSamples[0].pts);
                    if (rolloverDetected) logger["logger"].debug('PTS rollover detected');
                    return startPTS;
                };
                _proto.remux = function remux(audioTrack, videoTrack, id3Track, textTrack, timeOffset, contiguous, accurateTimeOffset) {
                    // generate Init Segment if needed
                    if (!this.ISGenerated) this.generateIS(audioTrack, videoTrack, timeOffset);
                    if (this.ISGenerated) {
                        var nbAudioSamples = audioTrack.samples.length;
                        var nbVideoSamples = videoTrack.samples.length;
                        var audioTimeOffset = timeOffset;
                        var videoTimeOffset = timeOffset;
                        if (nbAudioSamples && nbVideoSamples) {
                            // timeOffset is expected to be the offset of the first timestamp of this fragment (first DTS)
                            // if first audio DTS is not aligned with first video DTS then we need to take that into account
                            // when providing timeOffset to remuxAudio / remuxVideo. if we don't do that, there might be a permanent / small
                            // drift between audio and video streams
                            var startPTS = this.getVideoStartPts(videoTrack.samples);
                            var tsDelta = PTSNormalize(audioTrack.samples[0].pts, startPTS) - startPTS;
                            var audiovideoTimestampDelta = tsDelta / videoTrack.inputTimeScale;
                            audioTimeOffset += Math.max(0, audiovideoTimestampDelta);
                            videoTimeOffset += Math.max(0, -audiovideoTimestampDelta);
                        } // Purposefully remuxing audio before video, so that remuxVideo can use nextAudioPts, which is
                        // calculated in remuxAudio.
                        // logger.log('nb AAC samples:' + audioTrack.samples.length);
                        if (nbAudioSamples) {
                            // if initSegment was generated without video samples, regenerate it again
                            if (!audioTrack.timescale) {
                                logger["logger"].warn('regenerate InitSegment as audio detected');
                                this.generateIS(audioTrack, videoTrack, timeOffset);
                            }
                            var audioData = this.remuxAudio(audioTrack, audioTimeOffset, contiguous, accurateTimeOffset); // logger.log('nb AVC samples:' + videoTrack.samples.length);
                            if (nbVideoSamples) {
                                var audioTrackLength;
                                if (audioData) audioTrackLength = audioData.endPTS - audioData.startPTS;
                                 // if initSegment was generated without video samples, regenerate it again
                                if (!videoTrack.timescale) {
                                    logger["logger"].warn('regenerate InitSegment as video detected');
                                    this.generateIS(audioTrack, videoTrack, timeOffset);
                                }
                                this.remuxVideo(videoTrack, videoTimeOffset, contiguous, audioTrackLength);
                            }
                        } else // logger.log('nb AVC samples:' + videoTrack.samples.length);
                        if (nbVideoSamples) {
                            var videoData = this.remuxVideo(videoTrack, videoTimeOffset, contiguous, 0, accurateTimeOffset);
                            if (videoData && audioTrack.codec) this.remuxEmptyAudio(audioTrack, audioTimeOffset, contiguous, videoData);
                        }
                    } // logger.log('nb ID3 samples:' + audioTrack.samples.length);
                    if (id3Track.samples.length) this.remuxID3(id3Track, timeOffset);
                     // logger.log('nb ID3 samples:' + audioTrack.samples.length);
                    if (textTrack.samples.length) this.remuxText(textTrack, timeOffset);
                     // notify end of parsing
                    this.observer.trigger(events["default"].FRAG_PARSED);
                };
                _proto.generateIS = function generateIS(audioTrack, videoTrack, timeOffset) {
                    var observer = this.observer, audioSamples = audioTrack.samples, videoSamples = videoTrack.samples, typeSupported = this.typeSupported, container = 'audio/mp4', tracks = {
                    }, data = {
                        tracks: tracks
                    }, computePTSDTS = this._initPTS === undefined, initPTS, initDTS;
                    if (computePTSDTS) initPTS = initDTS = Infinity;
                    if (audioTrack.config && audioSamples.length) {
                        // let's use audio sampling rate as MP4 time scale.
                        // rationale is that there is a integer nb of audio frames per audio sample (1024 for AAC)
                        // using audio sampling rate here helps having an integer MP4 frame duration
                        // this avoids potential rounding issue and AV sync issue
                        audioTrack.timescale = audioTrack.samplerate;
                        logger["logger"].log("audio sampling rate : " + audioTrack.samplerate);
                        if (!audioTrack.isAAC) {
                            if (typeSupported.mpeg) {
                                // Chrome and Safari
                                container = 'audio/mpeg';
                                audioTrack.codec = '';
                            } else if (typeSupported.mp3) // Firefox
                            audioTrack.codec = 'mp3';
                        }
                        tracks.audio = {
                            container: container,
                            codec: audioTrack.codec,
                            initSegment: !audioTrack.isAAC && typeSupported.mpeg ? new Uint8Array() : mp4_generator.initSegment([
                                audioTrack
                            ]),
                            metadata: {
                                channelCount: audioTrack.channelCount
                            }
                        };
                        if (computePTSDTS) // remember first PTS of this demuxing context. for audio, PTS = DTS
                        initPTS = initDTS = audioSamples[0].pts - Math.round(audioTrack.inputTimeScale * timeOffset);
                    }
                    if (videoTrack.sps && videoTrack.pps && videoSamples.length) {
                        // let's use input time scale as MP4 video timescale
                        // we use input time scale straight away to avoid rounding issues on frame duration / cts computation
                        var inputTimeScale = videoTrack.inputTimeScale;
                        videoTrack.timescale = inputTimeScale;
                        tracks.video = {
                            container: 'video/mp4',
                            codec: videoTrack.codec,
                            initSegment: mp4_generator.initSegment([
                                videoTrack
                            ]),
                            metadata: {
                                width: videoTrack.width,
                                height: videoTrack.height
                            }
                        };
                        if (computePTSDTS) {
                            var startPTS = this.getVideoStartPts(videoSamples);
                            var startOffset = Math.round(inputTimeScale * timeOffset);
                            initDTS = Math.min(initDTS, PTSNormalize(videoSamples[0].dts, startPTS) - startOffset);
                            initPTS = Math.min(initPTS, startPTS - startOffset);
                            this.observer.trigger(events["default"].INIT_PTS_FOUND, {
                                initPTS: initPTS
                            });
                        }
                    } else if (computePTSDTS && tracks.audio) // initPTS found for audio-only stream with main and alt audio
                    this.observer.trigger(events["default"].INIT_PTS_FOUND, {
                        initPTS: initPTS
                    });
                    if (Object.keys(tracks).length) {
                        observer.trigger(events["default"].FRAG_PARSING_INIT_SEGMENT, data);
                        this.ISGenerated = true;
                        if (computePTSDTS) {
                            this._initPTS = initPTS;
                            this._initDTS = initDTS;
                        }
                    } else observer.trigger(events["default"].ERROR, {
                        type: errors["ErrorTypes"].MEDIA_ERROR,
                        details: errors["ErrorDetails"].FRAG_PARSING_ERROR,
                        fatal: false,
                        reason: 'no audio/video samples found'
                    });
                };
                _proto.remuxVideo = function remuxVideo(track, timeOffset, contiguous, audioTrackLength) {
                    var timeScale = track.timescale;
                    var inputSamples = track.samples;
                    var outputSamples = [];
                    var nbSamples = inputSamples.length;
                    var initPTS = this._initPTS;
                    var offset = 8;
                    var mp4SampleDuration;
                    var mdat;
                    var moof;
                    var firstDTS;
                    var lastDTS;
                    var minPTS = Number.POSITIVE_INFINITY;
                    var maxPTS = Number.NEGATIVE_INFINITY;
                    var ptsDtsShift = 0;
                    var sortSamples = false; // if parsed fragment is contiguous with last one, let's use last DTS value as reference
                    var nextAvcDts = this.nextAvcDts;
                    if (nbSamples === 0) return;
                    if (!contiguous) {
                        var pts = timeOffset * timeScale;
                        var cts = inputSamples[0].pts - PTSNormalize(inputSamples[0].dts, inputSamples[0].pts); // if not contiguous, let's use target timeOffset
                        nextAvcDts = pts - cts;
                    } // PTS is coded on 33bits, and can loop from -2^32 to 2^32
                    // PTSNormalize will make PTS/DTS value monotonic, we use last known DTS value as reference value
                    for(var i = 0; i < nbSamples; i++){
                        var sample = inputSamples[i];
                        sample.pts = PTSNormalize(sample.pts - initPTS, nextAvcDts);
                        sample.dts = PTSNormalize(sample.dts - initPTS, nextAvcDts);
                        if (sample.dts > sample.pts) ptsDtsShift = Math.max(Math.min(ptsDtsShift, sample.pts - sample.dts), -1 * PTS_DTS_SHIFT_TOLERANCE_90KHZ);
                        if (sample.dts < inputSamples[i > 0 ? i - 1 : i].dts) sortSamples = true;
                    } // sort video samples by DTS then PTS then demux id order
                    if (sortSamples) inputSamples.sort(function(a, b) {
                        var deltadts = a.dts - b.dts;
                        var deltapts = a.pts - b.pts;
                        return deltadts || deltapts || a.id - b.id;
                    });
                     // Get first/last DTS
                    firstDTS = inputSamples[0].dts;
                    lastDTS = inputSamples[nbSamples - 1].dts; // on Safari let's signal the same sample duration for all samples
                    // sample duration (as expected by trun MP4 boxes), should be the delta between sample DTS
                    // set this constant duration as being the avg delta between consecutive DTS.
                    var averageSampleDuration = Math.round((lastDTS - firstDTS) / (nbSamples - 1)); // handle broken streams with PTS < DTS, tolerance up 0.2 seconds
                    if (ptsDtsShift < 0) {
                        if (ptsDtsShift < averageSampleDuration * -2) {
                            // Fix for "CNN special report, with CC" in test-streams (including Safari browser)
                            // With large PTS < DTS errors such as this, we want to correct CTS while maintaining increasing DTS values
                            logger["logger"].warn("PTS < DTS detected in video samples, offsetting DTS from PTS by " + toMsFromMpegTsClock(-averageSampleDuration, true) + " ms");
                            var lastDts = ptsDtsShift;
                            for(var _i = 0; _i < nbSamples; _i++){
                                inputSamples[_i].dts = lastDts = Math.max(lastDts, inputSamples[_i].pts - averageSampleDuration);
                                inputSamples[_i].pts = Math.max(lastDts, inputSamples[_i].pts);
                            }
                        } else {
                            // Fix for "Custom IV with bad PTS DTS" in test-streams
                            // With smaller PTS < DTS errors we can simply move all DTS back. This increases CTS without causing buffer gaps or decode errors in Safari
                            logger["logger"].warn("PTS < DTS detected in video samples, shifting DTS by " + toMsFromMpegTsClock(ptsDtsShift, true) + " ms to overcome this issue");
                            for(var _i2 = 0; _i2 < nbSamples; _i2++)inputSamples[_i2].dts = inputSamples[_i2].dts + ptsDtsShift;
                        }
                        firstDTS = inputSamples[0].dts;
                        lastDTS = inputSamples[nbSamples - 1].dts;
                    } // if fragment are contiguous, detect hole/overlapping between fragments
                    if (contiguous) {
                        // check timestamp continuity across consecutive fragments (this is to remove inter-fragment gap/hole)
                        var delta = firstDTS - nextAvcDts;
                        var foundHole = delta > averageSampleDuration;
                        var foundOverlap = delta < -1;
                        if (foundHole || foundOverlap) {
                            if (foundHole) logger["logger"].warn("AVC: " + toMsFromMpegTsClock(delta, true) + " ms (" + delta + "dts) hole between fragments detected, filling it");
                            else logger["logger"].warn("AVC: " + toMsFromMpegTsClock(-delta, true) + " ms (" + delta + "dts) overlapping between fragments detected");
                            firstDTS = nextAvcDts;
                            var firstPTS = inputSamples[0].pts - delta;
                            inputSamples[0].dts = firstDTS;
                            inputSamples[0].pts = firstPTS;
                            logger["logger"].log("Video: First PTS/DTS adjusted: " + toMsFromMpegTsClock(firstPTS, true) + "/" + toMsFromMpegTsClock(firstDTS, true) + ", delta: " + toMsFromMpegTsClock(delta, true) + " ms");
                        }
                    }
                    if (chromeVersion && chromeVersion < 75) firstDTS = Math.max(0, firstDTS);
                    var nbNalu = 0;
                    var naluLen = 0;
                    for(var _i3 = 0; _i3 < nbSamples; _i3++){
                        // compute total/avc sample length and nb of NAL units
                        var _sample = inputSamples[_i3];
                        var units = _sample.units;
                        var nbUnits = units.length;
                        var sampleLen = 0;
                        for(var j = 0; j < nbUnits; j++)sampleLen += units[j].data.length;
                        naluLen += sampleLen;
                        nbNalu += nbUnits;
                        _sample.length = sampleLen; // normalize PTS/DTS
                        // ensure sample monotonic DTS
                        _sample.dts = Math.max(_sample.dts, firstDTS); // ensure that computed value is greater or equal than sample DTS
                        _sample.pts = Math.max(_sample.pts, _sample.dts, 0);
                        minPTS = Math.min(_sample.pts, minPTS);
                        maxPTS = Math.max(_sample.pts, maxPTS);
                    }
                    lastDTS = inputSamples[nbSamples - 1].dts;
                    /* concatenate the video data and construct the mdat in place
      (need 8 more bytes to fill length and mpdat type) */ var mdatSize = naluLen + 4 * nbNalu + 8;
                    try {
                        mdat = new Uint8Array(mdatSize);
                    } catch (err) {
                        this.observer.trigger(events["default"].ERROR, {
                            type: errors["ErrorTypes"].MUX_ERROR,
                            details: errors["ErrorDetails"].REMUX_ALLOC_ERROR,
                            fatal: false,
                            bytes: mdatSize,
                            reason: "fail allocating video mdat " + mdatSize
                        });
                        return;
                    }
                    var view = new DataView(mdat.buffer);
                    view.setUint32(0, mdatSize);
                    mdat.set(mp4_generator.types.mdat, 4);
                    for(var _i4 = 0; _i4 < nbSamples; _i4++){
                        var avcSample = inputSamples[_i4];
                        var avcSampleUnits = avcSample.units;
                        var mp4SampleLength = 0;
                        var compositionTimeOffset = void 0; // convert NALU bitstream to MP4 format (prepend NALU with size field)
                        for(var _j = 0, _nbUnits = avcSampleUnits.length; _j < _nbUnits; _j++){
                            var unit = avcSampleUnits[_j];
                            var unitData = unit.data;
                            var unitDataLen = unit.data.byteLength;
                            view.setUint32(offset, unitDataLen);
                            offset += 4;
                            mdat.set(unitData, offset);
                            offset += unitDataLen;
                            mp4SampleLength += 4 + unitDataLen;
                        } // expected sample duration is the Decoding Timestamp diff of consecutive samples
                        if (_i4 < nbSamples - 1) mp4SampleDuration = inputSamples[_i4 + 1].dts - avcSample.dts;
                        else {
                            var config = this.config;
                            var lastFrameDuration = avcSample.dts - inputSamples[_i4 > 0 ? _i4 - 1 : _i4].dts;
                            if (config.stretchShortVideoTrack) {
                                // In some cases, a segment's audio track duration may exceed the video track duration.
                                // Since we've already remuxed audio, and we know how long the audio track is, we look to
                                // see if the delta to the next segment is longer than maxBufferHole.
                                // If so, playback would potentially get stuck, so we artificially inflate
                                // the duration of the last frame to minimize any potential gap between segments.
                                var maxBufferHole = config.maxBufferHole;
                                var gapTolerance = Math.floor(maxBufferHole * timeScale);
                                var deltaToFrameEnd = (audioTrackLength ? minPTS + audioTrackLength * timeScale : this.nextAudioPts) - avcSample.pts;
                                if (deltaToFrameEnd > gapTolerance) {
                                    // We subtract lastFrameDuration from deltaToFrameEnd to try to prevent any video
                                    // frame overlap. maxBufferHole should be >> lastFrameDuration anyway.
                                    mp4SampleDuration = deltaToFrameEnd - lastFrameDuration;
                                    if (mp4SampleDuration < 0) mp4SampleDuration = lastFrameDuration;
                                    logger["logger"].log("It is approximately " + toMsFromMpegTsClock(deltaToFrameEnd, false) + " ms to the next segment; using duration " + toMsFromMpegTsClock(mp4SampleDuration, false) + " ms for the last video frame.");
                                } else mp4SampleDuration = lastFrameDuration;
                            } else mp4SampleDuration = lastFrameDuration;
                        }
                        compositionTimeOffset = Math.round(avcSample.pts - avcSample.dts); // console.log('PTS/DTS/initDTS/normPTS/normDTS/relative PTS : ${avcSample.pts}/${avcSample.dts}/${initDTS}/${ptsnorm}/${dtsnorm}/${(avcSample.pts/4294967296).toFixed(3)}');
                        outputSamples.push({
                            size: mp4SampleLength,
                            // constant duration
                            duration: mp4SampleDuration,
                            cts: compositionTimeOffset,
                            flags: {
                                isLeading: 0,
                                isDependedOn: 0,
                                hasRedundancy: 0,
                                degradPrio: 0,
                                dependsOn: avcSample.key ? 2 : 1,
                                isNonSync: avcSample.key ? 0 : 1
                            }
                        });
                    } // next AVC sample DTS should be equal to last sample DTS + last sample duration (in PES timescale)
                    this.nextAvcDts = lastDTS + mp4SampleDuration;
                    var dropped = track.dropped;
                    track.nbNalu = 0;
                    track.dropped = 0;
                    if (outputSamples.length && navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
                        var flags = outputSamples[0].flags; // chrome workaround, mark first sample as being a Random Access Point to avoid sourcebuffer append issue
                        // https://code.google.com/p/chromium/issues/detail?id=229412
                        flags.dependsOn = 2;
                        flags.isNonSync = 0;
                    }
                    track.samples = outputSamples;
                    moof = mp4_generator.moof(track.sequenceNumber++, firstDTS, track);
                    track.samples = [];
                    var data = {
                        data1: moof,
                        data2: mdat,
                        startPTS: minPTS / timeScale,
                        endPTS: (maxPTS + mp4SampleDuration) / timeScale,
                        startDTS: firstDTS / timeScale,
                        endDTS: this.nextAvcDts / timeScale,
                        type: 'video',
                        hasAudio: false,
                        hasVideo: true,
                        nb: outputSamples.length,
                        dropped: dropped
                    };
                    this.observer.trigger(events["default"].FRAG_PARSING_DATA, data);
                    return data;
                };
                _proto.remuxAudio = function remuxAudio(track, timeOffset, contiguous, accurateTimeOffset) {
                    var inputTimeScale = track.inputTimeScale;
                    var mp4timeScale = track.timescale;
                    var scaleFactor = inputTimeScale / mp4timeScale;
                    var mp4SampleDuration = track.isAAC ? 1024 : 1152;
                    var inputSampleDuration = mp4SampleDuration * scaleFactor;
                    var initPTS = this._initPTS;
                    var rawMPEG = !track.isAAC && this.typeSupported.mpeg;
                    var mp4Sample;
                    var fillFrame;
                    var mdat;
                    var moof;
                    var firstPTS;
                    var lastPTS;
                    var offset = rawMPEG ? 0 : 8;
                    var inputSamples = track.samples;
                    var outputSamples = [];
                    var nextAudioPts = this.nextAudioPts; // for audio samples, also consider consecutive fragments as being contiguous (even if a level switch occurs),
                    // for sake of clarity:
                    // consecutive fragments are frags with
                    //  - less than 100ms gaps between new time offset (if accurate) and next expected PTS OR
                    //  - less than 20 audio frames distance
                    // contiguous fragments are consecutive fragments from same quality level (same level, new SN = old SN + 1)
                    // this helps ensuring audio continuity
                    // and this also avoids audio glitches/cut when switching quality, or reporting wrong duration on first audio frame
                    contiguous |= inputSamples.length && nextAudioPts && (accurateTimeOffset && Math.abs(timeOffset - nextAudioPts / inputTimeScale) < 0.1 || Math.abs(inputSamples[0].pts - nextAudioPts - initPTS) < 20 * inputSampleDuration); // compute normalized PTS
                    inputSamples.forEach(function(sample) {
                        sample.pts = sample.dts = PTSNormalize(sample.pts - initPTS, timeOffset * inputTimeScale);
                    }); // filter out sample with negative PTS that are not playable anyway
                    // if we don't remove these negative samples, they will shift all audio samples forward.
                    // leading to audio overlap between current / next fragment
                    inputSamples = inputSamples.filter(function(sample) {
                        return sample.pts >= 0;
                    }); // in case all samples have negative PTS, and have been filtered out, return now
                    if (inputSamples.length === 0) return;
                    if (!contiguous) {
                        if (!accurateTimeOffset) // if frag are mot contiguous and if we cant trust time offset, let's use first sample PTS as next audio PTS
                        nextAudioPts = inputSamples[0].pts;
                        else // if timeOffset is accurate, let's use it as predicted next audio PTS
                        nextAudioPts = Math.max(0, timeOffset * inputTimeScale);
                    } // If the audio track is missing samples, the frames seem to get "left-shifted" within the
                    // resulting mp4 segment, causing sync issues and leaving gaps at the end of the audio segment.
                    // In an effort to prevent this from happening, we inject frames here where there are gaps.
                    // When possible, we inject a silent frame; when that's not possible, we duplicate the last
                    // frame.
                    if (track.isAAC) {
                        var maxAudioFramesDrift = this.config.maxAudioFramesDrift;
                        for(var i = 0, nextPts = nextAudioPts; i < inputSamples.length;){
                            // First, let's see how far off this frame is from where we expect it to be
                            var sample1 = inputSamples[i];
                            var pts = sample1.pts;
                            var delta = pts - nextPts; // If we're overlapping by more than a duration, drop this sample
                            if (delta <= -maxAudioFramesDrift * inputSampleDuration) {
                                if (contiguous || i > 0) {
                                    logger["logger"].warn("Dropping 1 audio frame @ " + toMsFromMpegTsClock(nextPts, true) / 1000 + "s due to " + toMsFromMpegTsClock(delta, true) + " ms overlap.");
                                    inputSamples.splice(i, 1); // Don't touch nextPtsNorm or i
                                } else {
                                    // When changing qualities we can't trust that audio has been appended up to nextAudioPts
                                    // Warn about the overlap but do not drop samples as that can introduce buffer gaps
                                    logger["logger"].warn("Audio frame @ " + toMsFromMpegTsClock(pts, true) / 1000 + "s overlaps nextAudioPts by " + toMsFromMpegTsClock(delta, true) + " ms.");
                                    nextPts = pts + inputSampleDuration;
                                    i++;
                                }
                            } else if (delta >= maxAudioFramesDrift * inputSampleDuration && delta < MAX_SILENT_FRAME_DURATION_90KHZ && nextPts) {
                                var missing = Math.round(delta / inputSampleDuration);
                                logger["logger"].warn("Injecting " + missing + " audio frames @ " + toMsFromMpegTsClock(nextPts, true) / 1000 + "s due to " + toMsFromMpegTsClock(delta, true) + " ms gap.");
                                for(var j = 0; j < missing; j++){
                                    var newStamp = Math.max(nextPts, 0);
                                    fillFrame = aac_helper.getSilentFrame(track.manifestCodec || track.codec, track.channelCount);
                                    if (!fillFrame) {
                                        logger["logger"].log('Unable to get silent frame for given audio codec; duplicating last frame instead.');
                                        fillFrame = sample1.unit.subarray();
                                    }
                                    inputSamples.splice(i, 0, {
                                        unit: fillFrame,
                                        pts: newStamp,
                                        dts: newStamp
                                    });
                                    nextPts += inputSampleDuration;
                                    i++;
                                } // Adjust sample to next expected pts
                                sample1.pts = sample1.dts = nextPts;
                                nextPts += inputSampleDuration;
                                i++;
                            } else {
                                sample1.pts = sample1.dts = nextPts;
                                nextPts += inputSampleDuration;
                                i++;
                            }
                        }
                    } // compute mdat size, as we eventually filtered/added some samples
                    var nbSamples = inputSamples.length;
                    var mdatSize = 0;
                    while(nbSamples--)mdatSize += inputSamples[nbSamples].unit.byteLength;
                    for(var _j2 = 0, _nbSamples = inputSamples.length; _j2 < _nbSamples; _j2++){
                        var audioSample = inputSamples[_j2];
                        var unit = audioSample.unit;
                        var _pts = audioSample.pts; // logger.log(`Audio/PTS:${toMsFromMpegTsClock(pts, true)}`);
                        // if not first sample
                        if (lastPTS !== undefined && mp4Sample) mp4Sample.duration = Math.round((_pts - lastPTS) / scaleFactor);
                        else {
                            var _delta = _pts - nextAudioPts;
                            var numMissingFrames = 0; // if fragment are contiguous, detect hole/overlapping between fragments
                            // contiguous fragments are consecutive fragments from same quality level (same level, new SN = old SN + 1)
                            if (contiguous && track.isAAC) // log delta
                            {
                                if (_delta) {
                                    if (_delta > 0 && _delta < MAX_SILENT_FRAME_DURATION_90KHZ) {
                                        // Q: why do we have to round here, shouldn't this always result in an integer if timestamps are correct,
                                        // and if not, shouldn't we actually Math.ceil() instead?
                                        numMissingFrames = Math.round((_pts - nextAudioPts) / inputSampleDuration);
                                        logger["logger"].log(toMsFromMpegTsClock(_delta, true) + " ms hole between AAC samples detected,filling it");
                                        if (numMissingFrames > 0) {
                                            fillFrame = aac_helper.getSilentFrame(track.manifestCodec || track.codec, track.channelCount);
                                            if (!fillFrame) fillFrame = unit.subarray();
                                            mdatSize += numMissingFrames * fillFrame.length;
                                        } // if we have frame overlap, overlapping for more than half a frame duraion
                                    } else if (_delta < -12) {
                                        // drop overlapping audio frames... browser will deal with it
                                        logger["logger"].log("drop overlapping AAC sample, expected/parsed/delta: " + toMsFromMpegTsClock(nextAudioPts, true) + " ms / " + toMsFromMpegTsClock(_pts, true) + " ms / " + toMsFromMpegTsClock(-_delta, true) + " ms");
                                        mdatSize -= unit.byteLength;
                                        continue;
                                    } // set PTS/DTS to expected PTS/DTS
                                    _pts = nextAudioPts;
                                }
                            } // remember first PTS of our audioSamples
                            firstPTS = _pts;
                            if (mdatSize > 0) {
                                mdatSize += offset;
                                try {
                                    mdat = new Uint8Array(mdatSize);
                                } catch (err) {
                                    this.observer.trigger(events["default"].ERROR, {
                                        type: errors["ErrorTypes"].MUX_ERROR,
                                        details: errors["ErrorDetails"].REMUX_ALLOC_ERROR,
                                        fatal: false,
                                        bytes: mdatSize,
                                        reason: "fail allocating audio mdat " + mdatSize
                                    });
                                    return;
                                }
                                if (!rawMPEG) {
                                    var view = new DataView(mdat.buffer);
                                    view.setUint32(0, mdatSize);
                                    mdat.set(mp4_generator.types.mdat, 4);
                                }
                            } else // no audio samples
                            return;
                            for(var _i5 = 0; _i5 < numMissingFrames; _i5++){
                                fillFrame = aac_helper.getSilentFrame(track.manifestCodec || track.codec, track.channelCount);
                                if (!fillFrame) {
                                    logger["logger"].log('Unable to get silent frame for given audio codec; duplicating this frame instead.');
                                    fillFrame = unit.subarray();
                                }
                                mdat.set(fillFrame, offset);
                                offset += fillFrame.byteLength;
                                mp4Sample = {
                                    size: fillFrame.byteLength,
                                    cts: 0,
                                    duration: 1024,
                                    flags: {
                                        isLeading: 0,
                                        isDependedOn: 0,
                                        hasRedundancy: 0,
                                        degradPrio: 0,
                                        dependsOn: 1
                                    }
                                };
                                outputSamples.push(mp4Sample);
                            }
                        }
                        mdat.set(unit, offset);
                        var unitLen = unit.byteLength;
                        offset += unitLen; // console.log('PTS/DTS/initDTS/normPTS/normDTS/relative PTS : ${audioSample.pts}/${audioSample.dts}/${initDTS}/${ptsnorm}/${dtsnorm}/${(audioSample.pts/4294967296).toFixed(3)}');
                        mp4Sample = {
                            size: unitLen,
                            cts: 0,
                            duration: 0,
                            flags: {
                                isLeading: 0,
                                isDependedOn: 0,
                                hasRedundancy: 0,
                                degradPrio: 0,
                                dependsOn: 1
                            }
                        };
                        outputSamples.push(mp4Sample);
                        lastPTS = _pts;
                    }
                    var lastSampleDuration = 0;
                    nbSamples = outputSamples.length; // set last sample duration as being identical to previous sample
                    if (nbSamples >= 2) {
                        lastSampleDuration = outputSamples[nbSamples - 2].duration;
                        mp4Sample.duration = lastSampleDuration;
                    }
                    if (nbSamples) {
                        // next audio sample PTS should be equal to last sample PTS + duration
                        this.nextAudioPts = nextAudioPts = lastPTS + scaleFactor * lastSampleDuration; // logger.log('Audio/PTS/PTSend:' + audioSample.pts.toFixed(0) + '/' + this.nextAacDts.toFixed(0));
                        track.samples = outputSamples;
                        if (rawMPEG) moof = new Uint8Array();
                        else moof = mp4_generator.moof(track.sequenceNumber++, firstPTS / scaleFactor, track);
                        track.samples = [];
                        var start = firstPTS / inputTimeScale;
                        var end = nextAudioPts / inputTimeScale;
                        var audioData = {
                            data1: moof,
                            data2: mdat,
                            startPTS: start,
                            endPTS: end,
                            startDTS: start,
                            endDTS: end,
                            type: 'audio',
                            hasAudio: true,
                            hasVideo: false,
                            nb: nbSamples
                        };
                        this.observer.trigger(events["default"].FRAG_PARSING_DATA, audioData);
                        return audioData;
                    }
                    return null;
                };
                _proto.remuxEmptyAudio = function remuxEmptyAudio(track, timeOffset, contiguous, videoData) {
                    var inputTimeScale = track.inputTimeScale;
                    var mp4timeScale = track.samplerate ? track.samplerate : inputTimeScale;
                    var scaleFactor = inputTimeScale / mp4timeScale;
                    var nextAudioPts = this.nextAudioPts; // sync with video's timestamp
                    var startDTS = (nextAudioPts !== undefined ? nextAudioPts : videoData.startDTS * inputTimeScale) + this._initDTS;
                    var endDTS = videoData.endDTS * inputTimeScale + this._initDTS; // one sample's duration value
                    var sampleDuration = 1024;
                    var frameDuration = scaleFactor * sampleDuration; // samples count of this segment's duration
                    var nbSamples = Math.ceil((endDTS - startDTS) / frameDuration); // silent frame
                    var silentFrame = aac_helper.getSilentFrame(track.manifestCodec || track.codec, track.channelCount);
                    logger["logger"].warn('remux empty Audio'); // Can't remux if we can't generate a silent frame...
                    if (!silentFrame) {
                        logger["logger"].trace('Unable to remuxEmptyAudio since we were unable to get a silent frame for given audio codec!');
                        return;
                    }
                    var samples = [];
                    for(var i = 0; i < nbSamples; i++){
                        var stamp = startDTS + i * frameDuration;
                        samples.push({
                            unit: silentFrame,
                            pts: stamp,
                            dts: stamp
                        });
                    }
                    track.samples = samples;
                    this.remuxAudio(track, timeOffset, contiguous);
                };
                _proto.remuxID3 = function remuxID3(track, timeOffset) {
                    var length = track.samples.length;
                    if (!length) return;
                    var inputTimeScale = track.inputTimeScale;
                    var initPTS = this._initPTS;
                    var initDTS = this._initDTS; // consume samples
                    for(var index = 0; index < length; index++){
                        var sample = track.samples[index]; // setting id3 pts, dts to relative time
                        // using this._initPTS and this._initDTS to calculate relative time
                        sample.pts = PTSNormalize(sample.pts - initPTS, timeOffset * inputTimeScale) / inputTimeScale;
                        sample.dts = PTSNormalize(sample.dts - initDTS, timeOffset * inputTimeScale) / inputTimeScale;
                    }
                    this.observer.trigger(events["default"].FRAG_PARSING_METADATA, {
                        samples: track.samples
                    });
                    track.samples = [];
                };
                _proto.remuxText = function remuxText(track, timeOffset) {
                    var length = track.samples.length;
                    var inputTimeScale = track.inputTimeScale;
                    var initPTS = this._initPTS; // consume samples
                    if (length) {
                        for(var index = 0; index < length; index++){
                            var sample = track.samples[index]; // setting text pts, dts to relative time
                            // using this._initPTS and this._initDTS to calculate relative time
                            sample.pts = PTSNormalize(sample.pts - initPTS, timeOffset * inputTimeScale) / inputTimeScale;
                        }
                        track.samples.sort(function(a, b) {
                            return a.pts - b.pts;
                        });
                        this.observer.trigger(events["default"].FRAG_PARSING_USERDATA, {
                            samples: track.samples
                        });
                    }
                    track.samples = [];
                };
                return MP4Remuxer;
            }();
            function PTSNormalize(value, reference) {
                var offset;
                if (reference === undefined) return value;
                if (reference < value) // - 2^33
                offset = -8589934592;
                else // + 2^33
                offset = 8589934592;
                /* PTS is 33bit (from 0 to 2^33 -1)
    if diff between value and reference is bigger than half of the amplitude (2^32) then it means that
    PTS looping occured. fill the gap */ while(Math.abs(value - reference) > 4294967296)value += offset;
                return value;
            }
            /* harmony default export */ var mp4_remuxer = mp4_remuxer_MP4Remuxer;
            // CONCATENATED MODULE: ./src/remux/passthrough-remuxer.js
            /**
 * passthrough remuxer
*/ var passthrough_remuxer_PassThroughRemuxer = /*#__PURE__*/ function() {
                function PassThroughRemuxer(observer) {
                    this.observer = observer;
                }
                var _proto = PassThroughRemuxer.prototype;
                _proto.destroy = function destroy() {
                };
                _proto.resetTimeStamp = function resetTimeStamp() {
                };
                _proto.resetInitSegment = function resetInitSegment() {
                };
                _proto.remux = function remux(audioTrack, videoTrack, id3Track, textTrack, timeOffset, contiguous, accurateTimeOffset, rawData) {
                    var observer = this.observer;
                    var streamType = '';
                    if (audioTrack) streamType += 'audio';
                    if (videoTrack) streamType += 'video';
                    observer.trigger(events["default"].FRAG_PARSING_DATA, {
                        data1: rawData,
                        startPTS: timeOffset,
                        startDTS: timeOffset,
                        type: streamType,
                        hasAudio: !!audioTrack,
                        hasVideo: !!videoTrack,
                        nb: 1,
                        dropped: 0
                    }); // notify end of parsing
                    observer.trigger(events["default"].FRAG_PARSED);
                };
                return PassThroughRemuxer;
            }();
            /* harmony default export */ var passthrough_remuxer = passthrough_remuxer_PassThroughRemuxer;
            // CONCATENATED MODULE: ./src/demux/demuxer-inline.js
            /**
 *
 * inline demuxer: probe fragments and instantiate
 * appropriate demuxer depending on content type (TSDemuxer, AACDemuxer, ...)
 *
 */ // see https://stackoverflow.com/a/11237259/589493
            var global = Object(get_self_scope["getSelfScope"])(); // safeguard for code that might run both on worker and main thread
            var now; // performance.now() not available on WebWorker, at least on Safari Desktop
            try {
                now = global.performance.now.bind(global.performance);
            } catch (err) {
                logger["logger"].debug('Unable to use Performance API on this environment');
                now = global.Date.now;
            }
            var demuxer_inline_DemuxerInline = /*#__PURE__*/ function() {
                function DemuxerInline(observer, typeSupported, config, vendor) {
                    this.observer = observer;
                    this.typeSupported = typeSupported;
                    this.config = config;
                    this.vendor = vendor;
                }
                var _proto = DemuxerInline.prototype;
                _proto.destroy = function destroy() {
                    var demuxer = this.demuxer;
                    if (demuxer) demuxer.destroy();
                };
                _proto.push = function push(data, decryptdata, initSegment, audioCodec, videoCodec, timeOffset, discontinuity, trackSwitch, contiguous, duration, accurateTimeOffset, defaultInitPTS) {
                    var _this = this;
                    if (data.byteLength > 0 && decryptdata != null && decryptdata.key != null && decryptdata.method === 'AES-128') {
                        var decrypter = this.decrypter;
                        if (decrypter == null) decrypter = this.decrypter = new crypt_decrypter["default"](this.observer, this.config);
                        var startTime = now();
                        decrypter.decrypt(data, decryptdata.key.buffer, decryptdata.iv.buffer, function(decryptedData) {
                            var endTime = now();
                            _this.observer.trigger(events["default"].FRAG_DECRYPTED, {
                                stats: {
                                    tstart: startTime,
                                    tdecrypt: endTime
                                }
                            });
                            _this.pushDecrypted(new Uint8Array(decryptedData), decryptdata, new Uint8Array(initSegment), audioCodec, videoCodec, timeOffset, discontinuity, trackSwitch, contiguous, duration, accurateTimeOffset, defaultInitPTS);
                        });
                    } else this.pushDecrypted(new Uint8Array(data), decryptdata, new Uint8Array(initSegment), audioCodec, videoCodec, timeOffset, discontinuity, trackSwitch, contiguous, duration, accurateTimeOffset, defaultInitPTS);
                };
                _proto.pushDecrypted = function pushDecrypted(data, decryptdata, initSegment, audioCodec, videoCodec, timeOffset, discontinuity, trackSwitch, contiguous, duration, accurateTimeOffset, defaultInitPTS) {
                    var demuxer = this.demuxer;
                    var remuxer = this.remuxer;
                    if (!demuxer || // we might switch from content type (AAC container to TS container, or TS to fmp4 for example)
                    discontinuity || trackSwitch) {
                        var observer = this.observer;
                        var typeSupported = this.typeSupported;
                        var config = this.config; // probing order is TS/MP4/AAC/MP3
                        var muxConfig = [
                            {
                                demux: tsdemuxer,
                                remux: mp4_remuxer
                            },
                            {
                                demux: mp4demuxer["default"],
                                remux: passthrough_remuxer
                            },
                            {
                                demux: aacdemuxer,
                                remux: mp4_remuxer
                            },
                            {
                                demux: mp3demuxer,
                                remux: mp4_remuxer
                            }
                        ]; // probe for content type
                        var mux;
                        for(var i = 0, len = muxConfig.length; i < len; i++){
                            mux = muxConfig[i];
                            if (mux.demux.probe(data)) break;
                        }
                        if (!mux) {
                            observer.trigger(events["default"].ERROR, {
                                type: errors["ErrorTypes"].MEDIA_ERROR,
                                details: errors["ErrorDetails"].FRAG_PARSING_ERROR,
                                fatal: true,
                                reason: 'no demux matching with content found'
                            });
                            return;
                        } // so let's check that current remuxer and demuxer are still valid
                        if (!remuxer || !(remuxer instanceof mux.remux)) remuxer = new mux.remux(observer, config, typeSupported, this.vendor);
                        if (!demuxer || !(demuxer instanceof mux.demux)) {
                            demuxer = new mux.demux(observer, remuxer, config, typeSupported);
                            this.probe = mux.demux.probe;
                        }
                        this.demuxer = demuxer;
                        this.remuxer = remuxer;
                    }
                    if (discontinuity || trackSwitch) {
                        demuxer.resetInitSegment(initSegment, audioCodec, videoCodec, duration);
                        remuxer.resetInitSegment();
                    }
                    if (discontinuity) {
                        demuxer.resetTimeStamp(defaultInitPTS);
                        remuxer.resetTimeStamp(defaultInitPTS);
                    }
                    if (typeof demuxer.setDecryptData === 'function') demuxer.setDecryptData(decryptdata);
                    demuxer.append(data, timeOffset, contiguous, accurateTimeOffset);
                };
                return DemuxerInline;
            }();
            /* harmony default export */ var demuxer_inline = __webpack_exports__["default"] = demuxer_inline_DemuxerInline;
        /***/ },
        /***/ "./src/demux/demuxer-worker.js": function(module, __webpack_exports__, __webpack_require__) {
            "use strict";
            __webpack_require__.r(__webpack_exports__);
            /* harmony import */ var _demux_demuxer_inline__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../demux/demuxer-inline */ "./src/demux/demuxer-inline.js");
            /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../events */ "./src/events.js");
            /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.js");
            /* harmony import */ var eventemitter3__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! eventemitter3 */ "./node_modules/eventemitter3/index.js");
            /* harmony import */ var eventemitter3__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/ __webpack_require__.n(eventemitter3__WEBPACK_IMPORTED_MODULE_3__);
            /* demuxer web worker.
 *  - listen to worker message, and trigger DemuxerInline upon reception of Fragments.
 *  - provides MP4 Boxes back to main thread using [transferable objects](https://developers.google.com/web/updates/2011/12/Transferable-Objects-Lightning-Fast) in order to minimize message passing overhead.
 */ var DemuxerWorker = function DemuxerWorker(self) {
                // observer setup
                var observer = new eventemitter3__WEBPACK_IMPORTED_MODULE_3__["EventEmitter"]();
                observer.trigger = function trigger(event) {
                    for(var _len = arguments.length, data = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++)data[_key - 1] = arguments[_key];
                    observer.emit.apply(observer, [
                        event,
                        event
                    ].concat(data));
                };
                observer.off = function off(event) {
                    for(var _len2 = arguments.length, data = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++)data[_key2 - 1] = arguments[_key2];
                    observer.removeListener.apply(observer, [
                        event
                    ].concat(data));
                };
                var forwardMessage = function forwardMessage(ev, data) {
                    self.postMessage({
                        event: ev,
                        data: data
                    });
                };
                self.addEventListener('message', function(ev) {
                    var data = ev.data; // console.log('demuxer cmd:' + data.cmd);
                    switch(data.cmd){
                        case 'init':
                            var config = JSON.parse(data.config);
                            self.demuxer = new _demux_demuxer_inline__WEBPACK_IMPORTED_MODULE_0__["default"](observer, data.typeSupported, config, data.vendor);
                            Object(_utils_logger__WEBPACK_IMPORTED_MODULE_2__["enableLogs"])(config.debug); // signal end of worker init
                            forwardMessage('init', null);
                            break;
                        case 'demux':
                            self.demuxer.push(data.data, data.decryptdata, data.initSegment, data.audioCodec, data.videoCodec, data.timeOffset, data.discontinuity, data.trackSwitch, data.contiguous, data.duration, data.accurateTimeOffset, data.defaultInitPTS);
                            break;
                        default:
                            break;
                    }
                }); // forward events to main thread
                observer.on(_events__WEBPACK_IMPORTED_MODULE_1__["default"].FRAG_DECRYPTED, forwardMessage);
                observer.on(_events__WEBPACK_IMPORTED_MODULE_1__["default"].FRAG_PARSING_INIT_SEGMENT, forwardMessage);
                observer.on(_events__WEBPACK_IMPORTED_MODULE_1__["default"].FRAG_PARSED, forwardMessage);
                observer.on(_events__WEBPACK_IMPORTED_MODULE_1__["default"].ERROR, forwardMessage);
                observer.on(_events__WEBPACK_IMPORTED_MODULE_1__["default"].FRAG_PARSING_METADATA, forwardMessage);
                observer.on(_events__WEBPACK_IMPORTED_MODULE_1__["default"].FRAG_PARSING_USERDATA, forwardMessage);
                observer.on(_events__WEBPACK_IMPORTED_MODULE_1__["default"].INIT_PTS_FOUND, forwardMessage); // special case for FRAG_PARSING_DATA: pass data1/data2 as transferable object (no copy)
                observer.on(_events__WEBPACK_IMPORTED_MODULE_1__["default"].FRAG_PARSING_DATA, function(ev, data) {
                    var transferable = [];
                    var message = {
                        event: ev,
                        data: data
                    };
                    if (data.data1) {
                        message.data1 = data.data1.buffer;
                        transferable.push(data.data1.buffer);
                        delete data.data1;
                    }
                    if (data.data2) {
                        message.data2 = data.data2.buffer;
                        transferable.push(data.data2.buffer);
                        delete data.data2;
                    }
                    self.postMessage(message, transferable);
                });
            };
            /* harmony default export */ __webpack_exports__["default"] = DemuxerWorker;
        /***/ },
        /***/ "./src/demux/id3.js": function(module, __webpack_exports__, __webpack_require__) {
            "use strict";
            __webpack_require__.r(__webpack_exports__);
            /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "utf8ArrayToStr", function() {
                return utf8ArrayToStr;
            });
            /* harmony import */ var _utils_get_self_scope__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/get-self-scope */ "./src/utils/get-self-scope.js");
            /**
 * ID3 parser
 */ var ID31 = /*#__PURE__*/ function() {
                function ID3() {
                }
                /**
   * Returns true if an ID3 header can be found at offset in data
   * @param {Uint8Array} data - The data to search in
   * @param {number} offset - The offset at which to start searching
   * @return {boolean} - True if an ID3 header is found
   */ ID3.isHeader = function isHeader(data, offset) {
                    /*
    * http://id3.org/id3v2.3.0
    * [0]     = 'I'
    * [1]     = 'D'
    * [2]     = '3'
    * [3,4]   = {Version}
    * [5]     = {Flags}
    * [6-9]   = {ID3 Size}
    *
    * An ID3v2 tag can be detected with the following pattern:
    *  $49 44 33 yy yy xx zz zz zz zz
    * Where yy is less than $FF, xx is the 'flags' byte and zz is less than $80
    */ if (offset + 10 <= data.length) {
                        // look for 'ID3' identifier
                        if (data[offset] === 73 && data[offset + 1] === 68 && data[offset + 2] === 51) // check version is within range
                        {
                            if (data[offset + 3] < 255 && data[offset + 4] < 255) {
                                // check size is within range
                                if (data[offset + 6] < 128 && data[offset + 7] < 128 && data[offset + 8] < 128 && data[offset + 9] < 128) return true;
                            }
                        }
                    }
                    return false;
                };
                ID3.isFooter = function isFooter(data, offset) {
                    /*
    * The footer is a copy of the header, but with a different identifier
    */ if (offset + 10 <= data.length) {
                        // look for '3DI' identifier
                        if (data[offset] === 51 && data[offset + 1] === 68 && data[offset + 2] === 73) // check version is within range
                        {
                            if (data[offset + 3] < 255 && data[offset + 4] < 255) {
                                // check size is within range
                                if (data[offset + 6] < 128 && data[offset + 7] < 128 && data[offset + 8] < 128 && data[offset + 9] < 128) return true;
                            }
                        }
                    }
                    return false;
                };
                ID3.getID3Data = function getID3Data(data, offset) {
                    var front = offset;
                    var length = 0;
                    while(ID3.isHeader(data, offset)){
                        // ID3 header is 10 bytes
                        length += 10;
                        var size = ID3._readSize(data, offset + 6);
                        length += size;
                        if (ID3.isFooter(data, offset + 10)) // ID3 footer is 10 bytes
                        length += 10;
                        offset += length;
                    }
                    if (length > 0) return data.subarray(front, front + length);
                    return undefined;
                };
                ID3._readSize = function _readSize(data, offset) {
                    var size = 0;
                    size = (data[offset] & 127) << 21;
                    size |= (data[offset + 1] & 127) << 14;
                    size |= (data[offset + 2] & 127) << 7;
                    size |= data[offset + 3] & 127;
                    return size;
                };
                ID3.getTimeStamp = function getTimeStamp(data) {
                    var frames = ID3.getID3Frames(data);
                    for(var i = 0; i < frames.length; i++){
                        var frame = frames[i];
                        if (ID3.isTimeStampFrame(frame)) return ID3._readTimeStamp(frame);
                    }
                    return undefined;
                };
                ID3.isTimeStampFrame = function isTimeStampFrame(frame) {
                    return frame && frame.key === 'PRIV' && frame.info === 'com.apple.streaming.transportStreamTimestamp';
                };
                ID3._getFrameData = function _getFrameData(data) {
                    /*
    Frame ID       $xx xx xx xx (four characters)
    Size           $xx xx xx xx
    Flags          $xx xx
    */ var type = String.fromCharCode(data[0], data[1], data[2], data[3]);
                    var size = ID3._readSize(data, 4); // skip frame id, size, and flags
                    var offset = 10;
                    return {
                        type: type,
                        size: size,
                        data: data.subarray(offset, offset + size)
                    };
                };
                ID3.getID3Frames = function getID3Frames(id3Data) {
                    var offset = 0;
                    var frames = [];
                    while(ID3.isHeader(id3Data, offset)){
                        var size = ID3._readSize(id3Data, offset + 6); // skip past ID3 header
                        offset += 10;
                        var end = offset + size; // loop through frames in the ID3 tag
                        while(offset + 8 < end){
                            var frameData = ID3._getFrameData(id3Data.subarray(offset));
                            var frame = ID3._decodeFrame(frameData);
                            if (frame) frames.push(frame);
                             // skip frame header and frame data
                            offset += frameData.size + 10;
                        }
                        if (ID3.isFooter(id3Data, offset)) offset += 10;
                    }
                    return frames;
                };
                ID3._decodeFrame = function _decodeFrame(frame) {
                    if (frame.type === 'PRIV') return ID3._decodePrivFrame(frame);
                    else if (frame.type[0] === 'W') return ID3._decodeURLFrame(frame);
                    return ID3._decodeTextFrame(frame);
                };
                ID3._readTimeStamp = function _readTimeStamp(timeStampFrame) {
                    if (timeStampFrame.data.byteLength === 8) {
                        var data = new Uint8Array(timeStampFrame.data); // timestamp is 33 bit expressed as a big-endian eight-octet number,
                        // with the upper 31 bits set to zero.
                        var pts33Bit = data[3] & 1;
                        var timestamp = (data[4] << 23) + (data[5] << 15) + (data[6] << 7) + data[7];
                        timestamp /= 45;
                        if (pts33Bit) timestamp += 47721858.84;
                         // 2^32 / 90
                        return Math.round(timestamp);
                    }
                    return undefined;
                };
                ID3._decodePrivFrame = function _decodePrivFrame(frame) {
                    /*
    Format: <text string>\0<binary data>
    */ if (frame.size < 2) return undefined;
                    var owner = ID3._utf8ArrayToStr(frame.data, true);
                    var privateData = new Uint8Array(frame.data.subarray(owner.length + 1));
                    return {
                        key: frame.type,
                        info: owner,
                        data: privateData.buffer
                    };
                };
                ID3._decodeTextFrame = function _decodeTextFrame(frame) {
                    if (frame.size < 2) return undefined;
                    if (frame.type === 'TXXX') {
                        /*
      Format:
      [0]   = {Text Encoding}
      [1-?] = {Description}\0{Value}
      */ var index = 1;
                        var description = ID3._utf8ArrayToStr(frame.data.subarray(index), true);
                        index += description.length + 1;
                        var value = ID3._utf8ArrayToStr(frame.data.subarray(index));
                        return {
                            key: frame.type,
                            info: description,
                            data: value
                        };
                    } else {
                        /*
      Format:
      [0]   = {Text Encoding}
      [1-?] = {Value}
      */ var text = ID3._utf8ArrayToStr(frame.data.subarray(1));
                        return {
                            key: frame.type,
                            data: text
                        };
                    }
                };
                ID3._decodeURLFrame = function _decodeURLFrame(frame) {
                    if (frame.type === 'WXXX') {
                        /*
      Format:
      [0]   = {Text Encoding}
      [1-?] = {Description}\0{URL}
      */ if (frame.size < 2) return undefined;
                        var index = 1;
                        var description = ID3._utf8ArrayToStr(frame.data.subarray(index), true);
                        index += description.length + 1;
                        var value = ID3._utf8ArrayToStr(frame.data.subarray(index));
                        return {
                            key: frame.type,
                            info: description,
                            data: value
                        };
                    } else {
                        /*
      Format:
      [0-?] = {URL}
      */ var url = ID3._utf8ArrayToStr(frame.data);
                        return {
                            key: frame.type,
                            data: url
                        };
                    }
                } // http://stackoverflow.com/questions/8936984/uint8array-to-string-in-javascript/22373197
                ;
                ID3._utf8ArrayToStr = function _utf8ArrayToStr(array, exitOnNull) {
                    if (exitOnNull === void 0) exitOnNull = false;
                    var decoder = getTextDecoder();
                    if (decoder) {
                        var decoded = decoder.decode(array);
                        if (exitOnNull) {
                            // grab up to the first null
                            var idx = decoded.indexOf('\0');
                            return idx !== -1 ? decoded.substring(0, idx) : decoded;
                        } // remove any null characters
                        return decoded.replace(/\0/g, '');
                    }
                    var len = array.length;
                    var c;
                    var char2;
                    var char3;
                    var out = '';
                    var i = 0;
                    while(i < len){
                        c = array[i++];
                        if (c === 0 && exitOnNull) return out;
                        else if (c === 0 || c === 3) continue;
                        switch(c >> 4){
                            case 0:
                            case 1:
                            case 2:
                            case 3:
                            case 4:
                            case 5:
                            case 6:
                            case 7:
                                // 0xxxxxxx
                                out += String.fromCharCode(c);
                                break;
                            case 12:
                            case 13:
                                // 110x xxxx   10xx xxxx
                                char2 = array[i++];
                                out += String.fromCharCode((c & 31) << 6 | char2 & 63);
                                break;
                            case 14:
                                // 1110 xxxx  10xx xxxx  10xx xxxx
                                char2 = array[i++];
                                char3 = array[i++];
                                out += String.fromCharCode((c & 15) << 12 | (char2 & 63) << 6 | (char3 & 63) << 0);
                                break;
                            default:
                        }
                    }
                    return out;
                };
                return ID3;
            }();
            var decoder1;
            function getTextDecoder() {
                var global = Object(_utils_get_self_scope__WEBPACK_IMPORTED_MODULE_0__["getSelfScope"])(); // safeguard for code that might run both on worker and main thread
                if (!decoder1 && typeof global.TextDecoder !== 'undefined') decoder1 = new global.TextDecoder('utf-8');
                return decoder1;
            }
            var utf8ArrayToStr = ID31._utf8ArrayToStr;
            /* harmony default export */ __webpack_exports__["default"] = ID31;
        /***/ },
        /***/ "./src/demux/mp4demuxer.js": function(module, __webpack_exports__, __webpack_require__) {
            "use strict";
            __webpack_require__.r(__webpack_exports__);
            /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.js");
            /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../events */ "./src/events.js");
            /**
 * MP4 demuxer
 */ var UINT32_MAX = Math.pow(2, 32) - 1;
            var MP4Demuxer1 = /*#__PURE__*/ function() {
                function MP4Demuxer(observer, remuxer) {
                    this.observer = observer;
                    this.remuxer = remuxer;
                }
                var _proto = MP4Demuxer.prototype;
                _proto.resetTimeStamp = function resetTimeStamp(initPTS) {
                    this.initPTS = initPTS;
                };
                _proto.resetInitSegment = function resetInitSegment(initSegment, audioCodec, videoCodec, duration) {
                    // jshint unused:false
                    if (initSegment && initSegment.byteLength) {
                        var initData = this.initData = MP4Demuxer.parseInitSegment(initSegment); // default audio codec if nothing specified
                        // TODO : extract that from initsegment
                        if (audioCodec == null) audioCodec = 'mp4a.40.5';
                        if (videoCodec == null) videoCodec = 'avc1.42e01e';
                        var tracks = {
                        };
                        if (initData.audio && initData.video) tracks.audiovideo = {
                            container: 'video/mp4',
                            codec: audioCodec + ',' + videoCodec,
                            initSegment: duration ? initSegment : null
                        };
                        else {
                            if (initData.audio) tracks.audio = {
                                container: 'audio/mp4',
                                codec: audioCodec,
                                initSegment: duration ? initSegment : null
                            };
                            if (initData.video) tracks.video = {
                                container: 'video/mp4',
                                codec: videoCodec,
                                initSegment: duration ? initSegment : null
                            };
                        }
                        this.observer.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["default"].FRAG_PARSING_INIT_SEGMENT, {
                            tracks: tracks
                        });
                    } else {
                        if (audioCodec) this.audioCodec = audioCodec;
                        if (videoCodec) this.videoCodec = videoCodec;
                    }
                };
                MP4Demuxer.probe = function probe(data) {
                    // ensure we find a moof box in the first 16 kB
                    return MP4Demuxer.findBox({
                        data: data,
                        start: 0,
                        end: Math.min(data.length, 16384)
                    }, [
                        'moof'
                    ]).length > 0;
                };
                MP4Demuxer.bin2str = function bin2str(buffer) {
                    return String.fromCharCode.apply(null, buffer);
                };
                MP4Demuxer.readUint16 = function readUint16(buffer, offset) {
                    if (buffer.data) {
                        offset += buffer.start;
                        buffer = buffer.data;
                    }
                    var val = buffer[offset] << 8 | buffer[offset + 1];
                    return val < 0 ? 65536 + val : val;
                };
                MP4Demuxer.readUint32 = function readUint32(buffer, offset) {
                    if (buffer.data) {
                        offset += buffer.start;
                        buffer = buffer.data;
                    }
                    var val = buffer[offset] << 24 | buffer[offset + 1] << 16 | buffer[offset + 2] << 8 | buffer[offset + 3];
                    return val < 0 ? 4294967296 + val : val;
                };
                MP4Demuxer.writeUint32 = function writeUint32(buffer, offset, value) {
                    if (buffer.data) {
                        offset += buffer.start;
                        buffer = buffer.data;
                    }
                    buffer[offset] = value >> 24;
                    buffer[offset + 1] = value >> 16 & 255;
                    buffer[offset + 2] = value >> 8 & 255;
                    buffer[offset + 3] = value & 255;
                } // Find the data for a box specified by its path
                ;
                MP4Demuxer.findBox = function findBox(data, path) {
                    var results = [], i, size, type, end, subresults, start, endbox;
                    if (data.data) {
                        start = data.start;
                        end = data.end;
                        data = data.data;
                    } else {
                        start = 0;
                        end = data.byteLength;
                    }
                    if (!path.length) // short-circuit the search for empty paths
                    return null;
                    for(i = start; i < end;){
                        size = MP4Demuxer.readUint32(data, i);
                        type = MP4Demuxer.bin2str(data.subarray(i + 4, i + 8));
                        endbox = size > 1 ? i + size : end;
                        if (type === path[0]) {
                            if (path.length === 1) // this is the end of the path and we've found the box we were
                            // looking for
                            results.push({
                                data: data,
                                start: i + 8,
                                end: endbox
                            });
                            else {
                                // recursively search for the next box along the path
                                subresults = MP4Demuxer.findBox({
                                    data: data,
                                    start: i + 8,
                                    end: endbox
                                }, path.slice(1));
                                if (subresults.length) results = results.concat(subresults);
                            }
                        }
                        i = endbox;
                    } // we've finished searching all of data
                    return results;
                };
                MP4Demuxer.parseSegmentIndex = function parseSegmentIndex(initSegment) {
                    var moov = MP4Demuxer.findBox(initSegment, [
                        'moov'
                    ])[0];
                    var moovEndOffset = moov ? moov.end : null; // we need this in case we need to chop of garbage of the end of current data
                    var index = 0;
                    var sidx = MP4Demuxer.findBox(initSegment, [
                        'sidx'
                    ]);
                    var references;
                    if (!sidx || !sidx[0]) return null;
                    references = [];
                    sidx = sidx[0];
                    var version = sidx.data[0]; // set initial offset, we skip the reference ID (not needed)
                    index = version === 0 ? 8 : 16;
                    var timescale = MP4Demuxer.readUint32(sidx, index);
                    index += 4; // TODO: parse earliestPresentationTime and firstOffset
                    // usually zero in our case
                    var earliestPresentationTime = 0;
                    var firstOffset = 0;
                    if (version === 0) index += 8;
                    else index += 16;
                     // skip reserved
                    index += 2;
                    var startByte = sidx.end + firstOffset;
                    var referencesCount = MP4Demuxer.readUint16(sidx, index);
                    index += 2;
                    for(var i = 0; i < referencesCount; i++){
                        var referenceIndex = index;
                        var referenceInfo = MP4Demuxer.readUint32(sidx, referenceIndex);
                        referenceIndex += 4;
                        var referenceSize = referenceInfo & 2147483647;
                        var referenceType = (referenceInfo & 2147483648) >>> 31;
                        if (referenceType === 1) {
                            console.warn('SIDX has hierarchical references (not supported)');
                            return;
                        }
                        var subsegmentDuration = MP4Demuxer.readUint32(sidx, referenceIndex);
                        referenceIndex += 4;
                        references.push({
                            referenceSize: referenceSize,
                            subsegmentDuration: subsegmentDuration,
                            // unscaled
                            info: {
                                duration: subsegmentDuration / timescale,
                                start: startByte,
                                end: startByte + referenceSize - 1
                            }
                        });
                        startByte += referenceSize; // Skipping 1 bit for |startsWithSap|, 3 bits for |sapType|, and 28 bits
                        // for |sapDelta|.
                        referenceIndex += 4; // skip to next ref
                        index = referenceIndex;
                    }
                    return {
                        earliestPresentationTime: earliestPresentationTime,
                        timescale: timescale,
                        version: version,
                        referencesCount: referencesCount,
                        references: references,
                        moovEndOffset: moovEndOffset
                    };
                };
                MP4Demuxer.parseInitSegment = function parseInitSegment(initSegment) {
                    var result = [];
                    var traks = MP4Demuxer.findBox(initSegment, [
                        'moov',
                        'trak'
                    ]);
                    traks.forEach(function(trak) {
                        var tkhd = MP4Demuxer.findBox(trak, [
                            'tkhd'
                        ])[0];
                        if (tkhd) {
                            var version = tkhd.data[tkhd.start];
                            var index = version === 0 ? 12 : 20;
                            var trackId = MP4Demuxer.readUint32(tkhd, index);
                            var mdhd = MP4Demuxer.findBox(trak, [
                                'mdia',
                                'mdhd'
                            ])[0];
                            if (mdhd) {
                                version = mdhd.data[mdhd.start];
                                index = version === 0 ? 12 : 20;
                                var timescale = MP4Demuxer.readUint32(mdhd, index);
                                var hdlr = MP4Demuxer.findBox(trak, [
                                    'mdia',
                                    'hdlr'
                                ])[0];
                                if (hdlr) {
                                    var hdlrType = MP4Demuxer.bin2str(hdlr.data.subarray(hdlr.start + 8, hdlr.start + 12));
                                    var type = {
                                        'soun': 'audio',
                                        'vide': 'video'
                                    }[hdlrType];
                                    if (type) {
                                        // extract codec info. TODO : parse codec details to be able to build MIME type
                                        var codecBox = MP4Demuxer.findBox(trak, [
                                            'mdia',
                                            'minf',
                                            'stbl',
                                            'stsd'
                                        ]);
                                        if (codecBox.length) {
                                            codecBox = codecBox[0];
                                            var codecType = MP4Demuxer.bin2str(codecBox.data.subarray(codecBox.start + 12, codecBox.start + 16));
                                            _utils_logger__WEBPACK_IMPORTED_MODULE_0__["logger"].log("MP4Demuxer:" + type + ":" + codecType + " found");
                                        }
                                        result[trackId] = {
                                            timescale: timescale,
                                            type: type
                                        };
                                        result[type] = {
                                            timescale: timescale,
                                            id: trackId
                                        };
                                    }
                                }
                            }
                        }
                    });
                    return result;
                };
                MP4Demuxer.getStartDTS = function getStartDTS(initData, fragment) {
                    var trafs, baseTimes, result1; // we need info from two childrend of each track fragment box
                    trafs = MP4Demuxer.findBox(fragment, [
                        'moof',
                        'traf'
                    ]); // determine the start times for each track
                    baseTimes = [].concat.apply([], trafs.map(function(traf) {
                        return MP4Demuxer.findBox(traf, [
                            'tfhd'
                        ]).map(function(tfhd) {
                            var id, scale, baseTime; // get the track id from the tfhd
                            id = MP4Demuxer.readUint32(tfhd, 4); // assume a 90kHz clock if no timescale was specified
                            scale = initData[id].timescale || 90000; // get the base media decode time from the tfdt
                            baseTime = MP4Demuxer.findBox(traf, [
                                'tfdt'
                            ]).map(function(tfdt) {
                                var version, result;
                                version = tfdt.data[tfdt.start];
                                result = MP4Demuxer.readUint32(tfdt, 4);
                                if (version === 1) {
                                    result *= Math.pow(2, 32);
                                    result += MP4Demuxer.readUint32(tfdt, 8);
                                }
                                return result;
                            })[0]; // convert base time to seconds
                            return baseTime / scale;
                        });
                    })); // return the minimum
                    result1 = Math.min.apply(null, baseTimes);
                    return isFinite(result1) ? result1 : 0;
                };
                MP4Demuxer.offsetStartDTS = function offsetStartDTS(initData, fragment, timeOffset) {
                    MP4Demuxer.findBox(fragment, [
                        'moof',
                        'traf'
                    ]).map(function(traf) {
                        return MP4Demuxer.findBox(traf, [
                            'tfhd'
                        ]).map(function(tfhd) {
                            // get the track id from the tfhd
                            var id = MP4Demuxer.readUint32(tfhd, 4); // assume a 90kHz clock if no timescale was specified
                            var timescale = initData[id].timescale || 90000; // get the base media decode time from the tfdt
                            MP4Demuxer.findBox(traf, [
                                'tfdt'
                            ]).map(function(tfdt) {
                                var version = tfdt.data[tfdt.start];
                                var baseMediaDecodeTime = MP4Demuxer.readUint32(tfdt, 4);
                                if (version === 0) MP4Demuxer.writeUint32(tfdt, 4, baseMediaDecodeTime - timeOffset * timescale);
                                else {
                                    baseMediaDecodeTime *= Math.pow(2, 32);
                                    baseMediaDecodeTime += MP4Demuxer.readUint32(tfdt, 8);
                                    baseMediaDecodeTime -= timeOffset * timescale;
                                    baseMediaDecodeTime = Math.max(baseMediaDecodeTime, 0);
                                    var upper = Math.floor(baseMediaDecodeTime / (UINT32_MAX + 1));
                                    var lower = Math.floor(baseMediaDecodeTime % (UINT32_MAX + 1));
                                    MP4Demuxer.writeUint32(tfdt, 4, upper);
                                    MP4Demuxer.writeUint32(tfdt, 8, lower);
                                }
                            });
                        });
                    });
                } // feed incoming data to the front of the parsing pipeline
                ;
                _proto.append = function append(data, timeOffset, contiguous, accurateTimeOffset) {
                    var initData = this.initData;
                    if (!initData) {
                        this.resetInitSegment(data, this.audioCodec, this.videoCodec, false);
                        initData = this.initData;
                    }
                    var startDTS, initPTS = this.initPTS;
                    if (initPTS === undefined) {
                        var _startDTS = MP4Demuxer.getStartDTS(initData, data);
                        this.initPTS = initPTS = _startDTS - timeOffset;
                        this.observer.trigger(_events__WEBPACK_IMPORTED_MODULE_1__["default"].INIT_PTS_FOUND, {
                            initPTS: initPTS
                        });
                    }
                    MP4Demuxer.offsetStartDTS(initData, data, initPTS);
                    startDTS = MP4Demuxer.getStartDTS(initData, data);
                    this.remuxer.remux(initData.audio, initData.video, null, null, startDTS, contiguous, accurateTimeOffset, data);
                };
                _proto.destroy = function destroy() {
                };
                return MP4Demuxer;
            }();
            /* harmony default export */ __webpack_exports__["default"] = MP4Demuxer1;
        /***/ },
        /***/ "./src/errors.ts": function(module, __webpack_exports__, __webpack_require__) {
            "use strict";
            __webpack_require__.r(__webpack_exports__);
            /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ErrorTypes", function() {
                return ErrorTypes1;
            });
            /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ErrorDetails", function() {
                return ErrorDetails1;
            });
            var ErrorTypes1;
            /**
 * @enum {ErrorDetails}
 * @typedef {string} ErrorDetail
 */ (function(ErrorTypes) {
                ErrorTypes["NETWORK_ERROR"] = "networkError";
                ErrorTypes["MEDIA_ERROR"] = "mediaError";
                ErrorTypes["KEY_SYSTEM_ERROR"] = "keySystemError";
                ErrorTypes["MUX_ERROR"] = "muxError";
                ErrorTypes["OTHER_ERROR"] = "otherError";
            })(ErrorTypes1 || (ErrorTypes1 = {
            }));
            var ErrorDetails1;
            (function(ErrorDetails) {
                ErrorDetails["KEY_SYSTEM_NO_KEYS"] = "keySystemNoKeys";
                ErrorDetails["KEY_SYSTEM_NO_ACCESS"] = "keySystemNoAccess";
                ErrorDetails["KEY_SYSTEM_NO_SESSION"] = "keySystemNoSession";
                ErrorDetails["KEY_SYSTEM_LICENSE_REQUEST_FAILED"] = "keySystemLicenseRequestFailed";
                ErrorDetails["KEY_SYSTEM_NO_INIT_DATA"] = "keySystemNoInitData";
                ErrorDetails["MANIFEST_LOAD_ERROR"] = "manifestLoadError";
                ErrorDetails["MANIFEST_LOAD_TIMEOUT"] = "manifestLoadTimeOut";
                ErrorDetails["MANIFEST_PARSING_ERROR"] = "manifestParsingError";
                ErrorDetails["MANIFEST_INCOMPATIBLE_CODECS_ERROR"] = "manifestIncompatibleCodecsError";
                ErrorDetails["LEVEL_EMPTY_ERROR"] = "levelEmptyError";
                ErrorDetails["LEVEL_LOAD_ERROR"] = "levelLoadError";
                ErrorDetails["LEVEL_LOAD_TIMEOUT"] = "levelLoadTimeOut";
                ErrorDetails["LEVEL_SWITCH_ERROR"] = "levelSwitchError";
                ErrorDetails["AUDIO_TRACK_LOAD_ERROR"] = "audioTrackLoadError";
                ErrorDetails["AUDIO_TRACK_LOAD_TIMEOUT"] = "audioTrackLoadTimeOut";
                ErrorDetails["FRAG_LOAD_ERROR"] = "fragLoadError";
                ErrorDetails["FRAG_LOAD_TIMEOUT"] = "fragLoadTimeOut";
                ErrorDetails["FRAG_DECRYPT_ERROR"] = "fragDecryptError";
                ErrorDetails["FRAG_PARSING_ERROR"] = "fragParsingError";
                ErrorDetails["REMUX_ALLOC_ERROR"] = "remuxAllocError";
                ErrorDetails["KEY_LOAD_ERROR"] = "keyLoadError";
                ErrorDetails["KEY_LOAD_TIMEOUT"] = "keyLoadTimeOut";
                ErrorDetails["BUFFER_ADD_CODEC_ERROR"] = "bufferAddCodecError";
                ErrorDetails["BUFFER_APPEND_ERROR"] = "bufferAppendError";
                ErrorDetails["BUFFER_APPENDING_ERROR"] = "bufferAppendingError";
                ErrorDetails["BUFFER_STALLED_ERROR"] = "bufferStalledError";
                ErrorDetails["BUFFER_FULL_ERROR"] = "bufferFullError";
                ErrorDetails["BUFFER_SEEK_OVER_HOLE"] = "bufferSeekOverHole";
                ErrorDetails["BUFFER_NUDGE_ON_STALL"] = "bufferNudgeOnStall";
                ErrorDetails["INTERNAL_EXCEPTION"] = "internalException";
            })(ErrorDetails1 || (ErrorDetails1 = {
            }));
        /***/ },
        /***/ "./src/events.js": function(module, __webpack_exports__, __webpack_require__) {
            "use strict";
            __webpack_require__.r(__webpack_exports__);
            /**
 * @readonly
 * @enum {string}
 */ var HlsEvents = {
                // fired before MediaSource is attaching to media element - data: { media }
                MEDIA_ATTACHING: 'hlsMediaAttaching',
                // fired when MediaSource has been succesfully attached to media element - data: { }
                MEDIA_ATTACHED: 'hlsMediaAttached',
                // fired before detaching MediaSource from media element - data: { }
                MEDIA_DETACHING: 'hlsMediaDetaching',
                // fired when MediaSource has been detached from media element - data: { }
                MEDIA_DETACHED: 'hlsMediaDetached',
                // fired when we buffer is going to be reset - data: { }
                BUFFER_RESET: 'hlsBufferReset',
                // fired when we know about the codecs that we need buffers for to push into - data: {tracks : { container, codec, levelCodec, initSegment, metadata }}
                BUFFER_CODECS: 'hlsBufferCodecs',
                // fired when sourcebuffers have been created - data: { tracks : tracks }
                BUFFER_CREATED: 'hlsBufferCreated',
                // fired when we append a segment to the buffer - data: { segment: segment object }
                BUFFER_APPENDING: 'hlsBufferAppending',
                // fired when we are done with appending a media segment to the buffer - data : { parent : segment parent that triggered BUFFER_APPENDING, pending : nb of segments waiting for appending for this segment parent}
                BUFFER_APPENDED: 'hlsBufferAppended',
                // fired when the stream is finished and we want to notify the media buffer that there will be no more data - data: { }
                BUFFER_EOS: 'hlsBufferEos',
                // fired when the media buffer should be flushed - data { startOffset, endOffset }
                BUFFER_FLUSHING: 'hlsBufferFlushing',
                // fired when the media buffer has been flushed - data: { }
                BUFFER_FLUSHED: 'hlsBufferFlushed',
                // fired to signal that a manifest loading starts - data: { url : manifestURL}
                MANIFEST_LOADING: 'hlsManifestLoading',
                // fired after manifest has been loaded - data: { levels : [available quality levels], audioTracks : [ available audio tracks], url : manifestURL, stats : { trequest, tfirst, tload, mtime}}
                MANIFEST_LOADED: 'hlsManifestLoaded',
                // fired after manifest has been parsed - data: { levels : [available quality levels], firstLevel : index of first quality level appearing in Manifest}
                MANIFEST_PARSED: 'hlsManifestParsed',
                // fired when a level switch is requested - data: { level : id of new level }
                LEVEL_SWITCHING: 'hlsLevelSwitching',
                // fired when a level switch is effective - data: { level : id of new level }
                LEVEL_SWITCHED: 'hlsLevelSwitched',
                // fired when a level playlist loading starts - data: { url : level URL, level : id of level being loaded}
                LEVEL_LOADING: 'hlsLevelLoading',
                // fired when a level playlist loading finishes - data: { details : levelDetails object, level : id of loaded level, stats : { trequest, tfirst, tload, mtime} }
                LEVEL_LOADED: 'hlsLevelLoaded',
                // fired when a level's details have been updated based on previous details, after it has been loaded - data: { details : levelDetails object, level : id of updated level }
                LEVEL_UPDATED: 'hlsLevelUpdated',
                // fired when a level's PTS information has been updated after parsing a fragment - data: { details : levelDetails object, level : id of updated level, drift: PTS drift observed when parsing last fragment }
                LEVEL_PTS_UPDATED: 'hlsLevelPtsUpdated',
                // fired to notify that levels have changed after removing a level - data: { levels : [available quality levels] }
                LEVELS_UPDATED: 'hlsLevelsUpdated',
                // fired to notify that audio track lists has been updated - data: { audioTracks : audioTracks }
                AUDIO_TRACKS_UPDATED: 'hlsAudioTracksUpdated',
                // fired when an audio track switching is requested - data: { id : audio track id }
                AUDIO_TRACK_SWITCHING: 'hlsAudioTrackSwitching',
                // fired when an audio track switch actually occurs - data: { id : audio track id }
                AUDIO_TRACK_SWITCHED: 'hlsAudioTrackSwitched',
                // fired when an audio track loading starts - data: { url : audio track URL, id : audio track id }
                AUDIO_TRACK_LOADING: 'hlsAudioTrackLoading',
                // fired when an audio track loading finishes - data: { details : levelDetails object, id : audio track id, stats : { trequest, tfirst, tload, mtime } }
                AUDIO_TRACK_LOADED: 'hlsAudioTrackLoaded',
                // fired to notify that subtitle track lists has been updated - data: { subtitleTracks : subtitleTracks }
                SUBTITLE_TRACKS_UPDATED: 'hlsSubtitleTracksUpdated',
                // fired when an subtitle track switch occurs - data: { id : subtitle track id }
                SUBTITLE_TRACK_SWITCH: 'hlsSubtitleTrackSwitch',
                // fired when a subtitle track loading starts - data: { url : subtitle track URL, id : subtitle track id }
                SUBTITLE_TRACK_LOADING: 'hlsSubtitleTrackLoading',
                // fired when a subtitle track loading finishes - data: { details : levelDetails object, id : subtitle track id, stats : { trequest, tfirst, tload, mtime } }
                SUBTITLE_TRACK_LOADED: 'hlsSubtitleTrackLoaded',
                // fired when a subtitle fragment has been processed - data: { success : boolean, frag : the processed frag }
                SUBTITLE_FRAG_PROCESSED: 'hlsSubtitleFragProcessed',
                // fired when a set of VTTCues to be managed externally has been parsed - data: { type: string, track: string, cues: [ VTTCue ] }
                CUES_PARSED: 'hlsCuesParsed',
                // fired when a text track to be managed externally is found - data: { tracks: [ { label: string, kind: string, default: boolean } ] }
                NON_NATIVE_TEXT_TRACKS_FOUND: 'hlsNonNativeTextTracksFound',
                // fired when the first timestamp is found - data: { id : demuxer id, initPTS: initPTS, frag : fragment object }
                INIT_PTS_FOUND: 'hlsInitPtsFound',
                // fired when a fragment loading starts - data: { frag : fragment object }
                FRAG_LOADING: 'hlsFragLoading',
                // fired when a fragment loading is progressing - data: { frag : fragment object, { trequest, tfirst, loaded } }
                FRAG_LOAD_PROGRESS: 'hlsFragLoadProgress',
                // Identifier for fragment load aborting for emergency switch down - data: { frag : fragment object }
                FRAG_LOAD_EMERGENCY_ABORTED: 'hlsFragLoadEmergencyAborted',
                // fired when a fragment loading is completed - data: { frag : fragment object, payload : fragment payload, stats : { trequest, tfirst, tload, length } }
                FRAG_LOADED: 'hlsFragLoaded',
                // fired when a fragment has finished decrypting - data: { id : demuxer id, frag: fragment object, payload : fragment payload, stats : { tstart, tdecrypt } }
                FRAG_DECRYPTED: 'hlsFragDecrypted',
                // fired when Init Segment has been extracted from fragment - data: { id : demuxer id, frag: fragment object, moov : moov MP4 box, codecs : codecs found while parsing fragment }
                FRAG_PARSING_INIT_SEGMENT: 'hlsFragParsingInitSegment',
                // fired when parsing sei text is completed - data: { id : demuxer id, frag: fragment object, samples : [ sei samples pes ] }
                FRAG_PARSING_USERDATA: 'hlsFragParsingUserdata',
                // fired when parsing id3 is completed - data: { id : demuxer id, frag: fragment object, samples : [ id3 samples pes ] }
                FRAG_PARSING_METADATA: 'hlsFragParsingMetadata',
                // fired when data have been extracted from fragment - data: { id : demuxer id, frag: fragment object, data1 : moof MP4 box or TS fragments, data2 : mdat MP4 box or null}
                FRAG_PARSING_DATA: 'hlsFragParsingData',
                // fired when fragment parsing is completed - data: { id : demuxer id, frag: fragment object }
                FRAG_PARSED: 'hlsFragParsed',
                // fired when fragment remuxed MP4 boxes have all been appended into SourceBuffer - data: { id : demuxer id, frag : fragment object, stats : { trequest, tfirst, tload, tparsed, tbuffered, length, bwEstimate } }
                FRAG_BUFFERED: 'hlsFragBuffered',
                // fired when fragment matching with current media position is changing - data : { id : demuxer id, frag : fragment object }
                FRAG_CHANGED: 'hlsFragChanged',
                // Identifier for a FPS drop event - data: { curentDropped, currentDecoded, totalDroppedFrames }
                FPS_DROP: 'hlsFpsDrop',
                // triggered when FPS drop triggers auto level capping - data: { level, droppedlevel }
                FPS_DROP_LEVEL_CAPPING: 'hlsFpsDropLevelCapping',
                // Identifier for an error event - data: { type : error type, details : error details, fatal : if true, hls.js cannot/will not try to recover, if false, hls.js will try to recover,other error specific data }
                ERROR: 'hlsError',
                // fired when hls.js instance starts destroying. Different from MEDIA_DETACHED as one could want to detach and reattach a media to the instance of hls.js to handle mid-rolls for example - data: { }
                DESTROYING: 'hlsDestroying',
                // fired when a decrypt key loading starts - data: { frag : fragment object }
                KEY_LOADING: 'hlsKeyLoading',
                // fired when a decrypt key loading is completed - data: { frag : fragment object, payload : key payload, stats : { trequest, tfirst, tload, length } }
                KEY_LOADED: 'hlsKeyLoaded',
                // fired upon stream controller state transitions - data: { previousState, nextState }
                STREAM_STATE_TRANSITION: 'hlsStreamStateTransition',
                // fired when the live back buffer is reached defined by the liveBackBufferLength config option - data : { bufferEnd: number }
                LIVE_BACK_BUFFER_REACHED: 'hlsLiveBackBufferReached'
            };
            /* harmony default export */ __webpack_exports__["default"] = HlsEvents;
        /***/ },
        /***/ "./src/hls.ts": function(module, __webpack_exports__, __webpack_require__) {
            "use strict";
            // ESM COMPAT FLAG
            __webpack_require__.r(__webpack_exports__);
            // EXPORTS
            __webpack_require__.d(__webpack_exports__, "default", function() {
                return(/* binding */ hls_Hls);
            });
            // NAMESPACE OBJECT: ./src/utils/cues.ts
            var cues_namespaceObject = {
            };
            __webpack_require__.r(cues_namespaceObject);
            __webpack_require__.d(cues_namespaceObject, "newCue", function() {
                return newCue;
            });
            // EXTERNAL MODULE: ./node_modules/url-toolkit/src/url-toolkit.js
            var url_toolkit = __webpack_require__("./node_modules/url-toolkit/src/url-toolkit.js");
            // EXTERNAL MODULE: ./src/errors.ts
            var errors = __webpack_require__("./src/errors.ts");
            // EXTERNAL MODULE: ./src/polyfills/number.js
            var number = __webpack_require__("./src/polyfills/number.js");
            // EXTERNAL MODULE: ./src/events.js
            var events1 = __webpack_require__("./src/events.js");
            // EXTERNAL MODULE: ./src/utils/logger.js
            var logger1 = __webpack_require__("./src/utils/logger.js");
            // CONCATENATED MODULE: ./src/event-handler.ts
            /*
*
* All objects in the event handling chain should inherit from this class
*
*/ var FORBIDDEN_EVENT_NAMES = {
                'hlsEventGeneric': true,
                'hlsHandlerDestroying': true,
                'hlsHandlerDestroyed': true
            };
            var event_handler_EventHandler = /*#__PURE__*/ function() {
                function EventHandler(hls) {
                    this.hls = void 0;
                    this.handledEvents = void 0;
                    this.useGenericHandler = void 0;
                    this.hls = hls;
                    this.onEvent = this.onEvent.bind(this);
                    for(var _len = arguments.length, events = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++)events[_key - 1] = arguments[_key];
                    this.handledEvents = events;
                    this.useGenericHandler = true;
                    this.registerListeners();
                }
                var _proto = EventHandler.prototype;
                _proto.destroy = function destroy() {
                    this.onHandlerDestroying();
                    this.unregisterListeners();
                    this.onHandlerDestroyed();
                };
                _proto.onHandlerDestroying = function onHandlerDestroying() {
                };
                _proto.onHandlerDestroyed = function onHandlerDestroyed() {
                };
                _proto.isEventHandler = function isEventHandler() {
                    return typeof this.handledEvents === 'object' && this.handledEvents.length && typeof this.onEvent === 'function';
                };
                _proto.registerListeners = function registerListeners() {
                    if (this.isEventHandler()) this.handledEvents.forEach(function(event) {
                        if (FORBIDDEN_EVENT_NAMES[event]) throw new Error('Forbidden event-name: ' + event);
                        this.hls.on(event, this.onEvent);
                    }, this);
                };
                _proto.unregisterListeners = function unregisterListeners() {
                    if (this.isEventHandler()) this.handledEvents.forEach(function(event) {
                        this.hls.off(event, this.onEvent);
                    }, this);
                };
                _proto.onEvent = function onEvent(event, data) {
                    this.onEventGeneric(event, data);
                };
                _proto.onEventGeneric = function onEventGeneric(event1, data1) {
                    var eventToFunction = function eventToFunction(event, data) {
                        var funcName = 'on' + event.replace('hls', '');
                        if (typeof this[funcName] !== 'function') throw new Error("Event " + event + " has no generic handler in this " + this.constructor.name + " class (tried " + funcName + ")");
                        return this[funcName].bind(this, data);
                    };
                    try {
                        eventToFunction.call(this, event1, data1).call();
                    } catch (err) {
                        logger1["logger"].error("An internal error happened while handling event " + event1 + ". Error message: \"" + err.message + "\". Here is a stacktrace:", err);
                        this.hls.trigger(events1["default"].ERROR, {
                            type: errors["ErrorTypes"].OTHER_ERROR,
                            details: errors["ErrorDetails"].INTERNAL_EXCEPTION,
                            fatal: false,
                            event: event1,
                            err: err
                        });
                    }
                };
                return EventHandler;
            }();
            /* harmony default export */ var event_handler = event_handler_EventHandler;
            // CONCATENATED MODULE: ./src/types/loader.ts
            /**
 * `type` property values for this loaders' context object
 * @enum
 *
 */ var PlaylistContextType1;
            /**
 * @enum {string}
 */ (function(PlaylistContextType) {
                PlaylistContextType["MANIFEST"] = "manifest";
                PlaylistContextType["LEVEL"] = "level";
                PlaylistContextType["AUDIO_TRACK"] = "audioTrack";
                PlaylistContextType["SUBTITLE_TRACK"] = "subtitleTrack";
            })(PlaylistContextType1 || (PlaylistContextType1 = {
            }));
            var PlaylistLevelType1;
            (function(PlaylistLevelType) {
                PlaylistLevelType["MAIN"] = "main";
                PlaylistLevelType["AUDIO"] = "audio";
                PlaylistLevelType["SUBTITLE"] = "subtitle";
            })(PlaylistLevelType1 || (PlaylistLevelType1 = {
            }));
            // EXTERNAL MODULE: ./src/demux/mp4demuxer.js
            var mp4demuxer = __webpack_require__("./src/demux/mp4demuxer.js");
            // CONCATENATED MODULE: ./src/loader/level-key.ts
            function _defineProperties(target, props) {
                for(var i = 0; i < props.length; i++){
                    var descriptor = props[i];
                    descriptor.enumerable = descriptor.enumerable || false;
                    descriptor.configurable = true;
                    if ("value" in descriptor) descriptor.writable = true;
                    Object.defineProperty(target, descriptor.key, descriptor);
                }
            }
            function _createClass(Constructor, protoProps, staticProps) {
                if (protoProps) _defineProperties(Constructor.prototype, protoProps);
                if (staticProps) _defineProperties(Constructor, staticProps);
                return Constructor;
            }
            var level_key_LevelKey = /*#__PURE__*/ function() {
                function LevelKey(baseURI, relativeURI) {
                    this._uri = null;
                    this.baseuri = void 0;
                    this.reluri = void 0;
                    this.method = null;
                    this.key = null;
                    this.iv = null;
                    this.baseuri = baseURI;
                    this.reluri = relativeURI;
                }
                _createClass(LevelKey, [
                    {
                        key: "uri",
                        get: function get() {
                            if (!this._uri && this.reluri) this._uri = Object(url_toolkit["buildAbsoluteURL"])(this.baseuri, this.reluri, {
                                alwaysNormalize: true
                            });
                            return this._uri;
                        }
                    }
                ]);
                return LevelKey;
            }();
            // CONCATENATED MODULE: ./src/loader/fragment.ts
            function fragment_defineProperties(target, props) {
                for(var i = 0; i < props.length; i++){
                    var descriptor = props[i];
                    descriptor.enumerable = descriptor.enumerable || false;
                    descriptor.configurable = true;
                    if ("value" in descriptor) descriptor.writable = true;
                    Object.defineProperty(target, descriptor.key, descriptor);
                }
            }
            function fragment_createClass(Constructor, protoProps, staticProps) {
                if (protoProps) fragment_defineProperties(Constructor.prototype, protoProps);
                if (staticProps) fragment_defineProperties(Constructor, staticProps);
                return Constructor;
            }
            var ElementaryStreamTypes1;
            (function(ElementaryStreamTypes) {
                ElementaryStreamTypes["AUDIO"] = "audio";
                ElementaryStreamTypes["VIDEO"] = "video";
            })(ElementaryStreamTypes1 || (ElementaryStreamTypes1 = {
            }));
            var fragment_Fragment = /*#__PURE__*/ function() {
                function Fragment() {
                    var _this$_elementaryStre;
                    this._url = null;
                    this._byteRange = null;
                    this._decryptdata = null;
                    this._elementaryStreams = (_this$_elementaryStre = {
                    }, _this$_elementaryStre[ElementaryStreamTypes1.AUDIO] = false, _this$_elementaryStre[ElementaryStreamTypes1.VIDEO] = false, _this$_elementaryStre);
                    this.deltaPTS = 0;
                    this.rawProgramDateTime = null;
                    this.programDateTime = null;
                    this.title = null;
                    this.tagList = [];
                    this.cc = void 0;
                    this.type = void 0;
                    this.relurl = void 0;
                    this.baseurl = void 0;
                    this.duration = void 0;
                    this.start = void 0;
                    this.sn = 0;
                    this.urlId = 0;
                    this.level = 0;
                    this.levelkey = void 0;
                    this.loader = void 0;
                }
                var _proto = Fragment.prototype;
                // setByteRange converts a EXT-X-BYTERANGE attribute into a two element array
                _proto.setByteRange = function setByteRange(value, previousFrag) {
                    var params = value.split('@', 2);
                    var byteRange = [];
                    if (params.length === 1) byteRange[0] = previousFrag ? previousFrag.byteRangeEndOffset : 0;
                    else byteRange[0] = parseInt(params[1]);
                    byteRange[1] = parseInt(params[0]) + byteRange[0];
                    this._byteRange = byteRange;
                };
                /**
   * @param {ElementaryStreamTypes} type
   */ _proto.addElementaryStream = function addElementaryStream(type) {
                    this._elementaryStreams[type] = true;
                };
                _proto.hasElementaryStream = function hasElementaryStream(type) {
                    return this._elementaryStreams[type] === true;
                };
                _proto.createInitializationVector = function createInitializationVector(segmentNumber) {
                    var uint8View = new Uint8Array(16);
                    for(var i = 12; i < 16; i++)uint8View[i] = segmentNumber >> 8 * (15 - i) & 255;
                    return uint8View;
                };
                _proto.setDecryptDataFromLevelKey = function setDecryptDataFromLevelKey(levelkey, segmentNumber) {
                    var decryptdata = levelkey;
                    if ((levelkey === null || levelkey === void 0 ? void 0 : levelkey.method) && levelkey.uri && !levelkey.iv) {
                        decryptdata = new level_key_LevelKey(levelkey.baseuri, levelkey.reluri);
                        decryptdata.method = levelkey.method;
                        decryptdata.iv = this.createInitializationVector(segmentNumber);
                    }
                    return decryptdata;
                };
                fragment_createClass(Fragment, [
                    {
                        key: "url",
                        get: function get() {
                            if (!this._url && this.relurl) this._url = Object(url_toolkit["buildAbsoluteURL"])(this.baseurl, this.relurl, {
                                alwaysNormalize: true
                            });
                            return this._url;
                        },
                        set: function set(value) {
                            this._url = value;
                        }
                    },
                    {
                        key: "byteRange",
                        get: function get() {
                            if (!this._byteRange) return [];
                            return this._byteRange;
                        }
                    },
                    {
                        key: "byteRangeStartOffset",
                        get: function get() {
                            return this.byteRange[0];
                        }
                    },
                    {
                        key: "byteRangeEndOffset",
                        get: function get() {
                            return this.byteRange[1];
                        }
                    },
                    {
                        key: "decryptdata",
                        get: function get() {
                            if (!this.levelkey && !this._decryptdata) return null;
                            if (!this._decryptdata && this.levelkey) {
                                var sn = this.sn;
                                if (typeof sn !== 'number') {
                                    // We are fetching decryption data for a initialization segment
                                    // If the segment was encrypted with AES-128
                                    // It must have an IV defined. We cannot substitute the Segment Number in.
                                    if (this.levelkey && this.levelkey.method === 'AES-128' && !this.levelkey.iv) logger1["logger"].warn("missing IV for initialization segment with method=\"" + this.levelkey.method + "\" - compliance issue");
                                    /*
          Be converted to a Number.
          'initSegment' will become NaN.
          NaN, which when converted through ToInt32() -> +0.
          ---
          Explicitly set sn to resulting value from implicit conversions 'initSegment' values for IV generation.
          */ sn = 0;
                                }
                                this._decryptdata = this.setDecryptDataFromLevelKey(this.levelkey, sn);
                            }
                            return this._decryptdata;
                        }
                    },
                    {
                        key: "endProgramDateTime",
                        get: function get() {
                            if (this.programDateTime === null) return null;
                            if (!Object(number["isFiniteNumber"])(this.programDateTime)) return null;
                            var duration = !Object(number["isFiniteNumber"])(this.duration) ? 0 : this.duration;
                            return this.programDateTime + duration * 1000;
                        }
                    },
                    {
                        key: "encrypted",
                        get: function get() {
                            return !!(this.decryptdata && this.decryptdata.uri !== null && this.decryptdata.key === null);
                        }
                    }
                ]);
                return Fragment;
            }();
            // CONCATENATED MODULE: ./src/loader/level.js
            function level_defineProperties(target, props) {
                for(var i = 0; i < props.length; i++){
                    var descriptor = props[i];
                    descriptor.enumerable = descriptor.enumerable || false;
                    descriptor.configurable = true;
                    if ("value" in descriptor) descriptor.writable = true;
                    Object.defineProperty(target, descriptor.key, descriptor);
                }
            }
            function level_createClass(Constructor, protoProps, staticProps) {
                if (protoProps) level_defineProperties(Constructor.prototype, protoProps);
                if (staticProps) level_defineProperties(Constructor, staticProps);
                return Constructor;
            }
            var level_Level = /*#__PURE__*/ function() {
                function Level(baseUrl) {
                    // Please keep properties in alphabetical order
                    this.endCC = 0;
                    this.endSN = 0;
                    this.fragments = [];
                    this.initSegment = null;
                    this.live = true;
                    this.needSidxRanges = false;
                    this.startCC = 0;
                    this.startSN = 0;
                    this.startTimeOffset = null;
                    this.targetduration = 0;
                    this.totalduration = 0;
                    this.type = null;
                    this.url = baseUrl;
                    this.version = null;
                }
                level_createClass(Level, [
                    {
                        key: "hasProgramDateTime",
                        get: function get() {
                            return !!(this.fragments[0] && Object(number["isFiniteNumber"])(this.fragments[0].programDateTime));
                        }
                    }
                ]);
                return Level;
            }();
            // CONCATENATED MODULE: ./src/utils/attr-list.js
            var DECIMAL_RESOLUTION_REGEX = /^(\d+)x(\d+)$/; // eslint-disable-line no-useless-escape
            var ATTR_LIST_REGEX = /\s*(.+?)\s*=((?:\".*?\")|.*?)(?:,|$)/g; // eslint-disable-line no-useless-escape
            // adapted from https://github.com/kanongil/node-m3u8parse/blob/master/attrlist.js
            var AttrList1 = /*#__PURE__*/ function() {
                function AttrList(attrs) {
                    if (typeof attrs === 'string') attrs = AttrList.parseAttrList(attrs);
                    for(var attr in attrs)if (attrs.hasOwnProperty(attr)) this[attr] = attrs[attr];
                }
                var _proto = AttrList.prototype;
                _proto.decimalInteger = function decimalInteger(attrName) {
                    var intValue = parseInt(this[attrName], 10);
                    if (intValue > Number.MAX_SAFE_INTEGER) return Infinity;
                    return intValue;
                };
                _proto.hexadecimalInteger = function hexadecimalInteger(attrName) {
                    if (this[attrName]) {
                        var stringValue = (this[attrName] || '0x').slice(2);
                        stringValue = (stringValue.length & 1 ? '0' : '') + stringValue;
                        var value = new Uint8Array(stringValue.length / 2);
                        for(var i = 0; i < stringValue.length / 2; i++)value[i] = parseInt(stringValue.slice(i * 2, i * 2 + 2), 16);
                        return value;
                    } else return null;
                };
                _proto.hexadecimalIntegerAsNumber = function hexadecimalIntegerAsNumber(attrName) {
                    var intValue = parseInt(this[attrName], 16);
                    if (intValue > Number.MAX_SAFE_INTEGER) return Infinity;
                    return intValue;
                };
                _proto.decimalFloatingPoint = function decimalFloatingPoint(attrName) {
                    return parseFloat(this[attrName]);
                };
                _proto.enumeratedString = function enumeratedString(attrName) {
                    return this[attrName];
                };
                _proto.decimalResolution = function decimalResolution(attrName) {
                    var res = DECIMAL_RESOLUTION_REGEX.exec(this[attrName]);
                    if (res === null) return undefined;
                    return {
                        width: parseInt(res[1], 10),
                        height: parseInt(res[2], 10)
                    };
                };
                AttrList.parseAttrList = function parseAttrList(input) {
                    var match, attrs = {
                    };
                    ATTR_LIST_REGEX.lastIndex = 0;
                    while((match = ATTR_LIST_REGEX.exec(input)) !== null){
                        var value = match[2], quote = '"';
                        if (value.indexOf(quote) === 0 && value.lastIndexOf(quote) === value.length - 1) value = value.slice(1, -1);
                        attrs[match[1]] = value;
                    }
                    return attrs;
                };
                return AttrList;
            }();
            /* harmony default export */ var attr_list = AttrList1;
            // CONCATENATED MODULE: ./src/utils/codecs.ts
            // from http://mp4ra.org/codecs.html
            var sampleEntryCodesISO = {
                audio: {
                    'a3ds': true,
                    'ac-3': true,
                    'ac-4': true,
                    'alac': true,
                    'alaw': true,
                    'dra1': true,
                    'dts+': true,
                    'dts-': true,
                    'dtsc': true,
                    'dtse': true,
                    'dtsh': true,
                    'ec-3': true,
                    'enca': true,
                    'g719': true,
                    'g726': true,
                    'm4ae': true,
                    'mha1': true,
                    'mha2': true,
                    'mhm1': true,
                    'mhm2': true,
                    'mlpa': true,
                    'mp4a': true,
                    'raw ': true,
                    'Opus': true,
                    'samr': true,
                    'sawb': true,
                    'sawp': true,
                    'sevc': true,
                    'sqcp': true,
                    'ssmv': true,
                    'twos': true,
                    'ulaw': true
                },
                video: {
                    'avc1': true,
                    'avc2': true,
                    'avc3': true,
                    'avc4': true,
                    'avcp': true,
                    'drac': true,
                    'dvav': true,
                    'dvhe': true,
                    'encv': true,
                    'hev1': true,
                    'hvc1': true,
                    'mjp2': true,
                    'mp4v': true,
                    'mvc1': true,
                    'mvc2': true,
                    'mvc3': true,
                    'mvc4': true,
                    'resv': true,
                    'rv60': true,
                    's263': true,
                    'svc1': true,
                    'svc2': true,
                    'vc-1': true,
                    'vp08': true,
                    'vp09': true
                }
            };
            function isCodecType(codec, type) {
                var typeCodes = sampleEntryCodesISO[type];
                return !!typeCodes && typeCodes[codec.slice(0, 4)] === true;
            }
            function isCodecSupportedInMp4(codec, type) {
                return MediaSource.isTypeSupported((type || 'video') + "/mp4;codecs=\"" + codec + "\"");
            }
            // CONCATENATED MODULE: ./src/loader/m3u8-parser.ts
            /**
 * M3U8 parser
 * @module
 */ // https://regex101.com is your friend
            var MASTER_PLAYLIST_REGEX = /(?:#EXT-X-STREAM-INF:([^\n\r]*)[\r\n]+([^\r\n]+)|#EXT-X-SESSION-DATA:([^\n\r]*)[\r\n]+)/g;
            var MASTER_PLAYLIST_MEDIA_REGEX = /#EXT-X-MEDIA:(.*)/g;
            var LEVEL_PLAYLIST_REGEX_FAST = new RegExp([
                /#EXTINF:\s*(\d*(?:\.\d+)?)(?:,(.*)\s+)?/.source,
                /|(?!#)([\S+ ?]+)/.source,
                /|#EXT-X-BYTERANGE:*(.+)/.source,
                /|#EXT-X-PROGRAM-DATE-TIME:(.+)/.source,
                /|#.*/.source // All other non-segment oriented tags will match with all groups empty
            ].join(''), 'g');
            var LEVEL_PLAYLIST_REGEX_SLOW = /(?:(?:#(EXTM3U))|(?:#EXT-X-(PLAYLIST-TYPE):(.+))|(?:#EXT-X-(MEDIA-SEQUENCE): *(\d+))|(?:#EXT-X-(TARGETDURATION): *(\d+))|(?:#EXT-X-(KEY):(.+))|(?:#EXT-X-(START):(.+))|(?:#EXT-X-(ENDLIST))|(?:#EXT-X-(DISCONTINUITY-SEQ)UENCE:(\d+))|(?:#EXT-X-(DIS)CONTINUITY))|(?:#EXT-X-(VERSION):(\d+))|(?:#EXT-X-(MAP):(.+))|(?:(#)([^:]*):(.*))|(?:(#)(.*))(?:.*)\r?\n?/;
            var MP4_REGEX_SUFFIX = /\.(mp4|m4s|m4v|m4a)$/i;
            var m3u8_parser_M3U8Parser = /*#__PURE__*/ function() {
                function M3U8Parser() {
                }
                M3U8Parser.findGroup = function findGroup(groups, mediaGroupId) {
                    for(var i = 0; i < groups.length; i++){
                        var group = groups[i];
                        if (group.id === mediaGroupId) return group;
                    }
                };
                M3U8Parser.convertAVC1ToAVCOTI = function convertAVC1ToAVCOTI(codec) {
                    var avcdata = codec.split('.');
                    var result;
                    if (avcdata.length > 2) {
                        result = avcdata.shift() + '.';
                        result += parseInt(avcdata.shift()).toString(16);
                        result += ('000' + parseInt(avcdata.shift()).toString(16)).substr(-4);
                    } else result = codec;
                    return result;
                };
                M3U8Parser.resolve = function resolve(url, baseUrl) {
                    return url_toolkit["buildAbsoluteURL"](baseUrl, url, {
                        alwaysNormalize: true
                    });
                };
                M3U8Parser.parseMasterPlaylist = function parseMasterPlaylist(string, baseurl) {
                    // TODO(typescript-level)
                    var levels = [];
                    var sessionData = {
                    };
                    var hasSessionData = false;
                    MASTER_PLAYLIST_REGEX.lastIndex = 0; // TODO(typescript-level)
                    function setCodecs(codecs, level) {
                        [
                            'video',
                            'audio'
                        ].forEach(function(type) {
                            var filtered = codecs.filter(function(codec) {
                                return isCodecType(codec, type);
                            });
                            if (filtered.length) {
                                var preferred = filtered.filter(function(codec) {
                                    return codec.lastIndexOf('avc1', 0) === 0 || codec.lastIndexOf('mp4a', 0) === 0;
                                });
                                level[type + "Codec"] = preferred.length > 0 ? preferred[0] : filtered[0]; // remove from list
                                codecs = codecs.filter(function(codec) {
                                    return filtered.indexOf(codec) === -1;
                                });
                            }
                        });
                        level.unknownCodecs = codecs;
                    }
                    var result;
                    while((result = MASTER_PLAYLIST_REGEX.exec(string)) != null){
                        if (result[1]) {
                            // '#EXT-X-STREAM-INF' is found, parse level tag  in group 1
                            // TODO(typescript-level)
                            var level1 = {
                            };
                            var attrs = level1.attrs = new attr_list(result[1]);
                            level1.url = M3U8Parser.resolve(result[2], baseurl);
                            var resolution = attrs.decimalResolution('RESOLUTION');
                            if (resolution) {
                                level1.width = resolution.width;
                                level1.height = resolution.height;
                            }
                            level1.bitrate = attrs.decimalInteger('AVERAGE-BANDWIDTH') || attrs.decimalInteger('BANDWIDTH');
                            level1.name = attrs.NAME;
                            setCodecs([].concat((attrs.CODECS || '').split(/[ ,]+/)), level1);
                            if (level1.videoCodec && level1.videoCodec.indexOf('avc1') !== -1) level1.videoCodec = M3U8Parser.convertAVC1ToAVCOTI(level1.videoCodec);
                            levels.push(level1);
                        } else if (result[3]) {
                            // '#EXT-X-SESSION-DATA' is found, parse session data in group 3
                            var sessionAttrs = new attr_list(result[3]);
                            if (sessionAttrs['DATA-ID']) {
                                hasSessionData = true;
                                sessionData[sessionAttrs['DATA-ID']] = sessionAttrs;
                            }
                        }
                    }
                    return {
                        levels: levels,
                        sessionData: hasSessionData ? sessionData : null
                    };
                };
                M3U8Parser.parseMasterPlaylistMedia = function parseMasterPlaylistMedia(string, baseurl, type, audioGroups) {
                    if (audioGroups === void 0) audioGroups = [];
                    var result;
                    var medias = [];
                    var id = 0;
                    MASTER_PLAYLIST_MEDIA_REGEX.lastIndex = 0;
                    while((result = MASTER_PLAYLIST_MEDIA_REGEX.exec(string)) !== null){
                        var attrs = new attr_list(result[1]);
                        if (attrs.TYPE === type) {
                            var media = {
                                attrs: attrs,
                                id: id++,
                                groupId: attrs['GROUP-ID'],
                                instreamId: attrs['INSTREAM-ID'],
                                name: attrs.NAME || attrs.LANGUAGE,
                                type: type,
                                default: attrs.DEFAULT === 'YES',
                                autoselect: attrs.AUTOSELECT === 'YES',
                                forced: attrs.FORCED === 'YES',
                                lang: attrs.LANGUAGE
                            };
                            if (attrs.URI) media.url = M3U8Parser.resolve(attrs.URI, baseurl);
                            if (audioGroups.length) {
                                // If there are audio groups signalled in the manifest, let's look for a matching codec string for this track
                                var groupCodec = M3U8Parser.findGroup(audioGroups, media.groupId); // If we don't find the track signalled, lets use the first audio groups codec we have
                                // Acting as a best guess
                                media.audioCodec = groupCodec ? groupCodec.codec : audioGroups[0].codec;
                            }
                            medias.push(media);
                        }
                    }
                    return medias;
                };
                M3U8Parser.parseLevelPlaylist = function parseLevelPlaylist(string, baseurl, id, type, levelUrlId) {
                    var currentSN = 0;
                    var totalduration = 0;
                    var level = new level_Level(baseurl);
                    var discontinuityCounter = 0;
                    var prevFrag = null;
                    var frag1 = new fragment_Fragment();
                    var result;
                    var i;
                    var levelkey;
                    var firstPdtIndex = null;
                    LEVEL_PLAYLIST_REGEX_FAST.lastIndex = 0;
                    while((result = LEVEL_PLAYLIST_REGEX_FAST.exec(string)) !== null){
                        var duration = result[1];
                        if (duration) {
                            // INF
                            frag1.duration = parseFloat(duration); // avoid sliced strings    https://github.com/video-dev/hls.js/issues/939
                            var title = (' ' + result[2]).slice(1);
                            frag1.title = title || null;
                            frag1.tagList.push(title ? [
                                'INF',
                                duration,
                                title
                            ] : [
                                'INF',
                                duration
                            ]);
                        } else if (result[3]) // url
                        {
                            if (Object(number["isFiniteNumber"])(frag1.duration)) {
                                var sn = currentSN++;
                                frag1.type = type;
                                frag1.start = totalduration;
                                if (levelkey) frag1.levelkey = levelkey;
                                frag1.sn = sn;
                                frag1.level = id;
                                frag1.cc = discontinuityCounter;
                                frag1.urlId = levelUrlId;
                                frag1.baseurl = baseurl; // avoid sliced strings    https://github.com/video-dev/hls.js/issues/939
                                frag1.relurl = (' ' + result[3]).slice(1);
                                assignProgramDateTime(frag1, prevFrag);
                                level.fragments.push(frag1);
                                prevFrag = frag1;
                                totalduration += frag1.duration;
                                frag1 = new fragment_Fragment();
                            }
                        } else if (result[4]) {
                            // X-BYTERANGE
                            var data = (' ' + result[4]).slice(1);
                            if (prevFrag) frag1.setByteRange(data, prevFrag);
                            else frag1.setByteRange(data);
                        } else if (result[5]) {
                            // PROGRAM-DATE-TIME
                            // avoid sliced strings    https://github.com/video-dev/hls.js/issues/939
                            frag1.rawProgramDateTime = (' ' + result[5]).slice(1);
                            frag1.tagList.push([
                                'PROGRAM-DATE-TIME',
                                frag1.rawProgramDateTime
                            ]);
                            if (firstPdtIndex === null) firstPdtIndex = level.fragments.length;
                        } else {
                            result = result[0].match(LEVEL_PLAYLIST_REGEX_SLOW);
                            if (!result) {
                                logger1["logger"].warn('No matches on slow regex match for level playlist!');
                                continue;
                            }
                            for(i = 1; i < result.length; i++){
                                if (typeof result[i] !== 'undefined') break;
                            } // avoid sliced strings    https://github.com/video-dev/hls.js/issues/939
                            var value1 = (' ' + result[i + 1]).slice(1);
                            var value2 = (' ' + result[i + 2]).slice(1);
                            switch(result[i]){
                                case '#':
                                    frag1.tagList.push(value2 ? [
                                        value1,
                                        value2
                                    ] : [
                                        value1
                                    ]);
                                    break;
                                case 'PLAYLIST-TYPE':
                                    level.type = value1.toUpperCase();
                                    break;
                                case 'MEDIA-SEQUENCE':
                                    currentSN = level.startSN = parseInt(value1);
                                    break;
                                case 'TARGETDURATION':
                                    level.targetduration = parseFloat(value1);
                                    break;
                                case 'VERSION':
                                    level.version = parseInt(value1);
                                    break;
                                case 'EXTM3U':
                                    break;
                                case 'ENDLIST':
                                    level.live = false;
                                    break;
                                case 'DIS':
                                    discontinuityCounter++;
                                    frag1.tagList.push([
                                        'DIS'
                                    ]);
                                    break;
                                case 'DISCONTINUITY-SEQ':
                                    discontinuityCounter = parseInt(value1);
                                    break;
                                case 'KEY':
                                    // https://tools.ietf.org/html/rfc8216#section-4.3.2.4
                                    var decryptparams = value1;
                                    var keyAttrs = new attr_list(decryptparams);
                                    var decryptmethod = keyAttrs.enumeratedString('METHOD');
                                    var decrypturi = keyAttrs.URI;
                                    var decryptiv = keyAttrs.hexadecimalInteger('IV'); // From RFC: This attribute is OPTIONAL; its absence indicates an implicit value of "identity".
                                    var decryptkeyformat = keyAttrs.KEYFORMAT || 'identity';
                                    if (decryptkeyformat === 'com.apple.streamingkeydelivery') {
                                        logger1["logger"].warn('Keyformat com.apple.streamingkeydelivery is not supported');
                                        continue;
                                    }
                                    if (decryptmethod) {
                                        levelkey = new level_key_LevelKey(baseurl, decrypturi);
                                        if (decrypturi && [
                                            'AES-128',
                                            'SAMPLE-AES',
                                            'SAMPLE-AES-CENC'
                                        ].indexOf(decryptmethod) >= 0) {
                                            levelkey.method = decryptmethod;
                                            levelkey.key = null; // Initialization Vector (IV)
                                            levelkey.iv = decryptiv;
                                        }
                                    }
                                    break;
                                case 'START':
                                    var startAttrs = new attr_list(value1);
                                    var startTimeOffset = startAttrs.decimalFloatingPoint('TIME-OFFSET'); // TIME-OFFSET can be 0
                                    if (Object(number["isFiniteNumber"])(startTimeOffset)) level.startTimeOffset = startTimeOffset;
                                    break;
                                case 'MAP':
                                    var mapAttrs = new attr_list(value1);
                                    frag1.relurl = mapAttrs.URI;
                                    if (mapAttrs.BYTERANGE) frag1.setByteRange(mapAttrs.BYTERANGE);
                                    frag1.baseurl = baseurl;
                                    frag1.level = id;
                                    frag1.type = type;
                                    frag1.sn = 'initSegment';
                                    level.initSegment = frag1;
                                    frag1 = new fragment_Fragment();
                                    frag1.rawProgramDateTime = level.initSegment.rawProgramDateTime;
                                    break;
                                default:
                                    logger1["logger"].warn("line parsed but not handled: " + result);
                                    break;
                            }
                        }
                    }
                    frag1 = prevFrag; // logger.log('found ' + level.fragments.length + ' fragments');
                    if (frag1 && !frag1.relurl) {
                        level.fragments.pop();
                        totalduration -= frag1.duration;
                    }
                    level.totalduration = totalduration;
                    level.averagetargetduration = totalduration / level.fragments.length;
                    level.endSN = currentSN - 1;
                    level.startCC = level.fragments[0] ? level.fragments[0].cc : 0;
                    level.endCC = discontinuityCounter;
                    if (!level.initSegment && level.fragments.length) // this is a bit lurky but HLS really has no other way to tell us
                    // if the fragments are TS or MP4, except if we download them :/
                    // but this is to be able to handle SIDX.
                    {
                        if (level.fragments.every(function(frag) {
                            return MP4_REGEX_SUFFIX.test(frag.relurl);
                        })) {
                            logger1["logger"].warn('MP4 fragments found but no init segment (probably no MAP, incomplete M3U8), trying to fetch SIDX');
                            frag1 = new fragment_Fragment();
                            frag1.relurl = level.fragments[0].relurl;
                            frag1.baseurl = baseurl;
                            frag1.level = id;
                            frag1.type = type;
                            frag1.sn = 'initSegment';
                            level.initSegment = frag1;
                            level.needSidxRanges = true;
                        }
                    }
                    /**
     * Backfill any missing PDT values
       "If the first EXT-X-PROGRAM-DATE-TIME tag in a Playlist appears after
       one or more Media Segment URIs, the client SHOULD extrapolate
       backward from that tag (using EXTINF durations and/or media
       timestamps) to associate dates with those segments."
     * We have already extrapolated forward, but all fragments up to the first instance of PDT do not have their PDTs
     * computed.
     */ if (firstPdtIndex) backfillProgramDateTimes(level.fragments, firstPdtIndex);
                    return level;
                };
                return M3U8Parser;
            }();
            function backfillProgramDateTimes(fragments, startIndex) {
                var fragPrev = fragments[startIndex];
                for(var i = startIndex - 1; i >= 0; i--){
                    var frag = fragments[i];
                    frag.programDateTime = fragPrev.programDateTime - frag.duration * 1000;
                    fragPrev = frag;
                }
            }
            function assignProgramDateTime(frag, prevFrag) {
                if (frag.rawProgramDateTime) frag.programDateTime = Date.parse(frag.rawProgramDateTime);
                else if (prevFrag === null || prevFrag === void 0 ? void 0 : prevFrag.programDateTime) frag.programDateTime = prevFrag.endProgramDateTime;
                if (!Object(number["isFiniteNumber"])(frag.programDateTime)) {
                    frag.programDateTime = null;
                    frag.rawProgramDateTime = null;
                }
            }
            // CONCATENATED MODULE: ./src/loader/playlist-loader.ts
            function _inheritsLoose(subClass, superClass) {
                subClass.prototype = Object.create(superClass.prototype);
                subClass.prototype.constructor = subClass;
                subClass.__proto__ = superClass;
            }
            /**
 * PlaylistLoader - delegate for media manifest/playlist loading tasks. Takes care of parsing media to internal data-models.
 *
 * Once loaded, dispatches events with parsed data-models of manifest/levels/audio/subtitle tracks.
 *
 * Uses loader(s) set in config to do actual internal loading of resource tasks.
 *
 * @module
 *
 */ var _window = window, performance = _window.performance;
            /**
 * @constructor
 */ var playlist_loader_PlaylistLoader = /*#__PURE__*/ function(_EventHandler) {
                _inheritsLoose(PlaylistLoader, _EventHandler);
                /**
   * @constructs
   * @param {Hls} hls
   */ function PlaylistLoader(hls) {
                    var _this;
                    _this = _EventHandler.call(this, hls, events1["default"].MANIFEST_LOADING, events1["default"].LEVEL_LOADING, events1["default"].AUDIO_TRACK_LOADING, events1["default"].SUBTITLE_TRACK_LOADING) || this;
                    _this.loaders = {
                    };
                    return _this;
                }
                /**
   * @param {PlaylistContextType} type
   * @returns {boolean}
   */ PlaylistLoader.canHaveQualityLevels = function canHaveQualityLevels(type) {
                    return type !== PlaylistContextType1.AUDIO_TRACK && type !== PlaylistContextType1.SUBTITLE_TRACK;
                };
                PlaylistLoader.mapContextToLevelType = function mapContextToLevelType(context) {
                    var type = context.type;
                    switch(type){
                        case PlaylistContextType1.AUDIO_TRACK:
                            return PlaylistLevelType1.AUDIO;
                        case PlaylistContextType1.SUBTITLE_TRACK:
                            return PlaylistLevelType1.SUBTITLE;
                        default:
                            return PlaylistLevelType1.MAIN;
                    }
                };
                PlaylistLoader.getResponseUrl = function getResponseUrl(response, context) {
                    var url = response.url; // responseURL not supported on some browsers (it is used to detect URL redirection)
                    // data-uri mode also not supported (but no need to detect redirection)
                    if (url === undefined || url.indexOf('data:') === 0) // fallback to initial URL
                    url = context.url;
                    return url;
                };
                var _proto = PlaylistLoader.prototype;
                _proto.createInternalLoader = function createInternalLoader(context) {
                    var config = this.hls.config;
                    var PLoader = config.pLoader;
                    var Loader = config.loader; // TODO(typescript-config): Verify once config is typed that InternalLoader always returns a Loader
                    var InternalLoader = PLoader || Loader;
                    var loader = new InternalLoader(config); // TODO - Do we really need to assign the instance or if the dep has been lost
                    context.loader = loader;
                    this.loaders[context.type] = loader;
                    return loader;
                };
                _proto.getInternalLoader = function getInternalLoader(context) {
                    return this.loaders[context.type];
                };
                _proto.resetInternalLoader = function resetInternalLoader(contextType) {
                    if (this.loaders[contextType]) delete this.loaders[contextType];
                };
                _proto.destroyInternalLoaders = function destroyInternalLoaders() {
                    for(var contextType in this.loaders){
                        var loader = this.loaders[contextType];
                        if (loader) loader.destroy();
                        this.resetInternalLoader(contextType);
                    }
                };
                _proto.destroy = function destroy() {
                    this.destroyInternalLoaders();
                    _EventHandler.prototype.destroy.call(this);
                };
                _proto.onManifestLoading = function onManifestLoading(data) {
                    this.load({
                        url: data.url,
                        type: PlaylistContextType1.MANIFEST,
                        level: 0,
                        id: null,
                        responseType: 'text'
                    });
                };
                _proto.onLevelLoading = function onLevelLoading(data) {
                    this.load({
                        url: data.url,
                        type: PlaylistContextType1.LEVEL,
                        level: data.level,
                        id: data.id,
                        responseType: 'text'
                    });
                };
                _proto.onAudioTrackLoading = function onAudioTrackLoading(data) {
                    this.load({
                        url: data.url,
                        type: PlaylistContextType1.AUDIO_TRACK,
                        level: null,
                        id: data.id,
                        responseType: 'text'
                    });
                };
                _proto.onSubtitleTrackLoading = function onSubtitleTrackLoading(data) {
                    this.load({
                        url: data.url,
                        type: PlaylistContextType1.SUBTITLE_TRACK,
                        level: null,
                        id: data.id,
                        responseType: 'text'
                    });
                };
                _proto.load = function load(context) {
                    var config = this.hls.config;
                    logger1["logger"].debug("Loading playlist of type " + context.type + ", level: " + context.level + ", id: " + context.id); // Check if a loader for this context already exists
                    var loader = this.getInternalLoader(context);
                    if (loader) {
                        var loaderContext = loader.context;
                        if (loaderContext && loaderContext.url === context.url) {
                            // same URL can't overlap
                            logger1["logger"].trace('playlist request ongoing');
                            return false;
                        } else {
                            logger1["logger"].warn("aborting previous loader for type: " + context.type);
                            loader.abort();
                        }
                    }
                    var maxRetry;
                    var timeout;
                    var retryDelay;
                    var maxRetryDelay; // apply different configs for retries depending on
                    // context (manifest, level, audio/subs playlist)
                    switch(context.type){
                        case PlaylistContextType1.MANIFEST:
                            maxRetry = config.manifestLoadingMaxRetry;
                            timeout = config.manifestLoadingTimeOut;
                            retryDelay = config.manifestLoadingRetryDelay;
                            maxRetryDelay = config.manifestLoadingMaxRetryTimeout;
                            break;
                        case PlaylistContextType1.LEVEL:
                            // Disable internal loader retry logic, since we are managing retries in Level Controller
                            maxRetry = 0;
                            maxRetryDelay = 0;
                            retryDelay = 0;
                            timeout = config.levelLoadingTimeOut; // TODO Introduce retry settings for audio-track and subtitle-track, it should not use level retry config
                            break;
                        default:
                            maxRetry = config.levelLoadingMaxRetry;
                            timeout = config.levelLoadingTimeOut;
                            retryDelay = config.levelLoadingRetryDelay;
                            maxRetryDelay = config.levelLoadingMaxRetryTimeout;
                            break;
                    }
                    loader = this.createInternalLoader(context);
                    var loaderConfig = {
                        timeout: timeout,
                        maxRetry: maxRetry,
                        retryDelay: retryDelay,
                        maxRetryDelay: maxRetryDelay
                    };
                    var loaderCallbacks = {
                        onSuccess: this.loadsuccess.bind(this),
                        onError: this.loaderror.bind(this),
                        onTimeout: this.loadtimeout.bind(this)
                    };
                    logger1["logger"].debug("Calling internal loader delegate for URL: " + context.url);
                    loader.load(context, loaderConfig, loaderCallbacks);
                    return true;
                };
                _proto.loadsuccess = function loadsuccess(response, stats, context, networkDetails) {
                    if (networkDetails === void 0) networkDetails = null;
                    if (context.isSidxRequest) {
                        this._handleSidxRequest(response, context);
                        this._handlePlaylistLoaded(response, stats, context, networkDetails);
                        return;
                    }
                    this.resetInternalLoader(context.type);
                    if (typeof response.data !== 'string') throw new Error('expected responseType of "text" for PlaylistLoader');
                    var string = response.data;
                    stats.tload = performance.now(); // stats.mtime = new Date(target.getResponseHeader('Last-Modified'));
                    // Validate if it is an M3U8 at all
                    if (string.indexOf('#EXTM3U') !== 0) {
                        this._handleManifestParsingError(response, context, 'no EXTM3U delimiter', networkDetails);
                        return;
                    } // Check if chunk-list or master. handle empty chunk list case (first EXTINF not signaled, but TARGETDURATION present)
                    if (string.indexOf('#EXTINF:') > 0 || string.indexOf('#EXT-X-TARGETDURATION:') > 0) this._handleTrackOrLevelPlaylist(response, stats, context, networkDetails);
                    else this._handleMasterPlaylist(response, stats, context, networkDetails);
                };
                _proto.loaderror = function loaderror(response, context, networkDetails) {
                    if (networkDetails === void 0) networkDetails = null;
                    this._handleNetworkError(context, networkDetails, false, response);
                };
                _proto.loadtimeout = function loadtimeout(stats, context, networkDetails) {
                    if (networkDetails === void 0) networkDetails = null;
                    this._handleNetworkError(context, networkDetails, true);
                } // TODO(typescript-config): networkDetails can currently be a XHR or Fetch impl,
                ;
                _proto._handleMasterPlaylist = function _handleMasterPlaylist(response, stats, context, networkDetails) {
                    var hls = this.hls;
                    var string = response.data;
                    var url = PlaylistLoader.getResponseUrl(response, context);
                    var _M3U8Parser$parseMast = m3u8_parser_M3U8Parser.parseMasterPlaylist(string, url), levels = _M3U8Parser$parseMast.levels, sessionData = _M3U8Parser$parseMast.sessionData;
                    if (!levels.length) {
                        this._handleManifestParsingError(response, context, 'no level found in manifest', networkDetails);
                        return;
                    } // multi level playlist, parse level info
                    var audioGroups = levels.map(function(level) {
                        return {
                            id: level.attrs.AUDIO,
                            codec: level.audioCodec
                        };
                    });
                    var audioTracks = m3u8_parser_M3U8Parser.parseMasterPlaylistMedia(string, url, 'AUDIO', audioGroups);
                    var subtitles = m3u8_parser_M3U8Parser.parseMasterPlaylistMedia(string, url, 'SUBTITLES');
                    var captions = m3u8_parser_M3U8Parser.parseMasterPlaylistMedia(string, url, 'CLOSED-CAPTIONS');
                    if (audioTracks.length) {
                        // check if we have found an audio track embedded in main playlist (audio track without URI attribute)
                        var embeddedAudioFound = false;
                        audioTracks.forEach(function(audioTrack) {
                            if (!audioTrack.url) embeddedAudioFound = true;
                        }); // if no embedded audio track defined, but audio codec signaled in quality level,
                        // we need to signal this main audio track this could happen with playlists with
                        // alt audio rendition in which quality levels (main)
                        // contains both audio+video. but with mixed audio track not signaled
                        if (embeddedAudioFound === false && levels[0].audioCodec && !levels[0].attrs.AUDIO) {
                            logger1["logger"].log('audio codec signaled in quality level, but no embedded audio track signaled, create one');
                            audioTracks.unshift({
                                type: 'main',
                                name: 'main',
                                default: false,
                                autoselect: false,
                                forced: false,
                                id: -1,
                                attrs: {
                                },
                                url: ''
                            });
                        }
                    }
                    hls.trigger(events1["default"].MANIFEST_LOADED, {
                        levels: levels,
                        audioTracks: audioTracks,
                        subtitles: subtitles,
                        captions: captions,
                        url: url,
                        stats: stats,
                        networkDetails: networkDetails,
                        sessionData: sessionData
                    });
                };
                _proto._handleTrackOrLevelPlaylist = function _handleTrackOrLevelPlaylist(response, stats, context, networkDetails) {
                    var hls = this.hls;
                    var id = context.id, level = context.level, type = context.type;
                    var url = PlaylistLoader.getResponseUrl(response, context); // if the values are null, they will result in the else conditional
                    var levelUrlId = Object(number["isFiniteNumber"])(id) ? id : 0;
                    var levelId = Object(number["isFiniteNumber"])(level) ? level : levelUrlId;
                    var levelType = PlaylistLoader.mapContextToLevelType(context);
                    var levelDetails = m3u8_parser_M3U8Parser.parseLevelPlaylist(response.data, url, levelId, levelType, levelUrlId); // set stats on level structure
                    // TODO(jstackhouse): why? mixing concerns, is it just treated as value bag?
                    levelDetails.tload = stats.tload;
                    if (!levelDetails.fragments.length) {
                        hls.trigger(events1["default"].ERROR, {
                            type: errors["ErrorTypes"].NETWORK_ERROR,
                            details: errors["ErrorDetails"].LEVEL_EMPTY_ERROR,
                            fatal: false,
                            url: url,
                            reason: 'no fragments found in level',
                            level: typeof context.level === 'number' ? context.level : undefined
                        });
                        return;
                    } // We have done our first request (Manifest-type) and receive
                    // not a master playlist but a chunk-list (track/level)
                    // We fire the manifest-loaded event anyway with the parsed level-details
                    // by creating a single-level structure for it.
                    if (type === PlaylistContextType1.MANIFEST) {
                        var singleLevel = {
                            url: url,
                            details: levelDetails
                        };
                        hls.trigger(events1["default"].MANIFEST_LOADED, {
                            levels: [
                                singleLevel
                            ],
                            audioTracks: [],
                            url: url,
                            stats: stats,
                            networkDetails: networkDetails,
                            sessionData: null
                        });
                    } // save parsing time
                    stats.tparsed = performance.now(); // in case we need SIDX ranges
                    // return early after calling load for
                    // the SIDX box.
                    if (levelDetails.needSidxRanges) {
                        var sidxUrl = levelDetails.initSegment.url;
                        this.load({
                            url: sidxUrl,
                            isSidxRequest: true,
                            type: type,
                            level: level,
                            levelDetails: levelDetails,
                            id: id,
                            rangeStart: 0,
                            rangeEnd: 2048,
                            responseType: 'arraybuffer'
                        });
                        return;
                    } // extend the context with the new levelDetails property
                    context.levelDetails = levelDetails;
                    this._handlePlaylistLoaded(response, stats, context, networkDetails);
                };
                _proto._handleSidxRequest = function _handleSidxRequest(response, context) {
                    if (typeof response.data === 'string') throw new Error('sidx request must be made with responseType of array buffer');
                    var sidxInfo = mp4demuxer["default"].parseSegmentIndex(new Uint8Array(response.data)); // if provided fragment does not contain sidx, early return
                    if (!sidxInfo) return;
                    var sidxReferences = sidxInfo.references;
                    var levelDetails = context.levelDetails;
                    sidxReferences.forEach(function(segmentRef, index) {
                        var segRefInfo = segmentRef.info;
                        if (!levelDetails) return;
                        var frag = levelDetails.fragments[index];
                        if (frag.byteRange.length === 0) frag.setByteRange(String(1 + segRefInfo.end - segRefInfo.start) + '@' + String(segRefInfo.start));
                    });
                    if (levelDetails) levelDetails.initSegment.setByteRange(String(sidxInfo.moovEndOffset) + '@0');
                };
                _proto._handleManifestParsingError = function _handleManifestParsingError(response, context, reason, networkDetails) {
                    this.hls.trigger(events1["default"].ERROR, {
                        type: errors["ErrorTypes"].NETWORK_ERROR,
                        details: errors["ErrorDetails"].MANIFEST_PARSING_ERROR,
                        fatal: true,
                        url: response.url,
                        reason: reason,
                        networkDetails: networkDetails
                    });
                };
                _proto._handleNetworkError = function _handleNetworkError(context, networkDetails, timeout, response) {
                    if (timeout === void 0) timeout = false;
                    if (response === void 0) response = null;
                    logger1["logger"].info("A network error occured while loading a " + context.type + "-type playlist");
                    var details;
                    var fatal;
                    var loader = this.getInternalLoader(context);
                    switch(context.type){
                        case PlaylistContextType1.MANIFEST:
                            details = timeout ? errors["ErrorDetails"].MANIFEST_LOAD_TIMEOUT : errors["ErrorDetails"].MANIFEST_LOAD_ERROR;
                            fatal = true;
                            break;
                        case PlaylistContextType1.LEVEL:
                            details = timeout ? errors["ErrorDetails"].LEVEL_LOAD_TIMEOUT : errors["ErrorDetails"].LEVEL_LOAD_ERROR;
                            fatal = false;
                            break;
                        case PlaylistContextType1.AUDIO_TRACK:
                            details = timeout ? errors["ErrorDetails"].AUDIO_TRACK_LOAD_TIMEOUT : errors["ErrorDetails"].AUDIO_TRACK_LOAD_ERROR;
                            fatal = false;
                            break;
                        default:
                            // details = ...?
                            fatal = false;
                    }
                    if (loader) {
                        loader.abort();
                        this.resetInternalLoader(context.type);
                    } // TODO(typescript-events): when error events are handled, type this
                    var errorData = {
                        type: errors["ErrorTypes"].NETWORK_ERROR,
                        details: details,
                        fatal: fatal,
                        url: context.url,
                        loader: loader,
                        context: context,
                        networkDetails: networkDetails
                    };
                    if (response) errorData.response = response;
                    this.hls.trigger(events1["default"].ERROR, errorData);
                };
                _proto._handlePlaylistLoaded = function _handlePlaylistLoaded(response, stats, context, networkDetails) {
                    var type = context.type, level = context.level, id = context.id, levelDetails = context.levelDetails;
                    if (!levelDetails || !levelDetails.targetduration) {
                        this._handleManifestParsingError(response, context, 'invalid target duration', networkDetails);
                        return;
                    }
                    var canHaveLevels = PlaylistLoader.canHaveQualityLevels(context.type);
                    if (canHaveLevels) this.hls.trigger(events1["default"].LEVEL_LOADED, {
                        details: levelDetails,
                        level: level || 0,
                        id: id || 0,
                        stats: stats,
                        networkDetails: networkDetails
                    });
                    else switch(type){
                        case PlaylistContextType1.AUDIO_TRACK:
                            this.hls.trigger(events1["default"].AUDIO_TRACK_LOADED, {
                                details: levelDetails,
                                id: id,
                                stats: stats,
                                networkDetails: networkDetails
                            });
                            break;
                        case PlaylistContextType1.SUBTITLE_TRACK:
                            this.hls.trigger(events1["default"].SUBTITLE_TRACK_LOADED, {
                                details: levelDetails,
                                id: id,
                                stats: stats,
                                networkDetails: networkDetails
                            });
                            break;
                    }
                };
                return PlaylistLoader;
            }(event_handler);
            /* harmony default export */ var playlist_loader = playlist_loader_PlaylistLoader;
            // CONCATENATED MODULE: ./src/loader/fragment-loader.js
            function fragment_loader_inheritsLoose(subClass, superClass) {
                subClass.prototype = Object.create(superClass.prototype);
                subClass.prototype.constructor = subClass;
                subClass.__proto__ = superClass;
            }
            /*
 * Fragment Loader
*/ var fragment_loader_FragmentLoader = /*#__PURE__*/ function(_EventHandler) {
                fragment_loader_inheritsLoose(FragmentLoader, _EventHandler);
                function FragmentLoader(hls) {
                    var _this;
                    _this = _EventHandler.call(this, hls, events1["default"].FRAG_LOADING) || this;
                    _this.loaders = {
                    };
                    return _this;
                }
                var _proto = FragmentLoader.prototype;
                _proto.destroy = function destroy() {
                    var loaders = this.loaders;
                    for(var loaderName in loaders){
                        var loader = loaders[loaderName];
                        if (loader) loader.destroy();
                    }
                    this.loaders = {
                    };
                    _EventHandler.prototype.destroy.call(this);
                };
                _proto.onFragLoading = function onFragLoading(data) {
                    var frag = data.frag, type = frag.type, loaders = this.loaders, config = this.hls.config, FragmentILoader = config.fLoader, DefaultILoader = config.loader; // reset fragment state
                    frag.loaded = 0;
                    var loader = loaders[type];
                    if (loader) {
                        logger1["logger"].warn("abort previous fragment loader for type: " + type);
                        loader.abort();
                    }
                    loader = loaders[type] = frag.loader = config.fLoader ? new FragmentILoader(config) : new DefaultILoader(config);
                    var loaderContext, loaderConfig, loaderCallbacks;
                    loaderContext = {
                        url: frag.url,
                        frag: frag,
                        responseType: 'arraybuffer',
                        progressData: false
                    };
                    var start = frag.byteRangeStartOffset, end = frag.byteRangeEndOffset;
                    if (Object(number["isFiniteNumber"])(start) && Object(number["isFiniteNumber"])(end)) {
                        loaderContext.rangeStart = start;
                        loaderContext.rangeEnd = end;
                    }
                    loaderConfig = {
                        timeout: config.fragLoadingTimeOut,
                        maxRetry: 0,
                        retryDelay: 0,
                        maxRetryDelay: config.fragLoadingMaxRetryTimeout
                    };
                    loaderCallbacks = {
                        onSuccess: this.loadsuccess.bind(this),
                        onError: this.loaderror.bind(this),
                        onTimeout: this.loadtimeout.bind(this),
                        onProgress: this.loadprogress.bind(this)
                    };
                    loader.load(loaderContext, loaderConfig, loaderCallbacks);
                };
                _proto.loadsuccess = function loadsuccess(response, stats, context, networkDetails) {
                    if (networkDetails === void 0) networkDetails = null;
                    var payload = response.data, frag = context.frag; // detach fragment loader on load success
                    frag.loader = undefined;
                    this.loaders[frag.type] = undefined;
                    this.hls.trigger(events1["default"].FRAG_LOADED, {
                        payload: payload,
                        frag: frag,
                        stats: stats,
                        networkDetails: networkDetails
                    });
                };
                _proto.loaderror = function loaderror(response, context, networkDetails) {
                    if (networkDetails === void 0) networkDetails = null;
                    var frag = context.frag;
                    var loader = frag.loader;
                    if (loader) loader.abort();
                    this.loaders[frag.type] = undefined;
                    this.hls.trigger(events1["default"].ERROR, {
                        type: errors["ErrorTypes"].NETWORK_ERROR,
                        details: errors["ErrorDetails"].FRAG_LOAD_ERROR,
                        fatal: false,
                        frag: context.frag,
                        response: response,
                        networkDetails: networkDetails
                    });
                };
                _proto.loadtimeout = function loadtimeout(stats, context, networkDetails) {
                    if (networkDetails === void 0) networkDetails = null;
                    var frag = context.frag;
                    var loader = frag.loader;
                    if (loader) loader.abort();
                    this.loaders[frag.type] = undefined;
                    this.hls.trigger(events1["default"].ERROR, {
                        type: errors["ErrorTypes"].NETWORK_ERROR,
                        details: errors["ErrorDetails"].FRAG_LOAD_TIMEOUT,
                        fatal: false,
                        frag: context.frag,
                        networkDetails: networkDetails
                    });
                } // data will be used for progressive parsing
                ;
                _proto.loadprogress = function loadprogress(stats, context, data, networkDetails) {
                    if (networkDetails === void 0) networkDetails = null;
                    // jshint ignore:line
                    var frag = context.frag;
                    frag.loaded = stats.loaded;
                    this.hls.trigger(events1["default"].FRAG_LOAD_PROGRESS, {
                        frag: frag,
                        stats: stats,
                        networkDetails: networkDetails
                    });
                };
                return FragmentLoader;
            }(event_handler);
            /* harmony default export */ var fragment_loader = fragment_loader_FragmentLoader;
            // CONCATENATED MODULE: ./src/loader/key-loader.ts
            function key_loader_inheritsLoose(subClass, superClass) {
                subClass.prototype = Object.create(superClass.prototype);
                subClass.prototype.constructor = subClass;
                subClass.__proto__ = superClass;
            }
            /*
 * Decrypt key Loader
*/ var key_loader_KeyLoader = /*#__PURE__*/ function(_EventHandler) {
                key_loader_inheritsLoose(KeyLoader, _EventHandler);
                function KeyLoader(hls) {
                    var _this;
                    _this = _EventHandler.call(this, hls, events1["default"].KEY_LOADING) || this;
                    _this.loaders = {
                    };
                    _this.decryptkey = null;
                    _this.decrypturl = null;
                    return _this;
                }
                var _proto = KeyLoader.prototype;
                _proto.destroy = function destroy() {
                    for(var loaderName in this.loaders){
                        var loader = this.loaders[loaderName];
                        if (loader) loader.destroy();
                    }
                    this.loaders = {
                    };
                    _EventHandler.prototype.destroy.call(this);
                };
                _proto.onKeyLoading = function onKeyLoading(data) {
                    var frag = data.frag;
                    var type = frag.type;
                    var loader = this.loaders[type];
                    if (!frag.decryptdata) {
                        logger1["logger"].warn('Missing decryption data on fragment in onKeyLoading');
                        return;
                    } // Load the key if the uri is different from previous one, or if the decrypt key has not yet been retrieved
                    var uri = frag.decryptdata.uri;
                    if (uri !== this.decrypturl || this.decryptkey === null) {
                        var config = this.hls.config;
                        if (loader) {
                            logger1["logger"].warn("abort previous key loader for type:" + type);
                            loader.abort();
                        }
                        if (!uri) {
                            logger1["logger"].warn('key uri is falsy');
                            return;
                        }
                        frag.loader = this.loaders[type] = new config.loader(config);
                        this.decrypturl = uri;
                        this.decryptkey = null;
                        var loaderContext = {
                            url: uri,
                            frag: frag,
                            responseType: 'arraybuffer'
                        }; // maxRetry is 0 so that instead of retrying the same key on the same variant multiple times,
                        // key-loader will trigger an error and rely on stream-controller to handle retry logic.
                        // this will also align retry logic with fragment-loader
                        var loaderConfig = {
                            timeout: config.fragLoadingTimeOut,
                            maxRetry: 0,
                            retryDelay: config.fragLoadingRetryDelay,
                            maxRetryDelay: config.fragLoadingMaxRetryTimeout
                        };
                        var loaderCallbacks = {
                            onSuccess: this.loadsuccess.bind(this),
                            onError: this.loaderror.bind(this),
                            onTimeout: this.loadtimeout.bind(this)
                        };
                        frag.loader.load(loaderContext, loaderConfig, loaderCallbacks);
                    } else if (this.decryptkey) {
                        // Return the key if it's already been loaded
                        frag.decryptdata.key = this.decryptkey;
                        this.hls.trigger(events1["default"].KEY_LOADED, {
                            frag: frag
                        });
                    }
                };
                _proto.loadsuccess = function loadsuccess(response, stats, context) {
                    var frag = context.frag;
                    if (!frag.decryptdata) {
                        logger1["logger"].error('after key load, decryptdata unset');
                        return;
                    }
                    this.decryptkey = frag.decryptdata.key = new Uint8Array(response.data); // detach fragment loader on load success
                    frag.loader = undefined;
                    delete this.loaders[frag.type];
                    this.hls.trigger(events1["default"].KEY_LOADED, {
                        frag: frag
                    });
                };
                _proto.loaderror = function loaderror(response, context) {
                    var frag = context.frag;
                    var loader = frag.loader;
                    if (loader) loader.abort();
                    delete this.loaders[frag.type];
                    this.hls.trigger(events1["default"].ERROR, {
                        type: errors["ErrorTypes"].NETWORK_ERROR,
                        details: errors["ErrorDetails"].KEY_LOAD_ERROR,
                        fatal: false,
                        frag: frag,
                        response: response
                    });
                };
                _proto.loadtimeout = function loadtimeout(stats, context) {
                    var frag = context.frag;
                    var loader = frag.loader;
                    if (loader) loader.abort();
                    delete this.loaders[frag.type];
                    this.hls.trigger(events1["default"].ERROR, {
                        type: errors["ErrorTypes"].NETWORK_ERROR,
                        details: errors["ErrorDetails"].KEY_LOAD_TIMEOUT,
                        fatal: false,
                        frag: frag
                    });
                };
                return KeyLoader;
            }(event_handler);
            /* harmony default export */ var key_loader = key_loader_KeyLoader;
            // CONCATENATED MODULE: ./src/controller/fragment-tracker.js
            function fragment_tracker_inheritsLoose(subClass, superClass) {
                subClass.prototype = Object.create(superClass.prototype);
                subClass.prototype.constructor = subClass;
                subClass.__proto__ = superClass;
            }
            var FragmentState = {
                NOT_LOADED: 'NOT_LOADED',
                APPENDING: 'APPENDING',
                PARTIAL: 'PARTIAL',
                OK: 'OK'
            };
            var fragment_tracker_FragmentTracker = /*#__PURE__*/ function(_EventHandler) {
                fragment_tracker_inheritsLoose(FragmentTracker, _EventHandler);
                function FragmentTracker(hls) {
                    var _this;
                    _this = _EventHandler.call(this, hls, events1["default"].BUFFER_APPENDED, events1["default"].FRAG_BUFFERED, events1["default"].FRAG_LOADED) || this;
                    _this.bufferPadding = 0.2;
                    _this.fragments = Object.create(null);
                    _this.timeRanges = Object.create(null);
                    _this.config = hls.config;
                    return _this;
                }
                var _proto = FragmentTracker.prototype;
                _proto.destroy = function destroy() {
                    this.fragments = Object.create(null);
                    this.timeRanges = Object.create(null);
                    this.config = null;
                    event_handler.prototype.destroy.call(this);
                    _EventHandler.prototype.destroy.call(this);
                };
                _proto.getBufferedFrag = function getBufferedFrag(position, levelType) {
                    var fragments = this.fragments;
                    var bufferedFrags = Object.keys(fragments).filter(function(key) {
                        var fragmentEntity = fragments[key];
                        if (fragmentEntity.body.type !== levelType) return false;
                        if (!fragmentEntity.buffered) return false;
                        var frag = fragmentEntity.body;
                        return frag.startPTS <= position && position <= frag.endPTS;
                    });
                    if (bufferedFrags.length === 0) return null;
                    else {
                        // https://github.com/video-dev/hls.js/pull/1545#discussion_r166229566
                        var bufferedFragKey = bufferedFrags.pop();
                        return fragments[bufferedFragKey].body;
                    }
                };
                _proto.detectEvictedFragments = function detectEvictedFragments(elementaryStream, timeRange) {
                    var _this2 = this;
                    // Check if any flagged fragments have been unloaded
                    Object.keys(this.fragments).forEach(function(key) {
                        var fragmentEntity = _this2.fragments[key];
                        if (!fragmentEntity || !fragmentEntity.buffered) return;
                        var esData = fragmentEntity.range[elementaryStream];
                        if (!esData) return;
                        var fragmentTimes = esData.time;
                        for(var i = 0; i < fragmentTimes.length; i++){
                            var time = fragmentTimes[i];
                            if (!_this2.isTimeBuffered(time.startPTS, time.endPTS, timeRange)) {
                                // Unregister partial fragment as it needs to load again to be reused
                                _this2.removeFragment(fragmentEntity.body);
                                break;
                            }
                        }
                    });
                };
                _proto.detectPartialFragments = function detectPartialFragments(fragment) {
                    var _this3 = this;
                    var fragKey = this.getFragmentKey(fragment);
                    var fragmentEntity = this.fragments[fragKey];
                    if (fragmentEntity) {
                        fragmentEntity.buffered = true;
                        Object.keys(this.timeRanges).forEach(function(elementaryStream) {
                            if (fragment.hasElementaryStream(elementaryStream)) {
                                var timeRange = _this3.timeRanges[elementaryStream]; // Check for malformed fragments
                                // Gaps need to be calculated for each elementaryStream
                                fragmentEntity.range[elementaryStream] = _this3.getBufferedTimes(fragment.startPTS, fragment.endPTS, timeRange);
                            }
                        });
                    }
                };
                _proto.getBufferedTimes = function getBufferedTimes(startPTS, endPTS, timeRange) {
                    var fragmentTimes = [];
                    var startTime, endTime;
                    var fragmentPartial = false;
                    for(var i = 0; i < timeRange.length; i++){
                        startTime = timeRange.start(i) - this.bufferPadding;
                        endTime = timeRange.end(i) + this.bufferPadding;
                        if (startPTS >= startTime && endPTS <= endTime) {
                            // Fragment is entirely contained in buffer
                            // No need to check the other timeRange times since it's completely playable
                            fragmentTimes.push({
                                startPTS: Math.max(startPTS, timeRange.start(i)),
                                endPTS: Math.min(endPTS, timeRange.end(i))
                            });
                            break;
                        } else if (startPTS < endTime && endPTS > startTime) {
                            // Check for intersection with buffer
                            // Get playable sections of the fragment
                            fragmentTimes.push({
                                startPTS: Math.max(startPTS, timeRange.start(i)),
                                endPTS: Math.min(endPTS, timeRange.end(i))
                            });
                            fragmentPartial = true;
                        } else if (endPTS <= startTime) break;
                    }
                    return {
                        time: fragmentTimes,
                        partial: fragmentPartial
                    };
                };
                _proto.getFragmentKey = function getFragmentKey(fragment) {
                    return fragment.type + "_" + fragment.level + "_" + fragment.urlId + "_" + fragment.sn;
                };
                _proto.getPartialFragment = function getPartialFragment(time) {
                    var _this4 = this;
                    var timePadding, startTime, endTime;
                    var bestFragment = null;
                    var bestOverlap = 0;
                    Object.keys(this.fragments).forEach(function(key) {
                        var fragmentEntity = _this4.fragments[key];
                        if (_this4.isPartial(fragmentEntity)) {
                            startTime = fragmentEntity.body.startPTS - _this4.bufferPadding;
                            endTime = fragmentEntity.body.endPTS + _this4.bufferPadding;
                            if (time >= startTime && time <= endTime) {
                                // Use the fragment that has the most padding from start and end time
                                timePadding = Math.min(time - startTime, endTime - time);
                                if (bestOverlap <= timePadding) {
                                    bestFragment = fragmentEntity.body;
                                    bestOverlap = timePadding;
                                }
                            }
                        }
                    });
                    return bestFragment;
                };
                _proto.getState = function getState(fragment) {
                    var fragKey = this.getFragmentKey(fragment);
                    var fragmentEntity = this.fragments[fragKey];
                    var state = FragmentState.NOT_LOADED;
                    if (fragmentEntity !== undefined) {
                        if (!fragmentEntity.buffered) state = FragmentState.APPENDING;
                        else if (this.isPartial(fragmentEntity) === true) state = FragmentState.PARTIAL;
                        else state = FragmentState.OK;
                    }
                    return state;
                };
                _proto.isPartial = function isPartial(fragmentEntity) {
                    return fragmentEntity.buffered === true && (fragmentEntity.range.video !== undefined && fragmentEntity.range.video.partial === true || fragmentEntity.range.audio !== undefined && fragmentEntity.range.audio.partial === true);
                };
                _proto.isTimeBuffered = function isTimeBuffered(startPTS, endPTS, timeRange) {
                    var startTime, endTime;
                    for(var i = 0; i < timeRange.length; i++){
                        startTime = timeRange.start(i) - this.bufferPadding;
                        endTime = timeRange.end(i) + this.bufferPadding;
                        if (startPTS >= startTime && endPTS <= endTime) return true;
                        if (endPTS <= startTime) // No need to check the rest of the timeRange as it is in order
                        return false;
                    }
                    return false;
                };
                _proto.onFragLoaded = function onFragLoaded(e) {
                    var fragment = e.frag; // don't track initsegment (for which sn is not a number)
                    // don't track frags used for bitrateTest, they're irrelevant.
                    if (!Object(number["isFiniteNumber"])(fragment.sn) || fragment.bitrateTest) return;
                    this.fragments[this.getFragmentKey(fragment)] = {
                        body: fragment,
                        range: Object.create(null),
                        buffered: false
                    };
                };
                _proto.onBufferAppended = function onBufferAppended(e) {
                    var _this5 = this;
                    // Store the latest timeRanges loaded in the buffer
                    this.timeRanges = e.timeRanges;
                    Object.keys(this.timeRanges).forEach(function(elementaryStream) {
                        var timeRange = _this5.timeRanges[elementaryStream];
                        _this5.detectEvictedFragments(elementaryStream, timeRange);
                    });
                };
                _proto.onFragBuffered = function onFragBuffered(e) {
                    this.detectPartialFragments(e.frag);
                };
                _proto.hasFragment = function hasFragment(fragment) {
                    var fragKey = this.getFragmentKey(fragment);
                    return this.fragments[fragKey] !== undefined;
                };
                _proto.removeFragment = function removeFragment(fragment) {
                    var fragKey = this.getFragmentKey(fragment);
                    delete this.fragments[fragKey];
                };
                _proto.removeAllFragments = function removeAllFragments() {
                    this.fragments = Object.create(null);
                };
                return FragmentTracker;
            }(event_handler);
            // CONCATENATED MODULE: ./src/utils/binary-search.ts
            var BinarySearch = {
                /**
   * Searches for an item in an array which matches a certain condition.
   * This requires the condition to only match one item in the array,
   * and for the array to be ordered.
   *
   * @param {Array<T>} list The array to search.
   * @param {BinarySearchComparison<T>} comparisonFn
   *      Called and provided a candidate item as the first argument.
   *      Should return:
   *          > -1 if the item should be located at a lower index than the provided item.
   *          > 1 if the item should be located at a higher index than the provided item.
   *          > 0 if the item is the item you're looking for.
   *
   * @return {T | null} The object if it is found or null otherwise.
   */ search: function search(list, comparisonFn) {
                    var minIndex = 0;
                    var maxIndex = list.length - 1;
                    var currentIndex = null;
                    var currentElement = null;
                    while(minIndex <= maxIndex){
                        currentIndex = (minIndex + maxIndex) / 2 | 0;
                        currentElement = list[currentIndex];
                        var comparisonResult = comparisonFn(currentElement);
                        if (comparisonResult > 0) minIndex = currentIndex + 1;
                        else if (comparisonResult < 0) maxIndex = currentIndex - 1;
                        else return currentElement;
                    }
                    return null;
                }
            };
            /* harmony default export */ var binary_search = BinarySearch;
            // CONCATENATED MODULE: ./src/utils/buffer-helper.ts
            /**
 * @module BufferHelper
 *
 * Providing methods dealing with buffer length retrieval for example.
 *
 * In general, a helper around HTML5 MediaElement TimeRanges gathered from `buffered` property.
 *
 * Also @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/buffered
*/ var BufferHelper1 = /*#__PURE__*/ function() {
                function BufferHelper() {
                }
                /**
   * Return true if `media`'s buffered include `position`
   * @param {Bufferable} media
   * @param {number} position
   * @returns {boolean}
   */ BufferHelper.isBuffered = function isBuffered(media, position) {
                    try {
                        if (media) {
                            var buffered = media.buffered;
                            for(var i = 0; i < buffered.length; i++){
                                if (position >= buffered.start(i) && position <= buffered.end(i)) return true;
                            }
                        }
                    } catch (error) {
                    // InvalidStateError: Failed to read the 'buffered' property from 'SourceBuffer':
                    // This SourceBuffer has been removed from the parent media source
                    }
                    return false;
                };
                BufferHelper.bufferInfo = function bufferInfo(media, pos, maxHoleDuration) {
                    try {
                        if (media) {
                            var vbuffered = media.buffered;
                            var buffered = [];
                            var i;
                            for(i = 0; i < vbuffered.length; i++)buffered.push({
                                start: vbuffered.start(i),
                                end: vbuffered.end(i)
                            });
                            return this.bufferedInfo(buffered, pos, maxHoleDuration);
                        }
                    } catch (error) {
                    // InvalidStateError: Failed to read the 'buffered' property from 'SourceBuffer':
                    // This SourceBuffer has been removed from the parent media source
                    }
                    return {
                        len: 0,
                        start: pos,
                        end: pos,
                        nextStart: undefined
                    };
                };
                BufferHelper.bufferedInfo = function bufferedInfo(buffered, pos, maxHoleDuration) {
                    // sort on buffer.start/smaller end (IE does not always return sorted buffered range)
                    buffered.sort(function(a, b) {
                        var diff = a.start - b.start;
                        if (diff) return diff;
                        else return b.end - a.end;
                    });
                    var buffered2 = [];
                    if (maxHoleDuration) // there might be some small holes between buffer time range
                    // consider that holes smaller than maxHoleDuration are irrelevant and build another
                    // buffer time range representations that discards those holes
                    for(var i = 0; i < buffered.length; i++){
                        var buf2len = buffered2.length;
                        if (buf2len) {
                            var buf2end = buffered2[buf2len - 1].end; // if small hole (value between 0 or maxHoleDuration ) or overlapping (negative)
                            if (buffered[i].start - buf2end < maxHoleDuration) // merge overlapping time ranges
                            // update lastRange.end only if smaller than item.end
                            // e.g.  [ 1, 15] with  [ 2,8] => [ 1,15] (no need to modify lastRange.end)
                            // whereas [ 1, 8] with  [ 2,15] => [ 1,15] ( lastRange should switch from [1,8] to [1,15])
                            {
                                if (buffered[i].end > buf2end) buffered2[buf2len - 1].end = buffered[i].end;
                            } else // big hole
                            buffered2.push(buffered[i]);
                        } else // first value
                        buffered2.push(buffered[i]);
                    }
                    else buffered2 = buffered;
                    var bufferLen = 0; // bufferStartNext can possibly be undefined based on the conditional logic below
                    var bufferStartNext; // bufferStart and bufferEnd are buffer boundaries around current video position
                    var bufferStart = pos;
                    var bufferEnd = pos;
                    for(var _i = 0; _i < buffered2.length; _i++){
                        var start = buffered2[_i].start, end = buffered2[_i].end; // logger.log('buf start/end:' + buffered.start(i) + '/' + buffered.end(i));
                        if (pos + maxHoleDuration >= start && pos < end) {
                            // play position is inside this buffer TimeRange, retrieve end of buffer position and buffer length
                            bufferStart = start;
                            bufferEnd = end;
                            bufferLen = bufferEnd - pos;
                        } else if (pos + maxHoleDuration < start) {
                            bufferStartNext = start;
                            break;
                        }
                    }
                    return {
                        len: bufferLen,
                        start: bufferStart,
                        end: bufferEnd,
                        nextStart: bufferStartNext
                    };
                };
                return BufferHelper;
            }();
            // EXTERNAL MODULE: ./node_modules/eventemitter3/index.js
            var eventemitter3 = __webpack_require__("./node_modules/eventemitter3/index.js");
            // EXTERNAL MODULE: ./node_modules/webworkify-webpack/index.js
            var webworkify_webpack = __webpack_require__("./node_modules/webworkify-webpack/index.js");
            // EXTERNAL MODULE: ./src/demux/demuxer-inline.js + 12 modules
            var demuxer_inline = __webpack_require__("./src/demux/demuxer-inline.js");
            // CONCATENATED MODULE: ./src/utils/mediasource-helper.ts
            /**
 * MediaSource helper
 */ function getMediaSource() {
                return window.MediaSource || window.WebKitMediaSource;
            }
            // EXTERNAL MODULE: ./src/utils/get-self-scope.js
            var get_self_scope = __webpack_require__("./src/utils/get-self-scope.js");
            // CONCATENATED MODULE: ./src/observer.ts
            function observer_inheritsLoose(subClass, superClass) {
                subClass.prototype = Object.create(superClass.prototype);
                subClass.prototype.constructor = subClass;
                subClass.__proto__ = superClass;
            }
            /**
 * Simple adapter sub-class of Nodejs-like EventEmitter.
 */ var Observer1 = /*#__PURE__*/ function(_EventEmitter) {
                observer_inheritsLoose(Observer, _EventEmitter);
                function Observer() {
                    return _EventEmitter.apply(this, arguments) || this;
                }
                var _proto = Observer.prototype;
                /**
   * We simply want to pass along the event-name itself
   * in every call to a handler, which is the purpose of our `trigger` method
   * extending the standard API.
   */ _proto.trigger = function trigger(event) {
                    for(var _len = arguments.length, data = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++)data[_key - 1] = arguments[_key];
                    this.emit.apply(this, [
                        event,
                        event
                    ].concat(data));
                };
                return Observer;
            }(eventemitter3["EventEmitter"]);
            // CONCATENATED MODULE: ./src/demux/demuxer.js
            // see https://stackoverflow.com/a/11237259/589493
            var global = Object(get_self_scope["getSelfScope"])(); // safeguard for code that might run both on worker and main thread
            var demuxer_MediaSource = getMediaSource() || {
                isTypeSupported: function isTypeSupported() {
                    return false;
                }
            };
            var demuxer_Demuxer = /*#__PURE__*/ function() {
                function Demuxer(hls, id) {
                    var _this = this;
                    this.hls = hls;
                    this.id = id;
                    var observer = this.observer = new Observer1();
                    var config = hls.config;
                    var forwardMessage = function forwardMessage(ev, data) {
                        data = data || {
                        };
                        data.frag = _this.frag;
                        data.id = _this.id;
                        hls.trigger(ev, data);
                    }; // forward events to main thread
                    observer.on(events1["default"].FRAG_DECRYPTED, forwardMessage);
                    observer.on(events1["default"].FRAG_PARSING_INIT_SEGMENT, forwardMessage);
                    observer.on(events1["default"].FRAG_PARSING_DATA, forwardMessage);
                    observer.on(events1["default"].FRAG_PARSED, forwardMessage);
                    observer.on(events1["default"].ERROR, forwardMessage);
                    observer.on(events1["default"].FRAG_PARSING_METADATA, forwardMessage);
                    observer.on(events1["default"].FRAG_PARSING_USERDATA, forwardMessage);
                    observer.on(events1["default"].INIT_PTS_FOUND, forwardMessage);
                    var typeSupported = {
                        mp4: demuxer_MediaSource.isTypeSupported('video/mp4'),
                        mpeg: demuxer_MediaSource.isTypeSupported('audio/mpeg'),
                        mp3: demuxer_MediaSource.isTypeSupported('audio/mp4; codecs="mp3"')
                    }; // navigator.vendor is not always available in Web Worker
                    // refer to https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/navigator
                    var vendor = navigator.vendor;
                    if (config.enableWorker && typeof Worker !== 'undefined') {
                        logger1["logger"].log('demuxing in webworker');
                        var w;
                        try {
                            w = this.w = webworkify_webpack(/*! ../demux/demuxer-worker.js */ "./src/demux/demuxer-worker.js");
                            this.onwmsg = this.onWorkerMessage.bind(this);
                            w.addEventListener('message', this.onwmsg);
                            w.onerror = function(event) {
                                hls.trigger(events1["default"].ERROR, {
                                    type: errors["ErrorTypes"].OTHER_ERROR,
                                    details: errors["ErrorDetails"].INTERNAL_EXCEPTION,
                                    fatal: true,
                                    event: 'demuxerWorker',
                                    err: {
                                        message: event.message + ' (' + event.filename + ':' + event.lineno + ')'
                                    }
                                });
                            };
                            w.postMessage({
                                cmd: 'init',
                                typeSupported: typeSupported,
                                vendor: vendor,
                                id: id,
                                config: JSON.stringify(config)
                            });
                        } catch (err) {
                            logger1["logger"].warn('Error in worker:', err);
                            logger1["logger"].error('Error while initializing DemuxerWorker, fallback on DemuxerInline');
                            if (w) // revoke the Object URL that was used to create demuxer worker, so as not to leak it
                            global.URL.revokeObjectURL(w.objectURL);
                            this.demuxer = new demuxer_inline["default"](observer, typeSupported, config, vendor);
                            this.w = undefined;
                        }
                    } else this.demuxer = new demuxer_inline["default"](observer, typeSupported, config, vendor);
                }
                var _proto = Demuxer.prototype;
                _proto.destroy = function destroy() {
                    var w = this.w;
                    if (w) {
                        w.removeEventListener('message', this.onwmsg);
                        w.terminate();
                        this.w = null;
                    } else {
                        var demuxer = this.demuxer;
                        if (demuxer) {
                            demuxer.destroy();
                            this.demuxer = null;
                        }
                    }
                    var observer = this.observer;
                    if (observer) {
                        observer.removeAllListeners();
                        this.observer = null;
                    }
                };
                _proto.push = function push(data, initSegment, audioCodec, videoCodec, frag, duration, accurateTimeOffset, defaultInitPTS) {
                    var w = this.w;
                    var timeOffset = Object(number["isFiniteNumber"])(frag.startPTS) ? frag.startPTS : frag.start;
                    var decryptdata = frag.decryptdata;
                    var lastFrag = this.frag;
                    var discontinuity = !(lastFrag && frag.cc === lastFrag.cc);
                    var trackSwitch = !(lastFrag && frag.level === lastFrag.level);
                    var nextSN = lastFrag && frag.sn === lastFrag.sn + 1;
                    var contiguous = !trackSwitch && nextSN;
                    if (discontinuity) logger1["logger"].log(this.id + ":discontinuity detected");
                    if (trackSwitch) logger1["logger"].log(this.id + ":switch detected");
                    this.frag = frag;
                    if (w) // post fragment payload as transferable objects for ArrayBuffer (no copy)
                    w.postMessage({
                        cmd: 'demux',
                        data: data,
                        decryptdata: decryptdata,
                        initSegment: initSegment,
                        audioCodec: audioCodec,
                        videoCodec: videoCodec,
                        timeOffset: timeOffset,
                        discontinuity: discontinuity,
                        trackSwitch: trackSwitch,
                        contiguous: contiguous,
                        duration: duration,
                        accurateTimeOffset: accurateTimeOffset,
                        defaultInitPTS: defaultInitPTS
                    }, data instanceof ArrayBuffer ? [
                        data
                    ] : []);
                    else {
                        var demuxer = this.demuxer;
                        if (demuxer) demuxer.push(data, decryptdata, initSegment, audioCodec, videoCodec, timeOffset, discontinuity, trackSwitch, contiguous, duration, accurateTimeOffset, defaultInitPTS);
                    }
                };
                _proto.onWorkerMessage = function onWorkerMessage(ev) {
                    var data = ev.data, hls = this.hls;
                    switch(data.event){
                        case 'init':
                            // revoke the Object URL that was used to create demuxer worker, so as not to leak it
                            global.URL.revokeObjectURL(this.w.objectURL);
                            break;
                        // special case for FRAG_PARSING_DATA: data1 and data2 are transferable objects
                        case events1["default"].FRAG_PARSING_DATA:
                            data.data.data1 = new Uint8Array(data.data1);
                            if (data.data2) data.data.data2 = new Uint8Array(data.data2);
                        /* falls through */ default:
                            data.data = data.data || {
                            };
                            data.data.frag = this.frag;
                            data.data.id = this.id;
                            hls.trigger(data.event, data.data);
                            break;
                    }
                };
                return Demuxer;
            }();
            /* harmony default export */ var demux_demuxer = demuxer_Demuxer;
            // CONCATENATED MODULE: ./src/controller/level-helper.js
            /**
 * @module LevelHelper
 *
 * Providing methods dealing with playlist sliding and drift
 *
 * TODO: Create an actual `Level` class/model that deals with all this logic in an object-oriented-manner.
 *
 * */ function addGroupId(level, type, id) {
                switch(type){
                    case 'audio':
                        if (!level.audioGroupIds) level.audioGroupIds = [];
                        level.audioGroupIds.push(id);
                        break;
                    case 'text':
                        if (!level.textGroupIds) level.textGroupIds = [];
                        level.textGroupIds.push(id);
                        break;
                }
            }
            function updatePTS(fragments, fromIdx, toIdx) {
                var fragFrom = fragments[fromIdx], fragTo = fragments[toIdx], fragToPTS = fragTo.startPTS; // if we know startPTS[toIdx]
                if (Object(number["isFiniteNumber"])(fragToPTS)) {
                    // update fragment duration.
                    // it helps to fix drifts between playlist reported duration and fragment real duration
                    if (toIdx > fromIdx) {
                        fragFrom.duration = fragToPTS - fragFrom.start;
                        if (fragFrom.duration < 0) logger1["logger"].warn("negative duration computed for frag " + fragFrom.sn + ",level " + fragFrom.level + ", there should be some duration drift between playlist and fragment!");
                    } else {
                        fragTo.duration = fragFrom.start - fragToPTS;
                        if (fragTo.duration < 0) logger1["logger"].warn("negative duration computed for frag " + fragTo.sn + ",level " + fragTo.level + ", there should be some duration drift between playlist and fragment!");
                    }
                } else // we dont know startPTS[toIdx]
                if (toIdx > fromIdx) {
                    var contiguous = fragFrom.cc === fragTo.cc;
                    fragTo.start = fragFrom.start + (contiguous && fragFrom.minEndPTS ? fragFrom.minEndPTS - fragFrom.start : fragFrom.duration);
                } else fragTo.start = Math.max(fragFrom.start - fragTo.duration, 0);
            }
            function updateFragPTSDTS(details, frag, startPTS, endPTS, startDTS, endDTS) {
                // update frag PTS/DTS
                var maxStartPTS = startPTS;
                var minEndPTS = endPTS;
                if (Object(number["isFiniteNumber"])(frag.startPTS)) {
                    // delta PTS between audio and video
                    var deltaPTS = Math.abs(frag.startPTS - startPTS);
                    if (!Object(number["isFiniteNumber"])(frag.deltaPTS)) frag.deltaPTS = deltaPTS;
                    else frag.deltaPTS = Math.max(deltaPTS, frag.deltaPTS);
                    maxStartPTS = Math.max(startPTS, frag.startPTS);
                    startPTS = Math.min(startPTS, frag.startPTS);
                    minEndPTS = Math.min(endPTS, frag.endPTS);
                    endPTS = Math.max(endPTS, frag.endPTS);
                    startDTS = Math.min(startDTS, frag.startDTS);
                    endDTS = Math.max(endDTS, frag.endDTS);
                }
                var drift = startPTS - frag.start;
                frag.start = frag.startPTS = startPTS;
                frag.maxStartPTS = maxStartPTS;
                frag.endPTS = endPTS;
                frag.minEndPTS = minEndPTS;
                frag.startDTS = startDTS;
                frag.endDTS = endDTS;
                frag.duration = endPTS - startPTS;
                var sn = frag.sn; // exit if sn out of range
                if (!details || sn < details.startSN || sn > details.endSN) return 0;
                var fragIdx, fragments, i;
                fragIdx = sn - details.startSN;
                fragments = details.fragments; // update frag reference in fragments array
                // rationale is that fragments array might not contain this frag object.
                // this will happen if playlist has been refreshed between frag loading and call to updateFragPTSDTS()
                // if we don't update frag, we won't be able to propagate PTS info on the playlist
                // resulting in invalid sliding computation
                fragments[fragIdx] = frag; // adjust fragment PTS/duration from seqnum-1 to frag 0
                for(i = fragIdx; i > 0; i--)updatePTS(fragments, i, i - 1);
                 // adjust fragment PTS/duration from seqnum to last frag
                for(i = fragIdx; i < fragments.length - 1; i++)updatePTS(fragments, i, i + 1);
                details.PTSKnown = true;
                return drift;
            }
            function mergeDetails(oldDetails, newDetails) {
                // potentially retrieve cached initsegment
                if (newDetails.initSegment && oldDetails.initSegment) newDetails.initSegment = oldDetails.initSegment;
                 // check if old/new playlists have fragments in common
                // loop through overlapping SN and update startPTS , cc, and duration if any found
                var ccOffset = 0;
                var PTSFrag;
                mapFragmentIntersection(oldDetails, newDetails, function(oldFrag, newFrag) {
                    ccOffset = oldFrag.cc - newFrag.cc;
                    if (Object(number["isFiniteNumber"])(oldFrag.startPTS)) {
                        newFrag.start = newFrag.startPTS = oldFrag.startPTS;
                        newFrag.endPTS = oldFrag.endPTS;
                        newFrag.duration = oldFrag.duration;
                        newFrag.backtracked = oldFrag.backtracked;
                        newFrag.dropped = oldFrag.dropped;
                        PTSFrag = newFrag;
                    } // PTS is known when there are overlapping segments
                    newDetails.PTSKnown = true;
                });
                if (!newDetails.PTSKnown) return;
                if (ccOffset) {
                    logger1["logger"].log('discontinuity sliding from playlist, take drift into account');
                    var newFragments = newDetails.fragments;
                    for(var i = 0; i < newFragments.length; i++)newFragments[i].cc += ccOffset;
                } // if at least one fragment contains PTS info, recompute PTS information for all fragments
                if (PTSFrag) updateFragPTSDTS(newDetails, PTSFrag, PTSFrag.startPTS, PTSFrag.endPTS, PTSFrag.startDTS, PTSFrag.endDTS);
                else // ensure that delta is within oldFragments range
                // also adjust sliding in case delta is 0 (we could have old=[50-60] and new=old=[50-61])
                // in that case we also need to adjust start offset of all fragments
                adjustSliding(oldDetails, newDetails);
                 // if we are here, it means we have fragments overlapping between
                // old and new level. reliable PTS info is thus relying on old level
                newDetails.PTSKnown = oldDetails.PTSKnown;
            }
            function mergeSubtitlePlaylists(oldPlaylist, newPlaylist, referenceStart) {
                if (referenceStart === void 0) referenceStart = 0;
                var lastIndex = -1;
                mapFragmentIntersection(oldPlaylist, newPlaylist, function(oldFrag, newFrag, index) {
                    newFrag.start = oldFrag.start;
                    lastIndex = index;
                });
                var frags = newPlaylist.fragments;
                if (lastIndex < 0) {
                    frags.forEach(function(frag) {
                        frag.start += referenceStart;
                    });
                    return;
                }
                for(var i = lastIndex + 1; i < frags.length; i++)frags[i].start = frags[i - 1].start + frags[i - 1].duration;
            }
            function mapFragmentIntersection(oldPlaylist, newPlaylist, intersectionFn) {
                if (!oldPlaylist || !newPlaylist) return;
                var start = Math.max(oldPlaylist.startSN, newPlaylist.startSN) - newPlaylist.startSN;
                var end = Math.min(oldPlaylist.endSN, newPlaylist.endSN) - newPlaylist.startSN;
                var delta = newPlaylist.startSN - oldPlaylist.startSN;
                for(var i = start; i <= end; i++){
                    var oldFrag = oldPlaylist.fragments[delta + i];
                    var newFrag = newPlaylist.fragments[i];
                    if (!oldFrag || !newFrag) break;
                    intersectionFn(oldFrag, newFrag, i);
                }
            }
            function adjustSliding(oldPlaylist, newPlaylist) {
                var delta = newPlaylist.startSN - oldPlaylist.startSN;
                var oldFragments = oldPlaylist.fragments;
                var newFragments = newPlaylist.fragments;
                if (delta < 0 || delta > oldFragments.length) return;
                for(var i = 0; i < newFragments.length; i++)newFragments[i].start += oldFragments[delta].start;
            }
            function computeReloadInterval(currentPlaylist, newPlaylist, lastRequestTime) {
                var reloadInterval = 1000 * (newPlaylist.averagetargetduration ? newPlaylist.averagetargetduration : newPlaylist.targetduration);
                var minReloadInterval = reloadInterval / 2;
                if (currentPlaylist && newPlaylist.endSN === currentPlaylist.endSN) // follow HLS Spec, If the client reloads a Playlist file and finds that it has not
                // changed then it MUST wait for a period of one-half the target
                // duration before retrying.
                reloadInterval = minReloadInterval;
                if (lastRequestTime) reloadInterval = Math.max(minReloadInterval, reloadInterval - (window.performance.now() - lastRequestTime));
                 // in any case, don't reload more than half of target duration
                return Math.round(reloadInterval);
            }
            // CONCATENATED MODULE: ./src/utils/time-ranges.ts
            /**
 *  TimeRanges to string helper
 */ var TimeRanges = {
                toString: function toString(r) {
                    var log = '';
                    var len = r.length;
                    for(var i = 0; i < len; i++)log += '[' + r.start(i).toFixed(3) + ',' + r.end(i).toFixed(3) + ']';
                    return log;
                }
            };
            /* harmony default export */ var time_ranges = TimeRanges;
            // CONCATENATED MODULE: ./src/utils/discontinuities.js
            function findFirstFragWithCC(fragments, cc) {
                var firstFrag = null;
                for(var i = 0; i < fragments.length; i += 1){
                    var currentFrag = fragments[i];
                    if (currentFrag && currentFrag.cc === cc) {
                        firstFrag = currentFrag;
                        break;
                    }
                }
                return firstFrag;
            }
            function findFragWithCC(fragments, CC) {
                return binary_search.search(fragments, function(candidate) {
                    if (candidate.cc < CC) return 1;
                    else if (candidate.cc > CC) return -1;
                    else return 0;
                });
            }
            function shouldAlignOnDiscontinuities(lastFrag, lastLevel, details) {
                var shouldAlign = false;
                if (lastLevel && lastLevel.details && details) {
                    if (details.endCC > details.startCC || lastFrag && lastFrag.cc < details.startCC) shouldAlign = true;
                }
                return shouldAlign;
            } // Find the first frag in the previous level which matches the CC of the first frag of the new level
            function findDiscontinuousReferenceFrag(prevDetails, curDetails) {
                var prevFrags = prevDetails.fragments;
                var curFrags = curDetails.fragments;
                if (!curFrags.length || !prevFrags.length) {
                    logger1["logger"].log('No fragments to align');
                    return;
                }
                var prevStartFrag = findFirstFragWithCC(prevFrags, curFrags[0].cc);
                if (!prevStartFrag || prevStartFrag && !prevStartFrag.startPTS) {
                    logger1["logger"].log('No frag in previous level to align on');
                    return;
                }
                return prevStartFrag;
            }
            function adjustPts(sliding, details) {
                details.fragments.forEach(function(frag) {
                    if (frag) {
                        var start = frag.start + sliding;
                        frag.start = frag.startPTS = start;
                        frag.endPTS = start + frag.duration;
                    }
                });
                details.PTSKnown = true;
            }
            /**
 * Using the parameters of the last level, this function computes PTS' of the new fragments so that they form a
 * contiguous stream with the last fragments.
 * The PTS of a fragment lets Hls.js know where it fits into a stream - by knowing every PTS, we know which fragment to
 * download at any given time. PTS is normally computed when the fragment is demuxed, so taking this step saves us time
 * and an extra download.
 * @param lastFrag
 * @param lastLevel
 * @param details
 */ function alignStream(lastFrag, lastLevel, details) {
                alignDiscontinuities(lastFrag, details, lastLevel);
                if (!details.PTSKnown && lastLevel) // If the PTS wasn't figured out via discontinuity sequence that means there was no CC increase within the level.
                // Aligning via Program Date Time should therefore be reliable, since PDT should be the same within the same
                // discontinuity sequence.
                alignPDT(details, lastLevel.details);
            }
            /**
 * Computes the PTS if a new level's fragments using the PTS of a fragment in the last level which shares the same
 * discontinuity sequence.
 * @param lastLevel - The details of the last loaded level
 * @param details - The details of the new level
 */ function alignDiscontinuities(lastFrag, details, lastLevel) {
                if (shouldAlignOnDiscontinuities(lastFrag, lastLevel, details)) {
                    var referenceFrag = findDiscontinuousReferenceFrag(lastLevel.details, details);
                    if (referenceFrag) {
                        logger1["logger"].log('Adjusting PTS using last level due to CC increase within current level');
                        adjustPts(referenceFrag.start, details);
                    }
                }
            }
            /**
 * Computes the PTS of a new level's fragments using the difference in Program Date Time from the last level.
 * @param details - The details of the new level
 * @param lastDetails - The details of the last loaded level
 */ function alignPDT(details, lastDetails) {
                if (lastDetails && lastDetails.fragments.length) {
                    if (!details.hasProgramDateTime || !lastDetails.hasProgramDateTime) return;
                     // if last level sliding is 1000 and its first frag PROGRAM-DATE-TIME is 2017-08-20 1:10:00 AM
                    // and if new details first frag PROGRAM DATE-TIME is 2017-08-20 1:10:08 AM
                    // then we can deduce that playlist B sliding is 1000+8 = 1008s
                    var lastPDT = lastDetails.fragments[0].programDateTime;
                    var newPDT = details.fragments[0].programDateTime; // date diff is in ms. frag.start is in seconds
                    var sliding = (newPDT - lastPDT) / 1000 + lastDetails.fragments[0].start;
                    if (Object(number["isFiniteNumber"])(sliding)) {
                        logger1["logger"].log("adjusting PTS using programDateTime delta, sliding:" + sliding.toFixed(3));
                        adjustPts(sliding, details);
                    }
                }
            }
            // CONCATENATED MODULE: ./src/controller/fragment-finders.ts
            /**
 * Returns first fragment whose endPdt value exceeds the given PDT.
 * @param {Array<Fragment>} fragments - The array of candidate fragments
 * @param {number|null} [PDTValue = null] - The PDT value which must be exceeded
 * @param {number} [maxFragLookUpTolerance = 0] - The amount of time that a fragment's start/end can be within in order to be considered contiguous
 * @returns {*|null} fragment - The best matching fragment
 */ function findFragmentByPDT(fragments, PDTValue, maxFragLookUpTolerance) {
                if (PDTValue === null || !Array.isArray(fragments) || !fragments.length || !Object(number["isFiniteNumber"])(PDTValue)) return null;
                 // if less than start
                var startPDT = fragments[0].programDateTime;
                if (PDTValue < (startPDT || 0)) return null;
                var endPDT = fragments[fragments.length - 1].endProgramDateTime;
                if (PDTValue >= (endPDT || 0)) return null;
                maxFragLookUpTolerance = maxFragLookUpTolerance || 0;
                for(var seg = 0; seg < fragments.length; ++seg){
                    var frag = fragments[seg];
                    if (pdtWithinToleranceTest(PDTValue, maxFragLookUpTolerance, frag)) return frag;
                }
                return null;
            }
            /**
 * Finds a fragment based on the SN of the previous fragment; or based on the needs of the current buffer.
 * This method compensates for small buffer gaps by applying a tolerance to the start of any candidate fragment, thus
 * breaking any traps which would cause the same fragment to be continuously selected within a small range.
 * @param {*} fragPrevious - The last frag successfully appended
 * @param {Array<Fragment>} fragments - The array of candidate fragments
 * @param {number} [bufferEnd = 0] - The end of the contiguous buffered range the playhead is currently within
 * @param {number} maxFragLookUpTolerance - The amount of time that a fragment's start/end can be within in order to be considered contiguous
 * @returns {*} foundFrag - The best matching fragment
 */ function findFragmentByPTS(fragPrevious, fragments, bufferEnd, maxFragLookUpTolerance) {
                if (bufferEnd === void 0) bufferEnd = 0;
                if (maxFragLookUpTolerance === void 0) maxFragLookUpTolerance = 0;
                var fragNext = null;
                if (fragPrevious) fragNext = fragments[fragPrevious.sn - fragments[0].sn + 1];
                else if (bufferEnd === 0 && fragments[0].start === 0) fragNext = fragments[0];
                 // Prefer the next fragment if it's within tolerance
                if (fragNext && fragmentWithinToleranceTest(bufferEnd, maxFragLookUpTolerance, fragNext) === 0) return fragNext;
                 // We might be seeking past the tolerance so find the best match
                var foundFragment = binary_search.search(fragments, fragmentWithinToleranceTest.bind(null, bufferEnd, maxFragLookUpTolerance));
                if (foundFragment) return foundFragment;
                 // If no match was found return the next fragment after fragPrevious, or null
                return fragNext;
            }
            /**
 * The test function used by the findFragmentBySn's BinarySearch to look for the best match to the current buffer conditions.
 * @param {*} candidate - The fragment to test
 * @param {number} [bufferEnd = 0] - The end of the current buffered range the playhead is currently within
 * @param {number} [maxFragLookUpTolerance = 0] - The amount of time that a fragment's start can be within in order to be considered contiguous
 * @returns {number} - 0 if it matches, 1 if too low, -1 if too high
 */ function fragmentWithinToleranceTest(bufferEnd, maxFragLookUpTolerance, candidate) {
                if (bufferEnd === void 0) bufferEnd = 0;
                if (maxFragLookUpTolerance === void 0) maxFragLookUpTolerance = 0;
                // offset should be within fragment boundary - config.maxFragLookUpTolerance
                // this is to cope with situations like
                // bufferEnd = 9.991
                // frag[Ø] : [0,10]
                // frag[1] : [10,20]
                // bufferEnd is within frag[0] range ... although what we are expecting is to return frag[1] here
                //              frag start               frag start+duration
                //                  |-----------------------------|
                //              <--->                         <--->
                //  ...--------><-----------------------------><---------....
                // previous frag         matching fragment         next frag
                //  return -1             return 0                 return 1
                // logger.log(`level/sn/start/end/bufEnd:${level}/${candidate.sn}/${candidate.start}/${(candidate.start+candidate.duration)}/${bufferEnd}`);
                // Set the lookup tolerance to be small enough to detect the current segment - ensures we don't skip over very small segments
                var candidateLookupTolerance = Math.min(maxFragLookUpTolerance, candidate.duration + (candidate.deltaPTS ? candidate.deltaPTS : 0));
                if (candidate.start + candidate.duration - candidateLookupTolerance <= bufferEnd) return 1;
                else if (candidate.start - candidateLookupTolerance > bufferEnd && candidate.start) // if maxFragLookUpTolerance will have negative value then don't return -1 for first element
                return -1;
                return 0;
            }
            /**
 * The test function used by the findFragmentByPdt's BinarySearch to look for the best match to the current buffer conditions.
 * This function tests the candidate's program date time values, as represented in Unix time
 * @param {*} candidate - The fragment to test
 * @param {number} [pdtBufferEnd = 0] - The Unix time representing the end of the current buffered range
 * @param {number} [maxFragLookUpTolerance = 0] - The amount of time that a fragment's start can be within in order to be considered contiguous
 * @returns {boolean} True if contiguous, false otherwise
 */ function pdtWithinToleranceTest(pdtBufferEnd, maxFragLookUpTolerance, candidate) {
                var candidateLookupTolerance = Math.min(maxFragLookUpTolerance, candidate.duration + (candidate.deltaPTS ? candidate.deltaPTS : 0)) * 1000; // endProgramDateTime can be null, default to zero
                var endProgramDateTime = candidate.endProgramDateTime || 0;
                return endProgramDateTime - candidateLookupTolerance > pdtBufferEnd;
            }
            // CONCATENATED MODULE: ./src/controller/gap-controller.js
            var STALL_MINIMUM_DURATION_MS = 250;
            var MAX_START_GAP_JUMP = 2;
            var SKIP_BUFFER_HOLE_STEP_SECONDS = 0.1;
            var SKIP_BUFFER_RANGE_START = 0.05;
            var gap_controller_GapController = /*#__PURE__*/ function() {
                function GapController(config, media, fragmentTracker, hls) {
                    this.config = config;
                    this.media = media;
                    this.fragmentTracker = fragmentTracker;
                    this.hls = hls;
                    this.nudgeRetry = 0;
                    this.stallReported = false;
                    this.stalled = null;
                    this.moved = false;
                    this.seeking = false;
                }
                /**
   * Checks if the playhead is stuck within a gap, and if so, attempts to free it.
   * A gap is an unbuffered range between two buffered ranges (or the start and the first buffered range).
   *
   * @param {number} lastCurrentTime Previously read playhead position
   */ var _proto = GapController.prototype;
                _proto.poll = function poll(lastCurrentTime) {
                    var config = this.config, media = this.media, stalled = this.stalled;
                    var currentTime = media.currentTime, seeking = media.seeking;
                    var seeked = this.seeking && !seeking;
                    var beginSeek = !this.seeking && seeking;
                    this.seeking = seeking; // The playhead is moving, no-op
                    if (currentTime !== lastCurrentTime) {
                        this.moved = true;
                        if (stalled !== null) {
                            // The playhead is now moving, but was previously stalled
                            if (this.stallReported) {
                                var _stalledDuration = self.performance.now() - stalled;
                                logger1["logger"].warn("playback not stuck anymore @" + currentTime + ", after " + Math.round(_stalledDuration) + "ms");
                                this.stallReported = false;
                            }
                            this.stalled = null;
                            this.nudgeRetry = 0;
                        }
                        return;
                    } // Clear stalled state when beginning or finishing seeking so that we don't report stalls coming out of a seek
                    if (beginSeek || seeked) this.stalled = null;
                     // The playhead should not be moving
                    if (media.paused || media.ended || media.playbackRate === 0 || !media.buffered.length) return;
                    var bufferInfo = BufferHelper1.bufferInfo(media, currentTime, 0);
                    var isBuffered = bufferInfo.len > 0;
                    var nextStart = bufferInfo.nextStart || 0; // There is no playable buffer (waiting for buffer append)
                    if (!isBuffered && !nextStart) return;
                    if (seeking) {
                        // Waiting for seeking in a buffered range to complete
                        var hasEnoughBuffer = bufferInfo.len > MAX_START_GAP_JUMP; // Next buffered range is too far ahead to jump to while still seeking
                        var noBufferGap = !nextStart || nextStart - currentTime > MAX_START_GAP_JUMP && !this.fragmentTracker.getPartialFragment(currentTime);
                        if (hasEnoughBuffer || noBufferGap) return;
                         // Reset moved state when seeking to a point in or before a gap
                        this.moved = false;
                    } // Skip start gaps if we haven't played, but the last poll detected the start of a stall
                    // The addition poll gives the browser a chance to jump the gap for us
                    if (!this.moved && this.stalled) {
                        // Jump start gaps within jump threshold
                        var startJump = Math.max(nextStart, bufferInfo.start || 0) - currentTime;
                        if (startJump > 0 && startJump <= MAX_START_GAP_JUMP) {
                            this._trySkipBufferHole(null);
                            return;
                        }
                    } // Start tracking stall time
                    var tnow = self.performance.now();
                    if (stalled === null) {
                        this.stalled = tnow;
                        return;
                    }
                    var stalledDuration = tnow - stalled;
                    if (!seeking && stalledDuration >= STALL_MINIMUM_DURATION_MS) // Report stalling after trying to fix
                    this._reportStall(bufferInfo.len);
                    var bufferedWithHoles = BufferHelper1.bufferInfo(media, currentTime, config.maxBufferHole);
                    this._tryFixBufferStall(bufferedWithHoles, stalledDuration);
                };
                _proto._tryFixBufferStall = function _tryFixBufferStall(bufferInfo, stalledDurationMs) {
                    var config = this.config, fragmentTracker = this.fragmentTracker, media = this.media;
                    var currentTime = media.currentTime;
                    var partial = fragmentTracker.getPartialFragment(currentTime);
                    if (partial) {
                        // Try to skip over the buffer hole caused by a partial fragment
                        // This method isn't limited by the size of the gap between buffered ranges
                        var targetTime = this._trySkipBufferHole(partial); // we return here in this case, meaning
                        // the branch below only executes when we don't handle a partial fragment
                        if (targetTime) return;
                    } // if we haven't had to skip over a buffer hole of a partial fragment
                    // we may just have to "nudge" the playlist as the browser decoding/rendering engine
                    // needs to cross some sort of threshold covering all source-buffers content
                    // to start playing properly.
                    if (bufferInfo.len > config.maxBufferHole && stalledDurationMs > config.highBufferWatchdogPeriod * 1000) {
                        logger1["logger"].warn('Trying to nudge playhead over buffer-hole'); // Try to nudge currentTime over a buffer hole if we've been stalling for the configured amount of seconds
                        // We only try to jump the hole if it's under the configured size
                        // Reset stalled so to rearm watchdog timer
                        this.stalled = null;
                        this._tryNudgeBuffer();
                    }
                };
                _proto._reportStall = function _reportStall(bufferLen) {
                    var hls = this.hls, media = this.media, stallReported = this.stallReported;
                    if (!stallReported) {
                        // Report stalled error once
                        this.stallReported = true;
                        logger1["logger"].warn("Playback stalling at @" + media.currentTime + " due to low buffer (buffer=" + bufferLen + ")");
                        hls.trigger(events1["default"].ERROR, {
                            type: errors["ErrorTypes"].MEDIA_ERROR,
                            details: errors["ErrorDetails"].BUFFER_STALLED_ERROR,
                            fatal: false,
                            buffer: bufferLen
                        });
                    }
                };
                _proto._trySkipBufferHole = function _trySkipBufferHole(partial) {
                    var config = this.config, hls = this.hls, media = this.media;
                    var currentTime = media.currentTime;
                    var lastEndTime = 0; // Check if currentTime is between unbuffered regions of partial fragments
                    for(var i = 0; i < media.buffered.length; i++){
                        var startTime = media.buffered.start(i);
                        if (currentTime + config.maxBufferHole >= lastEndTime && currentTime < startTime) {
                            var targetTime = Math.max(startTime + SKIP_BUFFER_RANGE_START, media.currentTime + SKIP_BUFFER_HOLE_STEP_SECONDS);
                            logger1["logger"].warn("skipping hole, adjusting currentTime from " + currentTime + " to " + targetTime);
                            this.moved = true;
                            this.stalled = null;
                            media.currentTime = targetTime;
                            if (partial) hls.trigger(events1["default"].ERROR, {
                                type: errors["ErrorTypes"].MEDIA_ERROR,
                                details: errors["ErrorDetails"].BUFFER_SEEK_OVER_HOLE,
                                fatal: false,
                                reason: "fragment loaded with buffer holes, seeking from " + currentTime + " to " + targetTime,
                                frag: partial
                            });
                            return targetTime;
                        }
                        lastEndTime = media.buffered.end(i);
                    }
                    return 0;
                };
                _proto._tryNudgeBuffer = function _tryNudgeBuffer() {
                    var config = this.config, hls = this.hls, media = this.media;
                    var currentTime = media.currentTime;
                    var nudgeRetry = (this.nudgeRetry || 0) + 1;
                    this.nudgeRetry = nudgeRetry;
                    if (nudgeRetry < config.nudgeMaxRetry) {
                        var targetTime = currentTime + nudgeRetry * config.nudgeOffset; // playback stalled in buffered area ... let's nudge currentTime to try to overcome this
                        logger1["logger"].warn("Nudging 'currentTime' from " + currentTime + " to " + targetTime);
                        media.currentTime = targetTime;
                        hls.trigger(events1["default"].ERROR, {
                            type: errors["ErrorTypes"].MEDIA_ERROR,
                            details: errors["ErrorDetails"].BUFFER_NUDGE_ON_STALL,
                            fatal: false
                        });
                    } else {
                        logger1["logger"].error("Playhead still not moving while enough data buffered @" + currentTime + " after " + config.nudgeMaxRetry + " nudges");
                        hls.trigger(events1["default"].ERROR, {
                            type: errors["ErrorTypes"].MEDIA_ERROR,
                            details: errors["ErrorDetails"].BUFFER_STALLED_ERROR,
                            fatal: true
                        });
                    }
                };
                return GapController;
            }();
            // CONCATENATED MODULE: ./src/task-loop.ts
            function _assertThisInitialized(self) {
                if (self === void 0) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
                return self;
            }
            function task_loop_inheritsLoose(subClass, superClass) {
                subClass.prototype = Object.create(superClass.prototype);
                subClass.prototype.constructor = subClass;
                subClass.__proto__ = superClass;
            }
            /**
 * Sub-class specialization of EventHandler base class.
 *
 * TaskLoop allows to schedule a task function being called (optionnaly repeatedly) on the main loop,
 * scheduled asynchroneously, avoiding recursive calls in the same tick.
 *
 * The task itself is implemented in `doTick`. It can be requested and called for single execution
 * using the `tick` method.
 *
 * It will be assured that the task execution method (`tick`) only gets called once per main loop "tick",
 * no matter how often it gets requested for execution. Execution in further ticks will be scheduled accordingly.
 *
 * If further execution requests have already been scheduled on the next tick, it can be checked with `hasNextTick`,
 * and cancelled with `clearNextTick`.
 *
 * The task can be scheduled as an interval repeatedly with a period as parameter (see `setInterval`, `clearInterval`).
 *
 * Sub-classes need to implement the `doTick` method which will effectively have the task execution routine.
 *
 * Further explanations:
 *
 * The baseclass has a `tick` method that will schedule the doTick call. It may be called synchroneously
 * only for a stack-depth of one. On re-entrant calls, sub-sequent calls are scheduled for next main loop ticks.
 *
 * When the task execution (`tick` method) is called in re-entrant way this is detected and
 * we are limiting the task execution per call stack to exactly one, but scheduling/post-poning further
 * task processing on the next main loop iteration (also known as "next tick" in the Node/JS runtime lingo).
 */ var TaskLoop1 = /*#__PURE__*/ function(_EventHandler) {
                task_loop_inheritsLoose(TaskLoop, _EventHandler);
                function TaskLoop(hls) {
                    var _this;
                    for(var _len = arguments.length, events = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++)events[_key - 1] = arguments[_key];
                    _this = _EventHandler.call.apply(_EventHandler, [
                        this,
                        hls
                    ].concat(events)) || this;
                    _this._boundTick = void 0;
                    _this._tickTimer = null;
                    _this._tickInterval = null;
                    _this._tickCallCount = 0;
                    _this._boundTick = _this.tick.bind(_assertThisInitialized(_this));
                    return _this;
                }
                /**
   * @override
   */ var _proto = TaskLoop.prototype;
                _proto.onHandlerDestroying = function onHandlerDestroying() {
                    // clear all timers before unregistering from event bus
                    this.clearNextTick();
                    this.clearInterval();
                };
                _proto.hasInterval = function hasInterval() {
                    return !!this._tickInterval;
                };
                _proto.hasNextTick = function hasNextTick() {
                    return !!this._tickTimer;
                };
                _proto.setInterval = function setInterval(millis) {
                    if (!this._tickInterval) {
                        this._tickInterval = self.setInterval(this._boundTick, millis);
                        return true;
                    }
                    return false;
                };
                _proto.clearInterval = function clearInterval() {
                    if (this._tickInterval) {
                        self.clearInterval(this._tickInterval);
                        this._tickInterval = null;
                        return true;
                    }
                    return false;
                };
                _proto.clearNextTick = function clearNextTick() {
                    if (this._tickTimer) {
                        self.clearTimeout(this._tickTimer);
                        this._tickTimer = null;
                        return true;
                    }
                    return false;
                };
                _proto.tick = function tick() {
                    this._tickCallCount++;
                    if (this._tickCallCount === 1) {
                        this.doTick(); // re-entrant call to tick from previous doTick call stack
                        // -> schedule a call on the next main loop iteration to process this task processing request
                        if (this._tickCallCount > 1) {
                            // make sure only one timer exists at any time at max
                            this.clearNextTick();
                            this._tickTimer = self.setTimeout(this._boundTick, 0);
                        }
                        this._tickCallCount = 0;
                    }
                };
                _proto.doTick = function doTick() {
                };
                return TaskLoop;
            }(event_handler);
            // CONCATENATED MODULE: ./src/controller/base-stream-controller.js
            function base_stream_controller_inheritsLoose(subClass, superClass) {
                subClass.prototype = Object.create(superClass.prototype);
                subClass.prototype.constructor = subClass;
                subClass.__proto__ = superClass;
            }
            var State = {
                STOPPED: 'STOPPED',
                STARTING: 'STARTING',
                IDLE: 'IDLE',
                PAUSED: 'PAUSED',
                KEY_LOADING: 'KEY_LOADING',
                FRAG_LOADING: 'FRAG_LOADING',
                FRAG_LOADING_WAITING_RETRY: 'FRAG_LOADING_WAITING_RETRY',
                WAITING_TRACK: 'WAITING_TRACK',
                PARSING: 'PARSING',
                PARSED: 'PARSED',
                BUFFER_FLUSHING: 'BUFFER_FLUSHING',
                ENDED: 'ENDED',
                ERROR: 'ERROR',
                WAITING_INIT_PTS: 'WAITING_INIT_PTS',
                WAITING_LEVEL: 'WAITING_LEVEL'
            };
            var base_stream_controller_BaseStreamController = /*#__PURE__*/ function(_TaskLoop) {
                base_stream_controller_inheritsLoose(BaseStreamController, _TaskLoop);
                function BaseStreamController() {
                    return _TaskLoop.apply(this, arguments) || this;
                }
                var _proto = BaseStreamController.prototype;
                _proto.doTick = function doTick() {
                };
                _proto.startLoad = function startLoad() {
                };
                _proto.stopLoad = function stopLoad() {
                    var frag = this.fragCurrent;
                    if (frag) {
                        if (frag.loader) frag.loader.abort();
                        this.fragmentTracker.removeFragment(frag);
                    }
                    if (this.demuxer) {
                        this.demuxer.destroy();
                        this.demuxer = null;
                    }
                    this.fragCurrent = null;
                    this.fragPrevious = null;
                    this.clearInterval();
                    this.clearNextTick();
                    this.state = State.STOPPED;
                };
                _proto._streamEnded = function _streamEnded(bufferInfo, levelDetails) {
                    var fragCurrent = this.fragCurrent, fragmentTracker = this.fragmentTracker; // we just got done loading the final fragment and there is no other buffered range after ...
                    // rationale is that in case there are any buffered ranges after, it means that there are unbuffered portion in between
                    // so we should not switch to ENDED in that case, to be able to buffer them
                    // dont switch to ENDED if we need to backtrack last fragment
                    if (!levelDetails.live && fragCurrent && !fragCurrent.backtracked && fragCurrent.sn === levelDetails.endSN && !bufferInfo.nextStart) {
                        var fragState = fragmentTracker.getState(fragCurrent);
                        return fragState === FragmentState.PARTIAL || fragState === FragmentState.OK;
                    }
                    return false;
                };
                _proto.onMediaSeeking = function onMediaSeeking() {
                    var config = this.config, media = this.media, mediaBuffer = this.mediaBuffer, state = this.state;
                    var currentTime = media ? media.currentTime : null;
                    var bufferInfo = BufferHelper1.bufferInfo(mediaBuffer || media, currentTime, this.config.maxBufferHole);
                    logger1["logger"].log("media seeking to " + (Object(number["isFiniteNumber"])(currentTime) ? currentTime.toFixed(3) : currentTime));
                    if (state === State.FRAG_LOADING) {
                        var fragCurrent = this.fragCurrent; // check if we are seeking to a unbuffered area AND if frag loading is in progress
                        if (bufferInfo.len === 0 && fragCurrent) {
                            var tolerance = config.maxFragLookUpTolerance;
                            var fragStartOffset = fragCurrent.start - tolerance;
                            var fragEndOffset = fragCurrent.start + fragCurrent.duration + tolerance; // check if we seek position will be out of currently loaded frag range : if out cancel frag load, if in, don't do anything
                            if (currentTime < fragStartOffset || currentTime > fragEndOffset) {
                                if (fragCurrent.loader) {
                                    logger1["logger"].log('seeking outside of buffer while fragment load in progress, cancel fragment load');
                                    fragCurrent.loader.abort();
                                }
                                this.fragCurrent = null;
                                this.fragPrevious = null; // switch to IDLE state to load new fragment
                                this.state = State.IDLE;
                            } else logger1["logger"].log('seeking outside of buffer but within currently loaded fragment range');
                        }
                    } else if (state === State.ENDED) {
                        // if seeking to unbuffered area, clean up fragPrevious
                        if (bufferInfo.len === 0) {
                            this.fragPrevious = null;
                            this.fragCurrent = null;
                        } // switch to IDLE state to check for potential new fragment
                        this.state = State.IDLE;
                    }
                    if (media) this.lastCurrentTime = currentTime;
                     // in case seeking occurs although no media buffered, adjust startPosition and nextLoadPosition to seek target
                    if (!this.loadedmetadata) this.nextLoadPosition = this.startPosition = currentTime;
                     // tick to speed up processing
                    this.tick();
                };
                _proto.onMediaEnded = function onMediaEnded() {
                    // reset startPosition and lastCurrentTime to restart playback @ stream beginning
                    this.startPosition = this.lastCurrentTime = 0;
                };
                _proto.onHandlerDestroying = function onHandlerDestroying() {
                    this.stopLoad();
                    _TaskLoop.prototype.onHandlerDestroying.call(this);
                };
                _proto.onHandlerDestroyed = function onHandlerDestroyed() {
                    this.state = State.STOPPED;
                    this.fragmentTracker = null;
                };
                _proto.computeLivePosition = function computeLivePosition(sliding, levelDetails) {
                    var targetLatency = this.config.liveSyncDuration !== undefined ? this.config.liveSyncDuration : this.config.liveSyncDurationCount * levelDetails.targetduration;
                    return sliding + Math.max(0, levelDetails.totalduration - targetLatency);
                };
                return BaseStreamController;
            }(TaskLoop1);
            // CONCATENATED MODULE: ./src/controller/stream-controller.js
            function stream_controller_defineProperties(target, props) {
                for(var i = 0; i < props.length; i++){
                    var descriptor = props[i];
                    descriptor.enumerable = descriptor.enumerable || false;
                    descriptor.configurable = true;
                    if ("value" in descriptor) descriptor.writable = true;
                    Object.defineProperty(target, descriptor.key, descriptor);
                }
            }
            function stream_controller_createClass(Constructor, protoProps, staticProps) {
                if (protoProps) stream_controller_defineProperties(Constructor.prototype, protoProps);
                if (staticProps) stream_controller_defineProperties(Constructor, staticProps);
                return Constructor;
            }
            function stream_controller_inheritsLoose(subClass, superClass) {
                subClass.prototype = Object.create(superClass.prototype);
                subClass.prototype.constructor = subClass;
                subClass.__proto__ = superClass;
            }
            /*
 * Stream Controller
*/ var TICK_INTERVAL = 100; // how often to tick in ms
            var stream_controller_StreamController = /*#__PURE__*/ function(_BaseStreamController) {
                stream_controller_inheritsLoose(StreamController, _BaseStreamController);
                function StreamController(hls, fragmentTracker) {
                    var _this;
                    _this = _BaseStreamController.call(this, hls, events1["default"].MEDIA_ATTACHED, events1["default"].MEDIA_DETACHING, events1["default"].MANIFEST_LOADING, events1["default"].MANIFEST_PARSED, events1["default"].LEVEL_LOADED, events1["default"].LEVELS_UPDATED, events1["default"].KEY_LOADED, events1["default"].FRAG_LOADED, events1["default"].FRAG_LOAD_EMERGENCY_ABORTED, events1["default"].FRAG_PARSING_INIT_SEGMENT, events1["default"].FRAG_PARSING_DATA, events1["default"].FRAG_PARSED, events1["default"].ERROR, events1["default"].AUDIO_TRACK_SWITCHING, events1["default"].AUDIO_TRACK_SWITCHED, events1["default"].BUFFER_CREATED, events1["default"].BUFFER_APPENDED, events1["default"].BUFFER_FLUSHED) || this;
                    _this.fragmentTracker = fragmentTracker;
                    _this.config = hls.config;
                    _this.audioCodecSwap = false;
                    _this._state = State.STOPPED;
                    _this.stallReported = false;
                    _this.gapController = null;
                    _this.altAudio = false;
                    _this.audioOnly = false;
                    _this.bitrateTest = false;
                    return _this;
                }
                var _proto = StreamController.prototype;
                _proto.startLoad = function startLoad(startPosition) {
                    if (this.levels) {
                        var lastCurrentTime = this.lastCurrentTime, hls = this.hls;
                        this.stopLoad();
                        this.setInterval(TICK_INTERVAL);
                        this.level = -1;
                        this.fragLoadError = 0;
                        if (!this.startFragRequested) {
                            // determine load level
                            var startLevel = hls.startLevel;
                            if (startLevel === -1) {
                                if (hls.config.testBandwidth) {
                                    // -1 : guess start Level by doing a bitrate test by loading first fragment of lowest quality level
                                    startLevel = 0;
                                    this.bitrateTest = true;
                                } else startLevel = hls.nextAutoLevel;
                            } // set new level to playlist loader : this will trigger start level load
                            // hls.nextLoadLevel remains until it is set to a new value or until a new frag is successfully loaded
                            this.level = hls.nextLoadLevel = startLevel;
                            this.loadedmetadata = false;
                        } // if startPosition undefined but lastCurrentTime set, set startPosition to last currentTime
                        if (lastCurrentTime > 0 && startPosition === -1) {
                            logger1["logger"].log("override startPosition with lastCurrentTime @" + lastCurrentTime.toFixed(3));
                            startPosition = lastCurrentTime;
                        }
                        this.state = State.IDLE;
                        this.nextLoadPosition = this.startPosition = this.lastCurrentTime = startPosition;
                        this.tick();
                    } else {
                        this.forceStartLoad = true;
                        this.state = State.STOPPED;
                    }
                };
                _proto.stopLoad = function stopLoad() {
                    this.forceStartLoad = false;
                    _BaseStreamController.prototype.stopLoad.call(this);
                };
                _proto.doTick = function doTick() {
                    switch(this.state){
                        case State.BUFFER_FLUSHING:
                            // in buffer flushing state, reset fragLoadError counter
                            this.fragLoadError = 0;
                            break;
                        case State.IDLE:
                            this._doTickIdle();
                            break;
                        case State.WAITING_LEVEL:
                            var level = this.levels[this.level]; // check if playlist is already loaded
                            if (level && level.details) this.state = State.IDLE;
                            break;
                        case State.FRAG_LOADING_WAITING_RETRY:
                            var now = window.performance.now();
                            var retryDate = this.retryDate; // if current time is gt than retryDate, or if media seeking let's switch to IDLE state to retry loading
                            if (!retryDate || now >= retryDate || this.media && this.media.seeking) {
                                logger1["logger"].log('mediaController: retryDate reached, switch back to IDLE state');
                                this.state = State.IDLE;
                            }
                            break;
                        case State.ERROR:
                        case State.STOPPED:
                        case State.FRAG_LOADING:
                        case State.PARSING:
                        case State.PARSED:
                        case State.ENDED:
                            break;
                        default:
                            break;
                    } // check buffer
                    this._checkBuffer(); // check/update current fragment
                    this._checkFragmentChanged();
                } // Ironically the "idle" state is the on we do the most logic in it seems ....
                ;
                _proto._doTickIdle = function _doTickIdle() {
                    var hls = this.hls, config = hls.config, media = this.media; // if start level not parsed yet OR
                    // if video not attached AND start fragment already requested OR start frag prefetch disable
                    // exit loop, as we either need more info (level not parsed) or we need media to be attached to load new fragment
                    if (this.levelLastLoaded === undefined || !media && (this.startFragRequested || !config.startFragPrefetch)) return;
                     // If the "main" level is audio-only but we are loading an alternate track in the same group, do not load anything
                    if (this.altAudio && this.audioOnly) {
                        // Clear audio demuxer state so when switching back to main audio we're not still appending where we left off
                        this.demuxer.frag = null;
                        return;
                    } // if we have not yet loaded any fragment, start loading from start position
                    var pos;
                    if (this.loadedmetadata) pos = media.currentTime;
                    else pos = this.nextLoadPosition;
                     // determine next load level
                    var level = hls.nextLoadLevel, levelInfo = this.levels[level];
                    if (!levelInfo) return;
                    var levelBitrate = levelInfo.bitrate, maxBufLen; // compute max Buffer Length that we could get from this load level, based on level bitrate.
                    if (levelBitrate) maxBufLen = Math.max(8 * config.maxBufferSize / levelBitrate, config.maxBufferLength);
                    else maxBufLen = config.maxBufferLength;
                    maxBufLen = Math.min(maxBufLen, config.maxMaxBufferLength); // determine next candidate fragment to be loaded, based on current position and end of buffer position
                    // ensure up to `config.maxMaxBufferLength` of buffer upfront
                    var maxBufferHole = pos < config.maxBufferHole ? Math.max(MAX_START_GAP_JUMP, config.maxBufferHole) : config.maxBufferHole;
                    var bufferInfo = BufferHelper1.bufferInfo(this.mediaBuffer ? this.mediaBuffer : media, pos, maxBufferHole);
                    var bufferLen = bufferInfo.len; // Stay idle if we are still with buffer margins
                    if (bufferLen >= maxBufLen) return;
                     // if buffer length is less than maxBufLen try to load a new fragment ...
                    logger1["logger"].trace("buffer length of " + bufferLen.toFixed(3) + " is below max of " + maxBufLen.toFixed(3) + ". checking for more payload ..."); // set next load level : this will trigger a playlist load if needed
                    this.level = hls.nextLoadLevel = level;
                    var levelDetails = levelInfo.details; // if level info not retrieved yet, switch state and wait for level retrieval
                    // if live playlist, ensure that new playlist has been refreshed to avoid loading/try to load
                    // a useless and outdated fragment (that might even introduce load error if it is already out of the live playlist)
                    if (!levelDetails || levelDetails.live && this.levelLastLoaded !== level) {
                        this.state = State.WAITING_LEVEL;
                        return;
                    }
                    if (this._streamEnded(bufferInfo, levelDetails)) {
                        var data = {
                        };
                        if (this.altAudio) data.type = 'video';
                        this.hls.trigger(events1["default"].BUFFER_EOS, data);
                        this.state = State.ENDED;
                        return;
                    } // if we have the levelDetails for the selected variant, lets continue enrichen our stream (load keys/fragments or trigger EOS, etc..)
                    this._fetchPayloadOrEos(pos, bufferInfo, levelDetails);
                };
                _proto._fetchPayloadOrEos = function _fetchPayloadOrEos(pos, bufferInfo, levelDetails) {
                    var fragPrevious = this.fragPrevious, level = this.level, fragments = levelDetails.fragments, fragLen = fragments.length; // empty playlist
                    if (fragLen === 0) return;
                     // find fragment index, contiguous with end of buffer position
                    var start = fragments[0].start, end = fragments[fragLen - 1].start + fragments[fragLen - 1].duration, bufferEnd = bufferInfo.end, frag;
                    if (levelDetails.initSegment && !levelDetails.initSegment.data) frag = levelDetails.initSegment;
                    else {
                        // in case of live playlist we need to ensure that requested position is not located before playlist start
                        if (levelDetails.live) {
                            var initialLiveManifestSize = this.config.initialLiveManifestSize;
                            if (fragLen < initialLiveManifestSize) {
                                logger1["logger"].warn("Can not start playback of a level, reason: not enough fragments " + fragLen + " < " + initialLiveManifestSize);
                                return;
                            }
                            frag = this._ensureFragmentAtLivePoint(levelDetails, bufferEnd, start, end, fragPrevious, fragments); // if it explicitely returns null don't load any fragment and exit function now
                            if (frag === null) return;
                        } else // VoD playlist: if bufferEnd before start of playlist, load first fragment
                        if (bufferEnd < start) frag = fragments[0];
                    }
                    if (!frag) frag = this._findFragment(start, fragPrevious, fragLen, fragments, bufferEnd, end, levelDetails);
                    if (frag) {
                        if (frag.encrypted) this._loadKey(frag, levelDetails);
                        else this._loadFragment(frag, levelDetails, pos, bufferEnd);
                    }
                };
                _proto._ensureFragmentAtLivePoint = function _ensureFragmentAtLivePoint(levelDetails, bufferEnd, start, end, fragPrevious, fragments) {
                    var config = this.hls.config, media = this.media;
                    var frag2; // check if requested position is within seekable boundaries :
                    // logger.log(`start/pos/bufEnd/seeking:${start.toFixed(3)}/${pos.toFixed(3)}/${bufferEnd.toFixed(3)}/${this.media.seeking}`);
                    var maxLatency = Infinity;
                    if (config.liveMaxLatencyDuration !== undefined) maxLatency = config.liveMaxLatencyDuration;
                    else if (Object(number["isFiniteNumber"])(config.liveMaxLatencyDurationCount)) maxLatency = config.liveMaxLatencyDurationCount * levelDetails.targetduration;
                    if (bufferEnd < Math.max(start - config.maxFragLookUpTolerance, end - maxLatency)) {
                        var liveSyncPosition = this.liveSyncPosition = this.computeLivePosition(start, levelDetails);
                        bufferEnd = liveSyncPosition;
                        if (media && !media.paused && media.readyState && media.duration > liveSyncPosition && liveSyncPosition > media.currentTime) {
                            logger1["logger"].log("buffer end: " + bufferEnd.toFixed(3) + " is located too far from the end of live sliding playlist, reset currentTime to : " + liveSyncPosition.toFixed(3));
                            media.currentTime = liveSyncPosition;
                        }
                        this.nextLoadPosition = liveSyncPosition;
                    } // if end of buffer greater than live edge, don't load any fragment
                    // this could happen if live playlist intermittently slides in the past.
                    // level 1 loaded [182580161,182580167]
                    // level 1 loaded [182580162,182580169]
                    // Loading 182580168 of [182580162 ,182580169],level 1 ..
                    // Loading 182580169 of [182580162 ,182580169],level 1 ..
                    // level 1 loaded [182580162,182580168] <============= here we should have bufferEnd > end. in that case break to avoid reloading 182580168
                    // level 1 loaded [182580164,182580171]
                    //
                    // don't return null in case media not loaded yet (readystate === 0)
                    if (levelDetails.PTSKnown && bufferEnd > end && media && media.readyState) return null;
                    if (this.startFragRequested && !levelDetails.PTSKnown) /* we are switching level on live playlist, but we don't have any PTS info for that quality level ...
         try to load frag matching with next SN.
         even if SN are not synchronized between playlists, loading this frag will help us
         compute playlist sliding and find the right one after in case it was not the right consecutive one */ {
                        if (fragPrevious) {
                            if (levelDetails.hasProgramDateTime) {
                                // Relies on PDT in order to switch bitrates (Support EXT-X-DISCONTINUITY without EXT-X-DISCONTINUITY-SEQUENCE)
                                logger1["logger"].log("live playlist, switching playlist, load frag with same PDT: " + fragPrevious.programDateTime);
                                frag2 = findFragmentByPDT(fragments, fragPrevious.endProgramDateTime, config.maxFragLookUpTolerance);
                            } else {
                                // Uses buffer and sequence number to calculate switch segment (required if using EXT-X-DISCONTINUITY-SEQUENCE)
                                var targetSN = fragPrevious.sn + 1;
                                if (targetSN >= levelDetails.startSN && targetSN <= levelDetails.endSN) {
                                    var fragNext = fragments[targetSN - levelDetails.startSN];
                                    if (fragPrevious.cc === fragNext.cc) {
                                        frag2 = fragNext;
                                        logger1["logger"].log("live playlist, switching playlist, load frag with next SN: " + frag2.sn);
                                    }
                                } // next frag SN not available (or not with same continuity counter)
                                // look for a frag sharing the same CC
                                if (!frag2) {
                                    frag2 = binary_search.search(fragments, function(frag) {
                                        return fragPrevious.cc - frag.cc;
                                    });
                                    if (frag2) logger1["logger"].log("live playlist, switching playlist, load frag with same CC: " + frag2.sn);
                                }
                            }
                        }
                    }
                    return frag2;
                };
                _proto._findFragment = function _findFragment(start, fragPreviousLoad, fragmentIndexRange, fragments, bufferEnd, end, levelDetails) {
                    var config = this.hls.config;
                    var fragNextLoad;
                    if (bufferEnd < end) {
                        var lookupTolerance = bufferEnd > end - config.maxFragLookUpTolerance ? 0 : config.maxFragLookUpTolerance; // Remove the tolerance if it would put the bufferEnd past the actual end of stream
                        // Uses buffer and sequence number to calculate switch segment (required if using EXT-X-DISCONTINUITY-SEQUENCE)
                        fragNextLoad = findFragmentByPTS(fragPreviousLoad, fragments, bufferEnd, lookupTolerance);
                    } else // reach end of playlist
                    fragNextLoad = fragments[fragmentIndexRange - 1];
                    if (fragNextLoad) {
                        var curSNIdx = fragNextLoad.sn - levelDetails.startSN;
                        var sameLevel = fragPreviousLoad && fragNextLoad.level === fragPreviousLoad.level;
                        var prevSnFrag = fragments[curSNIdx - 1];
                        var nextSnFrag = fragments[curSNIdx + 1]; // logger.log('find SN matching with pos:' +  bufferEnd + ':' + frag.sn);
                        if (fragPreviousLoad && fragNextLoad.sn === fragPreviousLoad.sn) {
                            if (sameLevel && !fragNextLoad.backtracked) {
                                if (fragNextLoad.sn < levelDetails.endSN) {
                                    var deltaPTS = fragPreviousLoad.deltaPTS; // if there is a significant delta between audio and video, larger than max allowed hole,
                                    // and if previous remuxed fragment did not start with a keyframe. (fragPrevious.dropped)
                                    // let's try to load previous fragment again to get last keyframe
                                    // then we will reload again current fragment (that way we should be able to fill the buffer hole ...)
                                    if (deltaPTS && deltaPTS > config.maxBufferHole && fragPreviousLoad.dropped && curSNIdx) {
                                        fragNextLoad = prevSnFrag;
                                        logger1["logger"].warn('Previous fragment was dropped with large PTS gap between audio and video. Maybe fragment is not starting with a keyframe? Loading previous one to try to overcome this');
                                    } else {
                                        fragNextLoad = nextSnFrag;
                                        if (this.fragmentTracker.getState(fragNextLoad) !== FragmentState.OK) logger1["logger"].log("Re-loading fragment with SN: " + fragNextLoad.sn);
                                    }
                                } else fragNextLoad = null;
                            } else if (fragNextLoad.backtracked) {
                                // Only backtrack a max of 1 consecutive fragment to prevent sliding back too far when little or no frags start with keyframes
                                if (nextSnFrag && nextSnFrag.backtracked) {
                                    logger1["logger"].warn("Already backtracked from fragment " + nextSnFrag.sn + ", will not backtrack to fragment " + fragNextLoad.sn + ". Loading fragment " + nextSnFrag.sn);
                                    fragNextLoad = nextSnFrag;
                                } else {
                                    // If a fragment has dropped frames and it's in a same level/sequence, load the previous fragment to try and find the keyframe
                                    // Reset the dropped count now since it won't be reset until we parse the fragment again, which prevents infinite backtracking on the same segment
                                    logger1["logger"].warn('Loaded fragment with dropped frames, backtracking 1 segment to find a keyframe');
                                    fragNextLoad.dropped = 0;
                                    if (prevSnFrag) {
                                        fragNextLoad = prevSnFrag;
                                        fragNextLoad.backtracked = true;
                                    } else if (curSNIdx) // can't backtrack on very first fragment
                                    fragNextLoad = null;
                                }
                            }
                        }
                    }
                    return fragNextLoad;
                };
                _proto._loadKey = function _loadKey(frag, levelDetails) {
                    logger1["logger"].log("Loading key for " + frag.sn + " of [" + levelDetails.startSN + "-" + levelDetails.endSN + "], level " + this.level);
                    this.state = State.KEY_LOADING;
                    this.hls.trigger(events1["default"].KEY_LOADING, {
                        frag: frag
                    });
                };
                _proto._loadFragment = function _loadFragment(frag, levelDetails, pos, bufferEnd) {
                    // Check if fragment is not loaded
                    var fragState = this.fragmentTracker.getState(frag);
                    this.fragCurrent = frag;
                    if (frag.sn !== 'initSegment') this.startFragRequested = true;
                     // Don't update nextLoadPosition for fragments which are not buffered
                    if (Object(number["isFiniteNumber"])(frag.sn) && !frag.bitrateTest) this.nextLoadPosition = frag.start + frag.duration;
                     // Allow backtracked fragments to load
                    if (frag.backtracked || fragState === FragmentState.NOT_LOADED || fragState === FragmentState.PARTIAL) {
                        frag.autoLevel = this.hls.autoLevelEnabled;
                        frag.bitrateTest = this.bitrateTest;
                        logger1["logger"].log("Loading " + frag.sn + " of [" + levelDetails.startSN + "-" + levelDetails.endSN + "], level " + this.level + ", " + (this.loadedmetadata ? 'currentTime' : 'nextLoadPosition') + ": " + parseFloat(pos.toFixed(3)) + ", bufferEnd: " + parseFloat(bufferEnd.toFixed(3)));
                        this.hls.trigger(events1["default"].FRAG_LOADING, {
                            frag: frag
                        }); // lazy demuxer init, as this could take some time ... do it during frag loading
                        if (!this.demuxer) this.demuxer = new demux_demuxer(this.hls, 'main');
                        this.state = State.FRAG_LOADING;
                    } else if (fragState === FragmentState.APPENDING) // Lower the buffer size and try again
                    {
                        if (this._reduceMaxBufferLength(frag.duration)) this.fragmentTracker.removeFragment(frag);
                    }
                };
                _proto.getBufferedFrag = function getBufferedFrag(position) {
                    return this.fragmentTracker.getBufferedFrag(position, PlaylistLevelType1.MAIN);
                };
                _proto.followingBufferedFrag = function followingBufferedFrag(frag) {
                    if (frag) // try to get range of next fragment (500ms after this range)
                    return this.getBufferedFrag(frag.endPTS + 0.5);
                    return null;
                };
                _proto._checkFragmentChanged = function _checkFragmentChanged() {
                    var fragPlayingCurrent, currentTime, video = this.media;
                    if (video && video.readyState && video.seeking === false) {
                        currentTime = video.currentTime;
                        /* if video element is in seeked state, currentTime can only increase.
        (assuming that playback rate is positive ...)
        As sometimes currentTime jumps back to zero after a
        media decode error, check this, to avoid seeking back to
        wrong position after a media decode error
      */ if (currentTime > this.lastCurrentTime) this.lastCurrentTime = currentTime;
                        if (BufferHelper1.isBuffered(video, currentTime)) fragPlayingCurrent = this.getBufferedFrag(currentTime);
                        else if (BufferHelper1.isBuffered(video, currentTime + 0.1)) /* ensure that FRAG_CHANGED event is triggered at startup,
          when first video frame is displayed and playback is paused.
          add a tolerance of 100ms, in case current position is not buffered,
          check if current pos+100ms is buffered and use that buffer range
          for FRAG_CHANGED event reporting */ fragPlayingCurrent = this.getBufferedFrag(currentTime + 0.1);
                        if (fragPlayingCurrent) {
                            var fragPlaying = fragPlayingCurrent;
                            if (fragPlaying !== this.fragPlaying) {
                                this.hls.trigger(events1["default"].FRAG_CHANGED, {
                                    frag: fragPlaying
                                });
                                var fragPlayingLevel = fragPlaying.level;
                                if (!this.fragPlaying || this.fragPlaying.level !== fragPlayingLevel) this.hls.trigger(events1["default"].LEVEL_SWITCHED, {
                                    level: fragPlayingLevel
                                });
                                this.fragPlaying = fragPlaying;
                            }
                        }
                    }
                };
                _proto.immediateLevelSwitch = function immediateLevelSwitch() {
                    logger1["logger"].log('immediateLevelSwitch');
                    if (!this.immediateSwitch) {
                        this.immediateSwitch = true;
                        var media = this.media, previouslyPaused;
                        if (media) {
                            previouslyPaused = media.paused;
                            if (!previouslyPaused) media.pause();
                        } else // don't restart playback after instant level switch in case media not attached
                        previouslyPaused = true;
                        this.previouslyPaused = previouslyPaused;
                    }
                    var fragCurrent = this.fragCurrent;
                    if (fragCurrent && fragCurrent.loader) fragCurrent.loader.abort();
                    this.fragCurrent = null; // flush everything
                    this.flushMainBuffer(0, Number.POSITIVE_INFINITY);
                };
                _proto.immediateLevelSwitchEnd = function immediateLevelSwitchEnd() {
                    var media = this.media;
                    if (media && media.buffered.length) {
                        this.immediateSwitch = false;
                        if (media.currentTime > 0 && BufferHelper1.isBuffered(media, media.currentTime)) // only nudge if currentTime is buffered
                        media.currentTime -= 0.0001;
                        if (!this.previouslyPaused) media.play();
                    }
                };
                _proto.nextLevelSwitch = function nextLevelSwitch() {
                    var media = this.media; // ensure that media is defined and that metadata are available (to retrieve currentTime)
                    if (media && media.readyState) {
                        var fetchdelay;
                        var fragPlayingCurrent = this.getBufferedFrag(media.currentTime);
                        if (fragPlayingCurrent && fragPlayingCurrent.startPTS > 1) // flush buffer preceding current fragment (flush until current fragment start offset)
                        // minus 1s to avoid video freezing, that could happen if we flush keyframe of current video ...
                        this.flushMainBuffer(0, fragPlayingCurrent.startPTS - 1);
                        if (!media.paused) {
                            // add a safety delay of 1s
                            var nextLevelId = this.hls.nextLoadLevel, nextLevel = this.levels[nextLevelId], fragLastKbps = this.fragLastKbps;
                            if (fragLastKbps && this.fragCurrent) fetchdelay = this.fragCurrent.duration * nextLevel.bitrate / (1000 * fragLastKbps) + 1;
                            else fetchdelay = 0;
                        } else fetchdelay = 0;
                         // logger.log('fetchdelay:'+fetchdelay);
                        // find buffer range that will be reached once new fragment will be fetched
                        var bufferedFrag = this.getBufferedFrag(media.currentTime + fetchdelay);
                        if (bufferedFrag) {
                            // we can flush buffer range following this one without stalling playback
                            var nextBufferedFrag = this.followingBufferedFrag(bufferedFrag);
                            if (nextBufferedFrag) {
                                // if we are here, we can also cancel any loading/demuxing in progress, as they are useless
                                var fragCurrent = this.fragCurrent;
                                if (fragCurrent && fragCurrent.loader) fragCurrent.loader.abort();
                                this.fragCurrent = null; // start flush position is the start PTS of next buffered frag.
                                // we use frag.naxStartPTS which is max(audio startPTS, video startPTS).
                                // in case there is a small PTS Delta between audio and video, using maxStartPTS avoids flushing last samples from current fragment
                                var startPts = Math.max(bufferedFrag.endPTS, nextBufferedFrag.maxStartPTS + Math.min(this.config.maxFragLookUpTolerance, nextBufferedFrag.duration));
                                this.flushMainBuffer(startPts, Number.POSITIVE_INFINITY);
                            }
                        }
                    }
                };
                _proto.flushMainBuffer = function flushMainBuffer(startOffset, endOffset) {
                    this.state = State.BUFFER_FLUSHING;
                    var flushScope = {
                        startOffset: startOffset,
                        endOffset: endOffset
                    }; // if alternate audio tracks are used, only flush video, otherwise flush everything
                    if (this.altAudio) flushScope.type = 'video';
                    this.hls.trigger(events1["default"].BUFFER_FLUSHING, flushScope);
                };
                _proto.onMediaAttached = function onMediaAttached(data) {
                    var media = this.media = this.mediaBuffer = data.media;
                    this.onvseeking = this.onMediaSeeking.bind(this);
                    this.onvseeked = this.onMediaSeeked.bind(this);
                    this.onvended = this.onMediaEnded.bind(this);
                    media.addEventListener('seeking', this.onvseeking);
                    media.addEventListener('seeked', this.onvseeked);
                    media.addEventListener('ended', this.onvended);
                    var config = this.config;
                    if (this.levels && config.autoStartLoad) this.hls.startLoad(config.startPosition);
                    this.gapController = new gap_controller_GapController(config, media, this.fragmentTracker, this.hls);
                };
                _proto.onMediaDetaching = function onMediaDetaching() {
                    var media = this.media;
                    if (media && media.ended) {
                        logger1["logger"].log('MSE detaching and video ended, reset startPosition');
                        this.startPosition = this.lastCurrentTime = 0;
                    } // reset fragment backtracked flag
                    var levels = this.levels;
                    if (levels) levels.forEach(function(level) {
                        if (level.details) level.details.fragments.forEach(function(fragment) {
                            fragment.backtracked = undefined;
                        });
                    });
                     // remove video listeners
                    if (media) {
                        media.removeEventListener('seeking', this.onvseeking);
                        media.removeEventListener('seeked', this.onvseeked);
                        media.removeEventListener('ended', this.onvended);
                        this.onvseeking = this.onvseeked = this.onvended = null;
                    }
                    this.fragmentTracker.removeAllFragments();
                    this.media = this.mediaBuffer = null;
                    this.loadedmetadata = false;
                    this.stopLoad();
                };
                _proto.onMediaSeeked = function onMediaSeeked() {
                    var media = this.media;
                    var currentTime = media ? media.currentTime : undefined;
                    if (Object(number["isFiniteNumber"])(currentTime)) logger1["logger"].log("media seeked to " + currentTime.toFixed(3));
                     // tick to speed up FRAGMENT_PLAYING triggering
                    this.tick();
                };
                _proto.onManifestLoading = function onManifestLoading() {
                    // reset buffer on manifest loading
                    logger1["logger"].log('trigger BUFFER_RESET');
                    this.hls.trigger(events1["default"].BUFFER_RESET);
                    this.fragmentTracker.removeAllFragments();
                    this.stalled = false;
                    this.startPosition = this.lastCurrentTime = 0;
                };
                _proto.onManifestParsed = function onManifestParsed(data) {
                    var aac = false, heaac = false, codec;
                    data.levels.forEach(function(level) {
                        // detect if we have different kind of audio codecs used amongst playlists
                        codec = level.audioCodec;
                        if (codec) {
                            if (codec.indexOf('mp4a.40.2') !== -1) aac = true;
                            if (codec.indexOf('mp4a.40.5') !== -1) heaac = true;
                        }
                    });
                    this.audioCodecSwitch = aac && heaac;
                    if (this.audioCodecSwitch) logger1["logger"].log('both AAC/HE-AAC audio found in levels; declaring level codec as HE-AAC');
                    this.altAudio = data.altAudio;
                    this.levels = data.levels;
                    this.startFragRequested = false;
                    var config = this.config;
                    if (config.autoStartLoad || this.forceStartLoad) this.hls.startLoad(config.startPosition);
                };
                _proto.onLevelLoaded = function onLevelLoaded(data) {
                    var newDetails = data.details;
                    var newLevelId = data.level;
                    var lastLevel = this.levels[this.levelLastLoaded];
                    var curLevel = this.levels[newLevelId];
                    var duration = newDetails.totalduration;
                    var sliding = 0;
                    logger1["logger"].log("level " + newLevelId + " loaded [" + newDetails.startSN + "," + newDetails.endSN + "],duration:" + duration);
                    if (newDetails.live || curLevel.details && curLevel.details.live) {
                        var curDetails = curLevel.details;
                        if (curDetails && newDetails.fragments.length > 0) {
                            // we already have details for that level, merge them
                            mergeDetails(curDetails, newDetails);
                            sliding = newDetails.fragments[0].start;
                            this.liveSyncPosition = this.computeLivePosition(sliding, curDetails);
                            if (newDetails.PTSKnown && Object(number["isFiniteNumber"])(sliding)) logger1["logger"].log("live playlist sliding:" + sliding.toFixed(3));
                            else {
                                logger1["logger"].log('live playlist - outdated PTS, unknown sliding');
                                alignStream(this.fragPrevious, lastLevel, newDetails);
                            }
                        } else {
                            logger1["logger"].log('live playlist - first load, unknown sliding');
                            newDetails.PTSKnown = false;
                            alignStream(this.fragPrevious, lastLevel, newDetails);
                        }
                    } else newDetails.PTSKnown = false;
                     // override level info
                    curLevel.details = newDetails;
                    this.levelLastLoaded = newLevelId;
                    this.hls.trigger(events1["default"].LEVEL_UPDATED, {
                        details: newDetails,
                        level: newLevelId
                    });
                    if (this.startFragRequested === false) {
                        // compute start position if set to -1. use it straight away if value is defined
                        if (this.startPosition === -1 || this.lastCurrentTime === -1) {
                            // first, check if start time offset has been set in playlist, if yes, use this value
                            var startTimeOffset = newDetails.startTimeOffset;
                            if (Object(number["isFiniteNumber"])(startTimeOffset)) {
                                if (startTimeOffset < 0) {
                                    logger1["logger"].log("negative start time offset " + startTimeOffset + ", count from end of last fragment");
                                    startTimeOffset = sliding + duration + startTimeOffset;
                                }
                                logger1["logger"].log("start time offset found in playlist, adjust startPosition to " + startTimeOffset);
                                this.startPosition = startTimeOffset;
                            } else // if live playlist, set start position to be fragment N-this.config.liveSyncDurationCount (usually 3)
                            if (newDetails.live) {
                                this.startPosition = this.computeLivePosition(sliding, newDetails);
                                logger1["logger"].log("configure startPosition to " + this.startPosition);
                            } else this.startPosition = 0;
                            this.lastCurrentTime = this.startPosition;
                        }
                        this.nextLoadPosition = this.startPosition;
                    } // only switch batck to IDLE state if we were waiting for level to start downloading a new fragment
                    if (this.state === State.WAITING_LEVEL) this.state = State.IDLE;
                     // trigger handler right now
                    this.tick();
                };
                _proto.onKeyLoaded = function onKeyLoaded() {
                    if (this.state === State.KEY_LOADING) {
                        this.state = State.IDLE;
                        this.tick();
                    }
                };
                _proto.onFragLoaded = function onFragLoaded(data) {
                    var fragCurrent = this.fragCurrent, hls = this.hls, levels = this.levels, media = this.media;
                    var fragLoaded = data.frag;
                    if (this.state === State.FRAG_LOADING && fragCurrent && fragLoaded.type === 'main' && fragLoaded.level === fragCurrent.level && fragLoaded.sn === fragCurrent.sn) {
                        var stats = data.stats;
                        var currentLevel = levels[fragCurrent.level];
                        var details = currentLevel.details; // reset frag bitrate test in any case after frag loaded event
                        // if this frag was loaded to perform a bitrate test AND if hls.nextLoadLevel is greater than 0
                        // then this means that we should be able to load a fragment at a higher quality level
                        this.bitrateTest = false;
                        this.stats = stats;
                        logger1["logger"].log("Loaded " + fragCurrent.sn + " of [" + details.startSN + " ," + details.endSN + "],level " + fragCurrent.level);
                        if (fragLoaded.bitrateTest && hls.nextLoadLevel) {
                            // switch back to IDLE state ... we just loaded a fragment to determine adequate start bitrate and initialize autoswitch algo
                            this.state = State.IDLE;
                            this.startFragRequested = false;
                            stats.tparsed = stats.tbuffered = window.performance.now();
                            hls.trigger(events1["default"].FRAG_BUFFERED, {
                                stats: stats,
                                frag: fragCurrent,
                                id: 'main'
                            });
                            this.tick();
                        } else if (fragLoaded.sn === 'initSegment') {
                            this.state = State.IDLE;
                            stats.tparsed = stats.tbuffered = window.performance.now();
                            details.initSegment.data = data.payload;
                            hls.trigger(events1["default"].FRAG_BUFFERED, {
                                stats: stats,
                                frag: fragCurrent,
                                id: 'main'
                            });
                            this.tick();
                        } else {
                            logger1["logger"].log("Parsing " + fragCurrent.sn + " of [" + details.startSN + " ," + details.endSN + "],level " + fragCurrent.level + ", cc " + fragCurrent.cc);
                            this.state = State.PARSING;
                            this.pendingBuffering = true;
                            this.appended = false; // Bitrate test frags are not usually buffered so the fragment tracker ignores them. If Hls.js decides to buffer
                            // it (and therefore ends up at this line), then the fragment tracker needs to be manually informed.
                            if (fragLoaded.bitrateTest) {
                                fragLoaded.bitrateTest = false;
                                this.fragmentTracker.onFragLoaded({
                                    frag: fragLoaded
                                });
                            } // time Offset is accurate if level PTS is known, or if playlist is not sliding (not live) and if media is not seeking (this is to overcome potential timestamp drifts between playlists and fragments)
                            var accurateTimeOffset = !(media && media.seeking) && (details.PTSKnown || !details.live);
                            var initSegmentData = details.initSegment ? details.initSegment.data : [];
                            var audioCodec = this._getAudioCodec(currentLevel); // transmux the MPEG-TS data to ISO-BMFF segments
                            var demuxer = this.demuxer = this.demuxer || new demux_demuxer(this.hls, 'main');
                            demuxer.push(data.payload, initSegmentData, audioCodec, currentLevel.videoCodec, fragCurrent, details.totalduration, accurateTimeOffset);
                        }
                    }
                    this.fragLoadError = 0;
                };
                _proto.onFragParsingInitSegment = function onFragParsingInitSegment(data) {
                    var fragCurrent = this.fragCurrent;
                    var fragNew = data.frag;
                    if (fragCurrent && data.id === 'main' && fragNew.sn === fragCurrent.sn && fragNew.level === fragCurrent.level && this.state === State.PARSING) {
                        var tracks = data.tracks, trackName, track;
                        this.audioOnly = tracks.audio && !tracks.video; // if audio track is expected to come from audio stream controller, discard any coming from main
                        if (this.altAudio && !this.audioOnly) delete tracks.audio;
                         // include levelCodec in audio and video tracks
                        track = tracks.audio;
                        if (track) {
                            var audioCodec = this.levels[this.level].audioCodec, ua = navigator.userAgent.toLowerCase();
                            if (audioCodec && this.audioCodecSwap) {
                                logger1["logger"].log('swapping playlist audio codec');
                                if (audioCodec.indexOf('mp4a.40.5') !== -1) audioCodec = 'mp4a.40.2';
                                else audioCodec = 'mp4a.40.5';
                            } // in case AAC and HE-AAC audio codecs are signalled in manifest
                            // force HE-AAC , as it seems that most browsers prefers that way,
                            // except for mono streams OR on FF
                            // these conditions might need to be reviewed ...
                            if (this.audioCodecSwitch) // don't force HE-AAC if mono stream
                            {
                                if (track.metadata.channelCount !== 1 && ua.indexOf('firefox') === -1) audioCodec = 'mp4a.40.5';
                            } // HE-AAC is broken on Android, always signal audio codec as AAC even if variant manifest states otherwise
                            if (ua.indexOf('android') !== -1 && track.container !== 'audio/mpeg') {
                                // Exclude mpeg audio
                                audioCodec = 'mp4a.40.2';
                                logger1["logger"].log("Android: force audio codec to " + audioCodec);
                            }
                            track.levelCodec = audioCodec;
                            track.id = data.id;
                        }
                        track = tracks.video;
                        if (track) {
                            track.levelCodec = this.levels[this.level].videoCodec;
                            track.id = data.id;
                        }
                        this.hls.trigger(events1["default"].BUFFER_CODECS, tracks); // loop through tracks that are going to be provided to bufferController
                        for(trackName in tracks){
                            track = tracks[trackName];
                            logger1["logger"].log("main track:" + trackName + ",container:" + track.container + ",codecs[level/parsed]=[" + track.levelCodec + "/" + track.codec + "]");
                            var initSegment = track.initSegment;
                            if (initSegment) {
                                this.appended = true; // arm pending Buffering flag before appending a segment
                                this.pendingBuffering = true;
                                this.hls.trigger(events1["default"].BUFFER_APPENDING, {
                                    type: trackName,
                                    data: initSegment,
                                    parent: 'main',
                                    content: 'initSegment'
                                });
                            }
                        } // trigger handler right now
                        this.tick();
                    }
                };
                _proto.onFragParsingData = function onFragParsingData(data) {
                    var _this2 = this;
                    var fragCurrent = this.fragCurrent;
                    var fragNew = data.frag;
                    if (fragCurrent && data.id === 'main' && fragNew.sn === fragCurrent.sn && fragNew.level === fragCurrent.level && !(data.type === 'audio' && this.altAudio) && this.state === State.PARSING) {
                        var level = this.levels[this.level], frag = fragCurrent;
                        if (!Object(number["isFiniteNumber"])(data.endPTS)) {
                            data.endPTS = data.startPTS + fragCurrent.duration;
                            data.endDTS = data.startDTS + fragCurrent.duration;
                        }
                        if (data.hasAudio === true) frag.addElementaryStream(ElementaryStreamTypes1.AUDIO);
                        if (data.hasVideo === true) frag.addElementaryStream(ElementaryStreamTypes1.VIDEO);
                        logger1["logger"].log("Parsed " + data.type + ",PTS:[" + data.startPTS.toFixed(3) + "," + data.endPTS.toFixed(3) + "],DTS:[" + data.startDTS.toFixed(3) + "/" + data.endDTS.toFixed(3) + "],nb:" + data.nb + ",dropped:" + (data.dropped || 0)); // Detect gaps in a fragment  and try to fix it by finding a keyframe in the previous fragment (see _findFragments)
                        if (data.type === 'video') {
                            frag.dropped = data.dropped;
                            if (frag.dropped) {
                                if (!frag.backtracked) {
                                    var levelDetails = level.details;
                                    if (levelDetails && frag.sn === levelDetails.startSN) logger1["logger"].warn('missing video frame(s) on first frag, appending with gap', frag.sn);
                                    else {
                                        logger1["logger"].warn('missing video frame(s), backtracking fragment', frag.sn); // Return back to the IDLE state without appending to buffer
                                        // Causes findFragments to backtrack a segment and find the keyframe
                                        // Audio fragments arriving before video sets the nextLoadPosition, causing _findFragments to skip the backtracked fragment
                                        this.fragmentTracker.removeFragment(frag);
                                        frag.backtracked = true;
                                        this.nextLoadPosition = data.startPTS;
                                        this.state = State.IDLE;
                                        this.fragPrevious = frag;
                                        if (this.demuxer) {
                                            this.demuxer.destroy();
                                            this.demuxer = null;
                                        }
                                        this.tick();
                                        return;
                                    }
                                } else logger1["logger"].warn('Already backtracked on this fragment, appending with the gap', frag.sn);
                            } else // Only reset the backtracked flag if we've loaded the frag without any dropped frames
                            frag.backtracked = false;
                        }
                        var drift = updateFragPTSDTS(level.details, frag, data.startPTS, data.endPTS, data.startDTS, data.endDTS), hls = this.hls;
                        hls.trigger(events1["default"].LEVEL_PTS_UPDATED, {
                            details: level.details,
                            level: this.level,
                            drift: drift,
                            type: data.type,
                            start: data.startPTS,
                            end: data.endPTS
                        }); // has remuxer dropped video frames located before first keyframe ?
                        [
                            data.data1,
                            data.data2
                        ].forEach(function(buffer) {
                            // only append in PARSING state (rationale is that an appending error could happen synchronously on first segment appending)
                            // in that case it is useless to append following segments
                            if (buffer && buffer.length && _this2.state === State.PARSING) {
                                _this2.appended = true; // arm pending Buffering flag before appending a segment
                                _this2.pendingBuffering = true;
                                hls.trigger(events1["default"].BUFFER_APPENDING, {
                                    type: data.type,
                                    data: buffer,
                                    parent: 'main',
                                    content: 'data'
                                });
                            }
                        }); // trigger handler right now
                        this.tick();
                    }
                };
                _proto.onFragParsed = function onFragParsed(data) {
                    var fragCurrent = this.fragCurrent;
                    var fragNew = data.frag;
                    if (fragCurrent && data.id === 'main' && fragNew.sn === fragCurrent.sn && fragNew.level === fragCurrent.level && this.state === State.PARSING) {
                        this.stats.tparsed = window.performance.now();
                        this.state = State.PARSED;
                        this._checkAppendedParsed();
                    }
                };
                _proto.onAudioTrackSwitching = function onAudioTrackSwitching(data) {
                    // if any URL found on new audio track, it is an alternate audio track
                    var fromAltAudio = this.altAudio;
                    var altAudio = !!data.url;
                    var trackId = data.id; // if we switch on main audio, ensure that main fragment scheduling is synced with media.buffered
                    // don't do anything if we switch to alt audio: audio stream controller is handling it.
                    // we will just have to change buffer scheduling on audioTrackSwitched
                    if (!altAudio) {
                        if (this.mediaBuffer !== this.media) {
                            logger1["logger"].log('switching on main audio, use media.buffered to schedule main fragment loading');
                            this.mediaBuffer = this.media;
                            var fragCurrent = this.fragCurrent; // we need to refill audio buffer from main: cancel any frag loading to speed up audio switch
                            if (fragCurrent.loader) {
                                logger1["logger"].log('switching to main audio track, cancel main fragment load');
                                fragCurrent.loader.abort();
                            }
                            this.fragCurrent = null;
                            this.fragPrevious = null; // destroy demuxer to force init segment generation (following audio switch)
                            if (this.demuxer) {
                                this.demuxer.destroy();
                                this.demuxer = null;
                            } // switch to IDLE state to load new fragment
                            this.state = State.IDLE;
                        }
                        var hls = this.hls; // If switching from alt to main audio, flush all audio and trigger track switched
                        if (fromAltAudio) hls.trigger(events1["default"].BUFFER_FLUSHING, {
                            startOffset: 0,
                            endOffset: Number.POSITIVE_INFINITY,
                            type: 'audio'
                        });
                        hls.trigger(events1["default"].AUDIO_TRACK_SWITCHED, {
                            id: trackId
                        });
                    }
                };
                _proto.onAudioTrackSwitched = function onAudioTrackSwitched(data) {
                    var trackId = data.id, altAudio = !!this.hls.audioTracks[trackId].url;
                    if (altAudio) {
                        var videoBuffer = this.videoBuffer; // if we switched on alternate audio, ensure that main fragment scheduling is synced with video sourcebuffer buffered
                        if (videoBuffer && this.mediaBuffer !== videoBuffer) {
                            logger1["logger"].log('switching on alternate audio, use video.buffered to schedule main fragment loading');
                            this.mediaBuffer = videoBuffer;
                        }
                    }
                    this.altAudio = altAudio;
                    this.tick();
                };
                _proto.onBufferCreated = function onBufferCreated(data) {
                    var tracks = data.tracks, mediaTrack, name, alternate = false;
                    for(var type in tracks){
                        var track = tracks[type];
                        if (track.id === 'main') {
                            name = type;
                            mediaTrack = track; // keep video source buffer reference
                            if (type === 'video') this.videoBuffer = tracks[type].buffer;
                        } else alternate = true;
                    }
                    if (alternate && mediaTrack) {
                        logger1["logger"].log("alternate track found, use " + name + ".buffered to schedule main fragment loading");
                        this.mediaBuffer = mediaTrack.buffer;
                    } else this.mediaBuffer = this.media;
                };
                _proto.onBufferAppended = function onBufferAppended(data) {
                    if (data.parent === 'main') {
                        var state = this.state;
                        if (state === State.PARSING || state === State.PARSED) {
                            // check if all buffers have been appended
                            this.pendingBuffering = data.pending > 0;
                            this._checkAppendedParsed();
                        }
                    }
                };
                _proto._checkAppendedParsed = function _checkAppendedParsed() {
                    // trigger handler right now
                    if (this.state === State.PARSED && (!this.appended || !this.pendingBuffering)) {
                        var frag = this.fragCurrent;
                        if (frag) {
                            var media = this.mediaBuffer ? this.mediaBuffer : this.media;
                            logger1["logger"].log("main buffered : " + time_ranges.toString(media.buffered));
                            this.fragPrevious = frag;
                            var stats = this.stats;
                            stats.tbuffered = window.performance.now(); // we should get rid of this.fragLastKbps
                            this.fragLastKbps = Math.round(8 * stats.total / (stats.tbuffered - stats.tfirst));
                            this.hls.trigger(events1["default"].FRAG_BUFFERED, {
                                stats: stats,
                                frag: frag,
                                id: 'main'
                            });
                            this.state = State.IDLE;
                        } // Do not tick when _seekToStartPos needs to be called as seeking to the start can fail on live streams at this point
                        if (this.loadedmetadata || this.startPosition <= 0) this.tick();
                    }
                };
                _proto.onError = function onError(data) {
                    var frag = data.frag || this.fragCurrent; // don't handle frag error not related to main fragment
                    if (frag && frag.type !== 'main') return;
                     // 0.5 : tolerance needed as some browsers stalls playback before reaching buffered end
                    var mediaBuffered = !!this.media && BufferHelper1.isBuffered(this.media, this.media.currentTime) && BufferHelper1.isBuffered(this.media, this.media.currentTime + 0.5);
                    switch(data.details){
                        case errors["ErrorDetails"].FRAG_LOAD_ERROR:
                        case errors["ErrorDetails"].FRAG_LOAD_TIMEOUT:
                        case errors["ErrorDetails"].KEY_LOAD_ERROR:
                        case errors["ErrorDetails"].KEY_LOAD_TIMEOUT:
                            if (!data.fatal) {
                                // keep retrying until the limit will be reached
                                if (this.fragLoadError + 1 <= this.config.fragLoadingMaxRetry) {
                                    // exponential backoff capped to config.fragLoadingMaxRetryTimeout
                                    var delay = Math.min(Math.pow(2, this.fragLoadError) * this.config.fragLoadingRetryDelay, this.config.fragLoadingMaxRetryTimeout);
                                    logger1["logger"].warn("mediaController: frag loading failed, retry in " + delay + " ms");
                                    this.retryDate = window.performance.now() + delay; // retry loading state
                                    // if loadedmetadata is not set, it means that we are emergency switch down on first frag
                                    // in that case, reset startFragRequested flag
                                    if (!this.loadedmetadata) {
                                        this.startFragRequested = false;
                                        this.nextLoadPosition = this.startPosition;
                                    }
                                    this.fragLoadError++;
                                    this.state = State.FRAG_LOADING_WAITING_RETRY;
                                } else {
                                    logger1["logger"].error("mediaController: " + data.details + " reaches max retry, redispatch as fatal ..."); // switch error to fatal
                                    data.fatal = true;
                                    this.state = State.ERROR;
                                }
                            }
                            break;
                        case errors["ErrorDetails"].LEVEL_LOAD_ERROR:
                        case errors["ErrorDetails"].LEVEL_LOAD_TIMEOUT:
                            if (this.state !== State.ERROR) {
                                if (data.fatal) {
                                    // if fatal error, stop processing
                                    this.state = State.ERROR;
                                    logger1["logger"].warn("streamController: " + data.details + ",switch to " + this.state + " state ...");
                                } else // in case of non fatal error while loading level, if level controller is not retrying to load level , switch back to IDLE
                                if (!data.levelRetry && this.state === State.WAITING_LEVEL) this.state = State.IDLE;
                            }
                            break;
                        case errors["ErrorDetails"].BUFFER_FULL_ERROR:
                            // if in appending state
                            if (data.parent === 'main' && (this.state === State.PARSING || this.state === State.PARSED)) {
                                // reduce max buf len if current position is buffered
                                if (mediaBuffered) {
                                    this._reduceMaxBufferLength(this.config.maxBufferLength);
                                    this.state = State.IDLE;
                                } else {
                                    // current position is not buffered, but browser is still complaining about buffer full error
                                    // this happens on IE/Edge, refer to https://github.com/video-dev/hls.js/pull/708
                                    // in that case flush the whole buffer to recover
                                    logger1["logger"].warn('buffer full error also media.currentTime is not buffered, flush everything');
                                    this.fragCurrent = null; // flush everything
                                    this.flushMainBuffer(0, Number.POSITIVE_INFINITY);
                                }
                            }
                            break;
                        default:
                            break;
                    }
                };
                _proto._reduceMaxBufferLength = function _reduceMaxBufferLength(minLength) {
                    var config = this.config;
                    if (config.maxMaxBufferLength >= minLength) {
                        // reduce max buffer length as it might be too high. we do this to avoid loop flushing ...
                        config.maxMaxBufferLength /= 2;
                        logger1["logger"].warn("main:reduce max buffer length to " + config.maxMaxBufferLength + "s");
                        return true;
                    }
                    return false;
                };
                _proto._checkBuffer = function _checkBuffer() {
                    var media = this.media;
                    if (!media || media.readyState === 0) // Exit early if we don't have media or if the media hasn't bufferd anything yet (readyState 0)
                    return;
                    var mediaBuffer = this.mediaBuffer ? this.mediaBuffer : media;
                    var buffered = mediaBuffer.buffered;
                    if (!this.loadedmetadata && buffered.length) {
                        this.loadedmetadata = true;
                        this._seekToStartPos();
                    } else if (this.immediateSwitch) this.immediateLevelSwitchEnd();
                    else this.gapController.poll(this.lastCurrentTime, buffered);
                };
                _proto.onFragLoadEmergencyAborted = function onFragLoadEmergencyAborted() {
                    this.state = State.IDLE; // if loadedmetadata is not set, it means that we are emergency switch down on first frag
                    // in that case, reset startFragRequested flag
                    if (!this.loadedmetadata) {
                        this.startFragRequested = false;
                        this.nextLoadPosition = this.startPosition;
                    }
                    this.tick();
                };
                _proto.onBufferFlushed = function onBufferFlushed() {
                    /* after successful buffer flushing, filter flushed fragments from bufferedFrags
      use mediaBuffered instead of media (so that we will check against video.buffered ranges in case of alt audio track)
    */ var media = this.mediaBuffer ? this.mediaBuffer : this.media;
                    if (media) {
                        // filter fragments potentially evicted from buffer. this is to avoid memleak on live streams
                        var elementaryStreamType = this.audioOnly ? ElementaryStreamTypes1.AUDIO : ElementaryStreamTypes1.VIDEO;
                        this.fragmentTracker.detectEvictedFragments(elementaryStreamType, media.buffered);
                    } // move to IDLE once flush complete. this should trigger new fragment loading
                    this.state = State.IDLE; // reset reference to frag
                    this.fragPrevious = null;
                };
                _proto.onLevelsUpdated = function onLevelsUpdated(data) {
                    this.levels = data.levels;
                };
                _proto.swapAudioCodec = function swapAudioCodec() {
                    this.audioCodecSwap = !this.audioCodecSwap;
                };
                _proto._seekToStartPos = function _seekToStartPos() {
                    var media = this.media;
                    var currentTime = media.currentTime;
                    var startPosition = this.startPosition; // only adjust currentTime if different from startPosition or if startPosition not buffered
                    // at that stage, there should be only one buffered range, as we reach that code after first fragment has been buffered
                    if (currentTime !== startPosition && startPosition >= 0) {
                        if (media.seeking) {
                            logger1["logger"].log("could not seek to " + startPosition + ", already seeking at " + currentTime);
                            return;
                        }
                        var bufferStart = media.buffered.length ? media.buffered.start(0) : 0;
                        var delta = bufferStart - startPosition;
                        if (delta > 0 && delta < this.config.maxBufferHole) {
                            logger1["logger"].log("adjusting start position by " + delta + " to match buffer start");
                            startPosition += delta;
                            this.startPosition = startPosition;
                        }
                        logger1["logger"].log("seek to target start position " + startPosition + " from current time " + currentTime + ". ready state " + media.readyState);
                        media.currentTime = startPosition;
                    }
                };
                _proto._getAudioCodec = function _getAudioCodec(currentLevel) {
                    var audioCodec = this.config.defaultAudioCodec || currentLevel.audioCodec;
                    if (this.audioCodecSwap) {
                        logger1["logger"].log('swapping playlist audio codec');
                        if (audioCodec) {
                            if (audioCodec.indexOf('mp4a.40.5') !== -1) audioCodec = 'mp4a.40.2';
                            else audioCodec = 'mp4a.40.5';
                        }
                    }
                    return audioCodec;
                };
                stream_controller_createClass(StreamController, [
                    {
                        key: "state",
                        set: function set(nextState) {
                            if (this.state !== nextState) {
                                var previousState = this.state;
                                this._state = nextState;
                                logger1["logger"].log("main stream-controller: " + previousState + "->" + nextState);
                                this.hls.trigger(events1["default"].STREAM_STATE_TRANSITION, {
                                    previousState: previousState,
                                    nextState: nextState
                                });
                            }
                        },
                        get: function get() {
                            return this._state;
                        }
                    },
                    {
                        key: "currentLevel",
                        get: function get() {
                            var media = this.media;
                            if (media) {
                                var frag = this.getBufferedFrag(media.currentTime);
                                if (frag) return frag.level;
                            }
                            return -1;
                        }
                    },
                    {
                        key: "nextBufferedFrag",
                        get: function get() {
                            var media = this.media;
                            if (media) // first get end range of current fragment
                            return this.followingBufferedFrag(this.getBufferedFrag(media.currentTime));
                            else return null;
                        }
                    },
                    {
                        key: "nextLevel",
                        get: function get() {
                            var frag = this.nextBufferedFrag;
                            if (frag) return frag.level;
                            else return -1;
                        }
                    },
                    {
                        key: "liveSyncPosition",
                        get: function get() {
                            return this._liveSyncPosition;
                        },
                        set: function set(value) {
                            this._liveSyncPosition = value;
                        }
                    }
                ]);
                return StreamController;
            }(base_stream_controller_BaseStreamController);
            /* harmony default export */ var stream_controller = stream_controller_StreamController;
            // CONCATENATED MODULE: ./src/controller/level-controller.js
            function level_controller_defineProperties(target, props) {
                for(var i = 0; i < props.length; i++){
                    var descriptor = props[i];
                    descriptor.enumerable = descriptor.enumerable || false;
                    descriptor.configurable = true;
                    if ("value" in descriptor) descriptor.writable = true;
                    Object.defineProperty(target, descriptor.key, descriptor);
                }
            }
            function level_controller_createClass(Constructor, protoProps, staticProps) {
                if (protoProps) level_controller_defineProperties(Constructor.prototype, protoProps);
                if (staticProps) level_controller_defineProperties(Constructor, staticProps);
                return Constructor;
            }
            function level_controller_inheritsLoose(subClass, superClass) {
                subClass.prototype = Object.create(superClass.prototype);
                subClass.prototype.constructor = subClass;
                subClass.__proto__ = superClass;
            }
            /*
 * Level Controller
*/ var chromeOrFirefox;
            var level_controller_LevelController = /*#__PURE__*/ function(_EventHandler) {
                level_controller_inheritsLoose(LevelController, _EventHandler);
                function LevelController(hls) {
                    var _this;
                    _this = _EventHandler.call(this, hls, events1["default"].MANIFEST_LOADED, events1["default"].LEVEL_LOADED, events1["default"].AUDIO_TRACK_SWITCHED, events1["default"].FRAG_LOADED, events1["default"].ERROR) || this;
                    _this.canload = false;
                    _this.currentLevelIndex = null;
                    _this.manualLevelIndex = -1;
                    _this.timer = null;
                    chromeOrFirefox = /chrome|firefox/.test(navigator.userAgent.toLowerCase());
                    return _this;
                }
                var _proto = LevelController.prototype;
                _proto.onHandlerDestroying = function onHandlerDestroying() {
                    this.clearTimer();
                    this.manualLevelIndex = -1;
                };
                _proto.clearTimer = function clearTimer() {
                    if (this.timer !== null) {
                        clearTimeout(this.timer);
                        this.timer = null;
                    }
                };
                _proto.startLoad = function startLoad() {
                    var levels = this._levels;
                    this.canload = true;
                    this.levelRetryCount = 0; // clean up live level details to force reload them, and reset load errors
                    if (levels) levels.forEach(function(level) {
                        level.loadError = 0;
                        var levelDetails = level.details;
                        if (levelDetails && levelDetails.live) level.details = undefined;
                    });
                     // speed up live playlist refresh if timer exists
                    if (this.timer !== null) this.loadLevel();
                };
                _proto.stopLoad = function stopLoad() {
                    this.canload = false;
                };
                _proto.onManifestLoaded = function onManifestLoaded(data) {
                    var levels = [];
                    var audioTracks = [];
                    var bitrateStart;
                    var levelSet = {
                    };
                    var levelFromSet = null;
                    var videoCodecFound = false;
                    var audioCodecFound = false; // regroup redundant levels together
                    data.levels.forEach(function(level) {
                        var attributes = level.attrs;
                        level.loadError = 0;
                        level.fragmentError = false;
                        videoCodecFound = videoCodecFound || !!level.videoCodec;
                        audioCodecFound = audioCodecFound || !!level.audioCodec; // erase audio codec info if browser does not support mp4a.40.34.
                        // demuxer will autodetect codec and fallback to mpeg/audio
                        if (chromeOrFirefox && level.audioCodec && level.audioCodec.indexOf('mp4a.40.34') !== -1) level.audioCodec = undefined;
                        levelFromSet = levelSet[level.bitrate]; // FIXME: we would also have to match the resolution here
                        if (!levelFromSet) {
                            level.url = [
                                level.url
                            ];
                            level.urlId = 0;
                            levelSet[level.bitrate] = level;
                            levels.push(level);
                        } else levelFromSet.url.push(level.url);
                        if (attributes) {
                            if (attributes.AUDIO) addGroupId(levelFromSet || level, 'audio', attributes.AUDIO);
                            if (attributes.SUBTITLES) addGroupId(levelFromSet || level, 'text', attributes.SUBTITLES);
                        }
                    }); // remove audio-only level if we also have levels with audio+video codecs signalled
                    if (videoCodecFound && audioCodecFound) levels = levels.filter(function(_ref) {
                        var videoCodec = _ref.videoCodec;
                        return !!videoCodec;
                    });
                     // only keep levels with supported audio/video codecs
                    levels = levels.filter(function(_ref2) {
                        var audioCodec = _ref2.audioCodec, videoCodec = _ref2.videoCodec;
                        return (!audioCodec || isCodecSupportedInMp4(audioCodec, 'audio')) && (!videoCodec || isCodecSupportedInMp4(videoCodec, 'video'));
                    });
                    if (data.audioTracks) {
                        audioTracks = data.audioTracks.filter(function(track) {
                            return !track.audioCodec || isCodecSupportedInMp4(track.audioCodec, 'audio');
                        }); // Reassign id's after filtering since they're used as array indices
                        audioTracks.forEach(function(track, index) {
                            track.id = index;
                        });
                    }
                    if (levels.length > 0) {
                        // start bitrate is the first bitrate of the manifest
                        bitrateStart = levels[0].bitrate; // sort level on bitrate
                        levels.sort(function(a, b) {
                            return a.bitrate - b.bitrate;
                        });
                        this._levels = levels; // find index of first level in sorted levels
                        for(var i = 0; i < levels.length; i++)if (levels[i].bitrate === bitrateStart) {
                            this._firstLevel = i;
                            logger1["logger"].log("manifest loaded," + levels.length + " level(s) found, first bitrate:" + bitrateStart);
                            break;
                        }
                         // Audio is only alternate if manifest include a URI along with the audio group tag,
                        // and this is not an audio-only stream where levels contain audio-only
                        var audioOnly = audioCodecFound && !videoCodecFound;
                        this.hls.trigger(events1["default"].MANIFEST_PARSED, {
                            levels: levels,
                            audioTracks: audioTracks,
                            firstLevel: this._firstLevel,
                            stats: data.stats,
                            audio: audioCodecFound,
                            video: videoCodecFound,
                            altAudio: !audioOnly && audioTracks.some(function(t) {
                                return !!t.url;
                            })
                        });
                    } else this.hls.trigger(events1["default"].ERROR, {
                        type: errors["ErrorTypes"].MEDIA_ERROR,
                        details: errors["ErrorDetails"].MANIFEST_INCOMPATIBLE_CODECS_ERROR,
                        fatal: true,
                        url: this.hls.url,
                        reason: 'no level with compatible codecs found in manifest'
                    });
                };
                _proto.setLevelInternal = function setLevelInternal(newLevel) {
                    var levels = this._levels;
                    var hls = this.hls; // check if level idx is valid
                    if (newLevel >= 0 && newLevel < levels.length) {
                        // stopping live reloading timer if any
                        this.clearTimer();
                        if (this.currentLevelIndex !== newLevel) {
                            logger1["logger"].log("switching to level " + newLevel);
                            this.currentLevelIndex = newLevel;
                            var levelProperties = levels[newLevel];
                            levelProperties.level = newLevel;
                            hls.trigger(events1["default"].LEVEL_SWITCHING, levelProperties);
                        }
                        var level = levels[newLevel];
                        var levelDetails = level.details; // check if we need to load playlist for this level
                        if (!levelDetails || levelDetails.live) {
                            // level not retrieved yet, or live playlist we need to (re)load it
                            var urlId = level.urlId;
                            hls.trigger(events1["default"].LEVEL_LOADING, {
                                url: level.url[urlId],
                                level: newLevel,
                                id: urlId
                            });
                        }
                    } else // invalid level id given, trigger error
                    hls.trigger(events1["default"].ERROR, {
                        type: errors["ErrorTypes"].OTHER_ERROR,
                        details: errors["ErrorDetails"].LEVEL_SWITCH_ERROR,
                        level: newLevel,
                        fatal: false,
                        reason: 'invalid level idx'
                    });
                };
                _proto.onError = function onError(data) {
                    if (data.fatal) {
                        if (data.type === errors["ErrorTypes"].NETWORK_ERROR) this.clearTimer();
                        return;
                    }
                    var levelError = false, fragmentError = false;
                    var levelIndex; // try to recover not fatal errors
                    switch(data.details){
                        case errors["ErrorDetails"].FRAG_LOAD_ERROR:
                        case errors["ErrorDetails"].FRAG_LOAD_TIMEOUT:
                        case errors["ErrorDetails"].KEY_LOAD_ERROR:
                        case errors["ErrorDetails"].KEY_LOAD_TIMEOUT:
                            levelIndex = data.frag.level;
                            fragmentError = true;
                            break;
                        case errors["ErrorDetails"].LEVEL_LOAD_ERROR:
                        case errors["ErrorDetails"].LEVEL_LOAD_TIMEOUT:
                            levelIndex = data.context.level;
                            levelError = true;
                            break;
                        case errors["ErrorDetails"].REMUX_ALLOC_ERROR:
                            levelIndex = data.level;
                            levelError = true;
                            break;
                    }
                    if (levelIndex !== undefined) this.recoverLevel(data, levelIndex, levelError, fragmentError);
                };
                _proto.recoverLevel = function recoverLevel(errorEvent, levelIndex, levelError, fragmentError) {
                    var _this2 = this;
                    var config = this.hls.config;
                    var errorDetails = errorEvent.details;
                    var level = this._levels[levelIndex];
                    var redundantLevels, delay, nextLevel;
                    level.loadError++;
                    level.fragmentError = fragmentError;
                    if (levelError) {
                        if (this.levelRetryCount + 1 <= config.levelLoadingMaxRetry) {
                            // exponential backoff capped to max retry timeout
                            delay = Math.min(Math.pow(2, this.levelRetryCount) * config.levelLoadingRetryDelay, config.levelLoadingMaxRetryTimeout); // Schedule level reload
                            this.timer = setTimeout(function() {
                                return _this2.loadLevel();
                            }, delay); // boolean used to inform stream controller not to switch back to IDLE on non fatal error
                            errorEvent.levelRetry = true;
                            this.levelRetryCount++;
                            logger1["logger"].warn("level controller, " + errorDetails + ", retry in " + delay + " ms, current retry count is " + this.levelRetryCount);
                        } else {
                            logger1["logger"].error("level controller, cannot recover from " + errorDetails + " error");
                            this.currentLevelIndex = null; // stopping live reloading timer if any
                            this.clearTimer(); // switch error to fatal
                            errorEvent.fatal = true;
                            return;
                        }
                    } // Try any redundant streams if available for both errors: level and fragment
                    // If level.loadError reaches redundantLevels it means that we tried them all, no hope  => let's switch down
                    if (levelError || fragmentError) {
                        redundantLevels = level.url.length;
                        if (redundantLevels > 1 && level.loadError < redundantLevels) {
                            level.urlId = (level.urlId + 1) % redundantLevels;
                            level.details = undefined;
                            logger1["logger"].warn("level controller, " + errorDetails + " for level " + levelIndex + ": switching to redundant URL-id " + level.urlId); // console.log('Current audio track group ID:', this.hls.audioTracks[this.hls.audioTrack].groupId);
                        // console.log('New video quality level audio group id:', level.attrs.AUDIO);
                        } else {
                            // Search for available level
                            if (this.manualLevelIndex === -1) {
                                // When lowest level has been reached, let's start hunt from the top
                                nextLevel = levelIndex === 0 ? this._levels.length - 1 : levelIndex - 1;
                                logger1["logger"].warn("level controller, " + errorDetails + ": switch to " + nextLevel);
                                this.hls.nextAutoLevel = this.currentLevelIndex = nextLevel;
                            } else if (fragmentError) {
                                // Allow fragment retry as long as configuration allows.
                                // reset this._level so that another call to set level() will trigger again a frag load
                                logger1["logger"].warn("level controller, " + errorDetails + ": reload a fragment");
                                this.currentLevelIndex = null;
                            }
                        }
                    }
                } // reset errors on the successful load of a fragment
                ;
                _proto.onFragLoaded = function onFragLoaded(_ref3) {
                    var frag = _ref3.frag;
                    if (frag !== undefined && frag.type === 'main') {
                        var level = this._levels[frag.level];
                        if (level !== undefined) {
                            level.fragmentError = false;
                            level.loadError = 0;
                            this.levelRetryCount = 0;
                        }
                    }
                };
                _proto.onLevelLoaded = function onLevelLoaded(data) {
                    var _this3 = this;
                    var level = data.level, details = data.details; // only process level loaded events matching with expected level
                    if (level !== this.currentLevelIndex) return;
                    var curLevel = this._levels[level]; // reset level load error counter on successful level loaded only if there is no issues with fragments
                    if (!curLevel.fragmentError) {
                        curLevel.loadError = 0;
                        this.levelRetryCount = 0;
                    } // if current playlist is a live playlist, arm a timer to reload it
                    if (details.live) {
                        var reloadInterval = computeReloadInterval(curLevel.details, details, data.stats.trequest);
                        logger1["logger"].log("live playlist, reload in " + Math.round(reloadInterval) + " ms");
                        this.timer = setTimeout(function() {
                            return _this3.loadLevel();
                        }, reloadInterval);
                    } else this.clearTimer();
                };
                _proto.onAudioTrackSwitched = function onAudioTrackSwitched(data) {
                    var audioGroupId = this.hls.audioTracks[data.id].groupId;
                    var currentLevel = this.hls.levels[this.currentLevelIndex];
                    if (!currentLevel) return;
                    if (currentLevel.audioGroupIds) {
                        var urlId = -1;
                        for(var i = 0; i < currentLevel.audioGroupIds.length; i++)if (currentLevel.audioGroupIds[i] === audioGroupId) {
                            urlId = i;
                            break;
                        }
                        if (urlId !== currentLevel.urlId) {
                            currentLevel.urlId = urlId;
                            this.startLoad();
                        }
                    }
                };
                _proto.loadLevel = function loadLevel() {
                    logger1["logger"].debug('call to loadLevel');
                    if (this.currentLevelIndex !== null && this.canload) {
                        var levelObject = this._levels[this.currentLevelIndex];
                        if (typeof levelObject === 'object' && levelObject.url.length > 0) {
                            var level = this.currentLevelIndex;
                            var id = levelObject.urlId;
                            var url = levelObject.url[id];
                            logger1["logger"].log("Attempt loading level index " + level + " with URL-id " + id); // console.log('Current audio track group ID:', this.hls.audioTracks[this.hls.audioTrack].groupId);
                            // console.log('New video quality level audio group id:', levelObject.attrs.AUDIO, level);
                            this.hls.trigger(events1["default"].LEVEL_LOADING, {
                                url: url,
                                level: level,
                                id: id
                            });
                        }
                    }
                };
                _proto.removeLevel = function removeLevel(levelIndex, urlId) {
                    var levels = this.levels.filter(function(level, index) {
                        if (index !== levelIndex) return true;
                        if (level.url.length > 1 && urlId !== undefined) {
                            level.url = level.url.filter(function(url, id) {
                                return id !== urlId;
                            });
                            level.urlId = 0;
                            return true;
                        }
                        return false;
                    }).map(function(level, index) {
                        var details = level.details;
                        if (details && details.fragments) details.fragments.forEach(function(fragment) {
                            fragment.level = index;
                        });
                        return level;
                    });
                    this._levels = levels;
                    this.hls.trigger(events1["default"].LEVELS_UPDATED, {
                        levels: levels
                    });
                };
                level_controller_createClass(LevelController, [
                    {
                        key: "levels",
                        get: function get() {
                            return this._levels;
                        }
                    },
                    {
                        key: "level",
                        get: function get() {
                            return this.currentLevelIndex;
                        },
                        set: function set(newLevel) {
                            var levels = this._levels;
                            if (levels) {
                                newLevel = Math.min(newLevel, levels.length - 1);
                                if (this.currentLevelIndex !== newLevel || !levels[newLevel].details) this.setLevelInternal(newLevel);
                            }
                        }
                    },
                    {
                        key: "manualLevel",
                        get: function get() {
                            return this.manualLevelIndex;
                        },
                        set: function set(newLevel) {
                            this.manualLevelIndex = newLevel;
                            if (this._startLevel === undefined) this._startLevel = newLevel;
                            if (newLevel !== -1) this.level = newLevel;
                        }
                    },
                    {
                        key: "firstLevel",
                        get: function get() {
                            return this._firstLevel;
                        },
                        set: function set(newLevel) {
                            this._firstLevel = newLevel;
                        }
                    },
                    {
                        key: "startLevel",
                        get: function get() {
                            // hls.startLevel takes precedence over config.startLevel
                            // if none of these values are defined, fallback on this._firstLevel (first quality level appearing in variant manifest)
                            if (this._startLevel === undefined) {
                                var configStartLevel = this.hls.config.startLevel;
                                if (configStartLevel !== undefined) return configStartLevel;
                                else return this._firstLevel;
                            } else return this._startLevel;
                        },
                        set: function set(newLevel) {
                            this._startLevel = newLevel;
                        }
                    },
                    {
                        key: "nextLoadLevel",
                        get: function get() {
                            if (this.manualLevelIndex !== -1) return this.manualLevelIndex;
                            else return this.hls.nextAutoLevel;
                        },
                        set: function set(nextLevel) {
                            this.level = nextLevel;
                            if (this.manualLevelIndex === -1) this.hls.nextAutoLevel = nextLevel;
                        }
                    }
                ]);
                return LevelController;
            }(event_handler);
            // EXTERNAL MODULE: ./src/demux/id3.js
            var id3 = __webpack_require__("./src/demux/id3.js");
            // CONCATENATED MODULE: ./src/utils/texttrack-utils.ts
            function sendAddTrackEvent(track, videoEl) {
                var event;
                try {
                    event = new Event('addtrack');
                } catch (err) {
                    // for IE11
                    event = document.createEvent('Event');
                    event.initEvent('addtrack', false, false);
                }
                event.track = track;
                videoEl.dispatchEvent(event);
            }
            function clearCurrentCues(track) {
                if (track === null || track === void 0 ? void 0 : track.cues) while(track.cues.length > 0)track.removeCue(track.cues[0]);
            }
            /**
 *  Given a list of Cues, finds the closest cue matching the given time.
 *  Modified verison of binary search O(log(n)).
 *
 * @export
 * @param {(TextTrackCueList | TextTrackCue[])} cues - List of cues.
 * @param {number} time - Target time, to find closest cue to.
 * @returns {TextTrackCue}
 */ function getClosestCue(cues, time) {
                // If the offset is less than the first element, the first element is the closest.
                if (time < cues[0].endTime) return cues[0];
                 // If the offset is greater than the last cue, the last is the closest.
                if (time > cues[cues.length - 1].endTime) return cues[cues.length - 1];
                var left = 0;
                var right = cues.length - 1;
                while(left <= right){
                    var mid = Math.floor((right + left) / 2);
                    if (time < cues[mid].endTime) right = mid - 1;
                    else if (time > cues[mid].endTime) left = mid + 1;
                    else // If it's not lower or higher, it must be equal.
                    return cues[mid];
                } // At this point, left and right have swapped.
                // No direct match was found, left or right element must be the closest. Check which one has the smallest diff.
                return cues[left].endTime - time < time - cues[right].endTime ? cues[left] : cues[right];
            }
            // CONCATENATED MODULE: ./src/controller/id3-track-controller.js
            function id3_track_controller_inheritsLoose(subClass, superClass) {
                subClass.prototype = Object.create(superClass.prototype);
                subClass.prototype.constructor = subClass;
                subClass.__proto__ = superClass;
            }
            /*
 * id3 metadata track controller
*/ var MIN_CUE_DURATION = 0.25;
            var id3_track_controller_ID3TrackController = /*#__PURE__*/ function(_EventHandler) {
                id3_track_controller_inheritsLoose(ID3TrackController, _EventHandler);
                function ID3TrackController(hls) {
                    var _this;
                    _this = _EventHandler.call(this, hls, events1["default"].MEDIA_ATTACHED, events1["default"].MEDIA_DETACHING, events1["default"].FRAG_PARSING_METADATA, events1["default"].LIVE_BACK_BUFFER_REACHED) || this;
                    _this.id3Track = undefined;
                    _this.media = undefined;
                    return _this;
                }
                var _proto = ID3TrackController.prototype;
                _proto.destroy = function destroy() {
                    event_handler.prototype.destroy.call(this);
                } // Add ID3 metatadata text track.
                ;
                _proto.onMediaAttached = function onMediaAttached(data) {
                    this.media = data.media;
                    this.media;
                };
                _proto.onMediaDetaching = function onMediaDetaching() {
                    clearCurrentCues(this.id3Track);
                    this.id3Track = undefined;
                    this.media = undefined;
                };
                _proto.getID3Track = function getID3Track(textTracks) {
                    for(var i = 0; i < textTracks.length; i++){
                        var textTrack = textTracks[i];
                        if (textTrack.kind === 'metadata' && textTrack.label === 'id3') {
                            // send 'addtrack' when reusing the textTrack for metadata,
                            // same as what we do for captions
                            sendAddTrackEvent(textTrack, this.media);
                            return textTrack;
                        }
                    }
                    return this.media.addTextTrack('metadata', 'id3');
                };
                _proto.onFragParsingMetadata = function onFragParsingMetadata(data) {
                    var fragment = data.frag;
                    var samples = data.samples; // create track dynamically
                    if (!this.id3Track) {
                        this.id3Track = this.getID3Track(this.media.textTracks);
                        this.id3Track.mode = 'hidden';
                    } // Attempt to recreate Safari functionality by creating
                    // WebKitDataCue objects when available and store the decoded
                    // ID3 data in the value property of the cue
                    var Cue = window.WebKitDataCue || window.VTTCue || window.TextTrackCue;
                    for(var i = 0; i < samples.length; i++){
                        var frames = id3["default"].getID3Frames(samples[i].data);
                        if (frames) {
                            // Ensure the pts is positive - sometimes it's reported as a small negative number
                            var startTime = Math.max(samples[i].pts, 0);
                            var endTime = i < samples.length - 1 ? samples[i + 1].pts : fragment.endPTS;
                            if (!endTime) endTime = fragment.start + fragment.duration;
                            var timeDiff = endTime - startTime;
                            if (timeDiff <= 0) endTime = startTime + MIN_CUE_DURATION;
                            for(var j = 0; j < frames.length; j++){
                                var frame = frames[j]; // Safari doesn't put the timestamp frame in the TextTrack
                                if (!id3["default"].isTimeStampFrame(frame)) {
                                    var cue = new Cue(startTime, endTime, '');
                                    cue.value = frame;
                                    this.id3Track.addCue(cue);
                                }
                            }
                        }
                    }
                };
                _proto.onLiveBackBufferReached = function onLiveBackBufferReached(_ref) {
                    var bufferEnd = _ref.bufferEnd;
                    var id3Track = this.id3Track;
                    if (!id3Track || !id3Track.cues || !id3Track.cues.length) return;
                    var foundCue = getClosestCue(id3Track.cues, bufferEnd);
                    if (!foundCue) return;
                    while(id3Track.cues[0] !== foundCue)id3Track.removeCue(id3Track.cues[0]);
                };
                return ID3TrackController;
            }(event_handler);
            /* harmony default export */ var id3_track_controller = id3_track_controller_ID3TrackController;
            // CONCATENATED MODULE: ./src/is-supported.ts
            function is_supported_isSupported() {
                var mediaSource = getMediaSource();
                if (!mediaSource) return false;
                var sourceBuffer = self.SourceBuffer || self.WebKitSourceBuffer;
                var isTypeSupported = mediaSource && typeof mediaSource.isTypeSupported === 'function' && mediaSource.isTypeSupported('video/mp4; codecs="avc1.42E01E,mp4a.40.2"'); // if SourceBuffer is exposed ensure its API is valid
                // safari and old version of Chrome doe not expose SourceBuffer globally so checking SourceBuffer.prototype is impossible
                var sourceBufferValidAPI = !sourceBuffer || sourceBuffer.prototype && typeof sourceBuffer.prototype.appendBuffer === 'function' && typeof sourceBuffer.prototype.remove === 'function';
                return !!isTypeSupported && !!sourceBufferValidAPI;
            }
            // CONCATENATED MODULE: ./src/utils/ewma.ts
            /*
 * compute an Exponential Weighted moving average
 * - https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average
 *  - heavily inspired from shaka-player
 */ var EWMA1 = /*#__PURE__*/ function() {
                //  About half of the estimated value will be from the last |halfLife| samples by weight.
                function EWMA(halfLife) {
                    this.alpha_ = void 0;
                    this.estimate_ = void 0;
                    this.totalWeight_ = void 0;
                    // Larger values of alpha expire historical data more slowly.
                    this.alpha_ = halfLife ? Math.exp(Math.log(0.5) / halfLife) : 0;
                    this.estimate_ = 0;
                    this.totalWeight_ = 0;
                }
                var _proto = EWMA.prototype;
                _proto.sample = function sample(weight, value) {
                    var adjAlpha = Math.pow(this.alpha_, weight);
                    this.estimate_ = value * (1 - adjAlpha) + adjAlpha * this.estimate_;
                    this.totalWeight_ += weight;
                };
                _proto.getTotalWeight = function getTotalWeight() {
                    return this.totalWeight_;
                };
                _proto.getEstimate = function getEstimate() {
                    if (this.alpha_) {
                        var zeroFactor = 1 - Math.pow(this.alpha_, this.totalWeight_);
                        return this.estimate_ / zeroFactor;
                    } else return this.estimate_;
                };
                return EWMA;
            }();
            /* harmony default export */ var ewma = EWMA1;
            // CONCATENATED MODULE: ./src/utils/ewma-bandwidth-estimator.ts
            /*
 * EWMA Bandwidth Estimator
 *  - heavily inspired from shaka-player
 * Tracks bandwidth samples and estimates available bandwidth.
 * Based on the minimum of two exponentially-weighted moving averages with
 * different half-lives.
 */ var ewma_bandwidth_estimator_EwmaBandWidthEstimator = /*#__PURE__*/ function() {
                // TODO(typescript-hls)
                function EwmaBandWidthEstimator(hls, slow, fast, defaultEstimate) {
                    this.hls = void 0;
                    this.defaultEstimate_ = void 0;
                    this.minWeight_ = void 0;
                    this.minDelayMs_ = void 0;
                    this.slow_ = void 0;
                    this.fast_ = void 0;
                    this.hls = hls;
                    this.defaultEstimate_ = defaultEstimate;
                    this.minWeight_ = 0.001;
                    this.minDelayMs_ = 50;
                    this.slow_ = new ewma(slow);
                    this.fast_ = new ewma(fast);
                }
                var _proto = EwmaBandWidthEstimator.prototype;
                _proto.sample = function sample(durationMs, numBytes) {
                    durationMs = Math.max(durationMs, this.minDelayMs_);
                    var numBits = 8 * numBytes, // weight is duration in seconds
                    durationS = durationMs / 1000, // value is bandwidth in bits/s
                    bandwidthInBps = numBits / durationS;
                    this.fast_.sample(durationS, bandwidthInBps);
                    this.slow_.sample(durationS, bandwidthInBps);
                };
                _proto.canEstimate = function canEstimate() {
                    var fast = this.fast_;
                    return fast && fast.getTotalWeight() >= this.minWeight_;
                };
                _proto.getEstimate = function getEstimate() {
                    if (this.canEstimate()) // console.log('slow estimate:'+ Math.round(this.slow_.getEstimate()));
                    // console.log('fast estimate:'+ Math.round(this.fast_.getEstimate()));
                    // Take the minimum of these two estimates.  This should have the effect of
                    // adapting down quickly, but up more slowly.
                    return Math.min(this.fast_.getEstimate(), this.slow_.getEstimate());
                    else return this.defaultEstimate_;
                };
                _proto.destroy = function destroy() {
                };
                return EwmaBandWidthEstimator;
            }();
            /* harmony default export */ var ewma_bandwidth_estimator = ewma_bandwidth_estimator_EwmaBandWidthEstimator;
            // CONCATENATED MODULE: ./src/controller/abr-controller.js
            function abr_controller_defineProperties(target, props) {
                for(var i = 0; i < props.length; i++){
                    var descriptor = props[i];
                    descriptor.enumerable = descriptor.enumerable || false;
                    descriptor.configurable = true;
                    if ("value" in descriptor) descriptor.writable = true;
                    Object.defineProperty(target, descriptor.key, descriptor);
                }
            }
            function abr_controller_createClass(Constructor, protoProps, staticProps) {
                if (protoProps) abr_controller_defineProperties(Constructor.prototype, protoProps);
                if (staticProps) abr_controller_defineProperties(Constructor, staticProps);
                return Constructor;
            }
            function abr_controller_assertThisInitialized(self) {
                if (self === void 0) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
                return self;
            }
            function abr_controller_inheritsLoose(subClass, superClass) {
                subClass.prototype = Object.create(superClass.prototype);
                subClass.prototype.constructor = subClass;
                subClass.__proto__ = superClass;
            }
            /*
 * simple ABR Controller
 *  - compute next level based on last fragment bw heuristics
 *  - implement an abandon rules triggered if we have less than 2 frag buffered and if computed bw shows that we risk buffer stalling
 */ var abr_controller_window = window, abr_controller_performance = abr_controller_window.performance;
            var abr_controller_AbrController = /*#__PURE__*/ function(_EventHandler) {
                abr_controller_inheritsLoose(AbrController, _EventHandler);
                function AbrController(hls) {
                    var _this;
                    _this = _EventHandler.call(this, hls, events1["default"].FRAG_LOADING, events1["default"].FRAG_LOADED, events1["default"].FRAG_BUFFERED, events1["default"].ERROR) || this;
                    _this.lastLoadedFragLevel = 0;
                    _this._nextAutoLevel = -1;
                    _this.hls = hls;
                    _this.timer = null;
                    _this._bwEstimator = null;
                    _this.onCheck = _this._abandonRulesCheck.bind(abr_controller_assertThisInitialized(_this));
                    return _this;
                }
                var _proto = AbrController.prototype;
                _proto.destroy = function destroy() {
                    this.clearTimer();
                    event_handler.prototype.destroy.call(this);
                };
                _proto.onFragLoading = function onFragLoading(data) {
                    var frag = data.frag;
                    if (frag.type === 'main') {
                        if (!this.timer) {
                            this.fragCurrent = frag;
                            this.timer = setInterval(this.onCheck, 100);
                        } // lazy init of BwEstimator, rationale is that we use different params for Live/VoD
                        // so we need to wait for stream manifest / playlist type to instantiate it.
                        if (!this._bwEstimator) {
                            var hls = this.hls;
                            var config = hls.config;
                            var level = frag.level;
                            var isLive = hls.levels[level].details.live;
                            var ewmaFast;
                            var ewmaSlow;
                            if (isLive) {
                                ewmaFast = config.abrEwmaFastLive;
                                ewmaSlow = config.abrEwmaSlowLive;
                            } else {
                                ewmaFast = config.abrEwmaFastVoD;
                                ewmaSlow = config.abrEwmaSlowVoD;
                            }
                            this._bwEstimator = new ewma_bandwidth_estimator(hls, ewmaSlow, ewmaFast, config.abrEwmaDefaultEstimate);
                        }
                    }
                };
                _proto._abandonRulesCheck = function _abandonRulesCheck() {
                    /*
      monitor fragment retrieval time...
      we compute expected time of arrival of the complete fragment.
      we compare it to expected time of buffer starvation
    */ var hls = this.hls;
                    var video = hls.media;
                    var frag = this.fragCurrent;
                    if (!frag) return;
                    var loader = frag.loader; // if loader has been destroyed or loading has been aborted, stop timer and return
                    if (!loader || loader.stats && loader.stats.aborted) {
                        logger1["logger"].warn('frag loader destroy or aborted, disarm abandonRules');
                        this.clearTimer(); // reset forced auto level value so that next level will be selected
                        this._nextAutoLevel = -1;
                        return;
                    }
                    var stats = loader.stats;
                    /* only monitor frag retrieval time if
    (video not paused OR first fragment being loaded(ready state === HAVE_NOTHING = 0)) AND autoswitching enabled AND not lowest level (=> means that we have several levels) */ if (video && stats && (!video.paused && video.playbackRate !== 0 || !video.readyState) && frag.autoLevel && frag.level) {
                        var requestDelay = abr_controller_performance.now() - stats.trequest;
                        var playbackRate = Math.abs(video.playbackRate); // monitor fragment load progress after half of expected fragment duration,to stabilize bitrate
                        if (requestDelay > 500 * frag.duration / playbackRate) {
                            var levels = hls.levels;
                            var loadRate = Math.max(1, stats.bw ? stats.bw / 8 : stats.loaded * 1000 / requestDelay); // byte/s; at least 1 byte/s to avoid division by zero
                            // compute expected fragment length using frag duration and level bitrate. also ensure that expected len is gte than already loaded size
                            var level = levels[frag.level];
                            if (!level) return;
                            var levelBitrate = level.realBitrate ? Math.max(level.realBitrate, level.bitrate) : level.bitrate;
                            var expectedLen = stats.total ? stats.total : Math.max(stats.loaded, Math.round(frag.duration * levelBitrate / 8));
                            var pos = video.currentTime;
                            var fragLoadedDelay = (expectedLen - stats.loaded) / loadRate;
                            var bufferStarvationDelay = (BufferHelper1.bufferInfo(video, pos, hls.config.maxBufferHole).end - pos) / playbackRate; // consider emergency switch down only if we have less than 2 frag buffered AND
                            // time to finish loading current fragment is bigger than buffer starvation delay
                            // ie if we risk buffer starvation if bw does not increase quickly
                            if (bufferStarvationDelay < 2 * frag.duration / playbackRate && fragLoadedDelay > bufferStarvationDelay) {
                                var minAutoLevel = hls.minAutoLevel;
                                var fragLevelNextLoadedDelay;
                                var nextLoadLevel; // lets iterate through lower level and try to find the biggest one that could avoid rebuffering
                                // we start from current level - 1 and we step down , until we find a matching level
                                for(nextLoadLevel = frag.level - 1; nextLoadLevel > minAutoLevel; nextLoadLevel--){
                                    // compute time to load next fragment at lower level
                                    // 0.8 : consider only 80% of current bw to be conservative
                                    // 8 = bits per byte (bps/Bps)
                                    var levelNextBitrate = levels[nextLoadLevel].realBitrate ? Math.max(levels[nextLoadLevel].realBitrate, levels[nextLoadLevel].bitrate) : levels[nextLoadLevel].bitrate;
                                    var _fragLevelNextLoadedDelay = frag.duration * levelNextBitrate / (6.4 * loadRate);
                                    if (_fragLevelNextLoadedDelay < bufferStarvationDelay) break;
                                } // only emergency switch down if it takes less time to load new fragment at lowest level instead
                                // of finishing loading current one ...
                                if (fragLevelNextLoadedDelay < fragLoadedDelay) {
                                    logger1["logger"].warn("loading too slow, abort fragment loading and switch to level " + nextLoadLevel + ":fragLoadedDelay[" + nextLoadLevel + "]<fragLoadedDelay[" + (frag.level - 1) + "];bufferStarvationDelay:" + fragLevelNextLoadedDelay.toFixed(1) + "<" + fragLoadedDelay.toFixed(1) + ":" + bufferStarvationDelay.toFixed(1)); // force next load level in auto mode
                                    hls.nextLoadLevel = nextLoadLevel; // update bw estimate for this fragment before cancelling load (this will help reducing the bw)
                                    this._bwEstimator.sample(requestDelay, stats.loaded); // abort fragment loading
                                    loader.abort(); // stop abandon rules timer
                                    this.clearTimer();
                                    hls.trigger(events1["default"].FRAG_LOAD_EMERGENCY_ABORTED, {
                                        frag: frag,
                                        stats: stats
                                    });
                                }
                            }
                        }
                    }
                };
                _proto.onFragLoaded = function onFragLoaded(data) {
                    var frag = data.frag;
                    if (frag.type === 'main' && Object(number["isFiniteNumber"])(frag.sn)) {
                        // stop monitoring bw once frag loaded
                        this.clearTimer(); // store level id after successful fragment load
                        this.lastLoadedFragLevel = frag.level; // reset forced auto level value so that next level will be selected
                        this._nextAutoLevel = -1; // compute level average bitrate
                        if (this.hls.config.abrMaxWithRealBitrate) {
                            var level = this.hls.levels[frag.level];
                            var loadedBytes = (level.loaded ? level.loaded.bytes : 0) + data.stats.loaded;
                            var loadedDuration = (level.loaded ? level.loaded.duration : 0) + data.frag.duration;
                            level.loaded = {
                                bytes: loadedBytes,
                                duration: loadedDuration
                            };
                            level.realBitrate = Math.round(8 * loadedBytes / loadedDuration);
                        } // if fragment has been loaded to perform a bitrate test,
                        if (data.frag.bitrateTest) {
                            var stats = data.stats;
                            stats.tparsed = stats.tbuffered = stats.tload;
                            this.onFragBuffered(data);
                        }
                    }
                };
                _proto.onFragBuffered = function onFragBuffered(data) {
                    var stats = data.stats;
                    var frag = data.frag; // only update stats on first frag buffering
                    // if same frag is loaded multiple times, it might be in browser cache, and loaded quickly
                    // and leading to wrong bw estimation
                    // on bitrate test, also only update stats once (if tload = tbuffered == on FRAG_LOADED)
                    if (stats.aborted !== true && frag.type === 'main' && Object(number["isFiniteNumber"])(frag.sn) && (!frag.bitrateTest || stats.tload === stats.tbuffered)) {
                        // use tparsed-trequest instead of tbuffered-trequest to compute fragLoadingProcessing; rationale is that  buffer appending only happens once media is attached
                        // in case we use config.startFragPrefetch while media is not attached yet, fragment might be parsed while media not attached yet, but it will only be buffered on media attached
                        // as a consequence it could happen really late in the process. meaning that appending duration might appears huge ... leading to underestimated throughput estimation
                        var fragLoadingProcessingMs = stats.tparsed - stats.trequest;
                        logger1["logger"].log("latency/loading/parsing/append/kbps:" + Math.round(stats.tfirst - stats.trequest) + "/" + Math.round(stats.tload - stats.tfirst) + "/" + Math.round(stats.tparsed - stats.tload) + "/" + Math.round(stats.tbuffered - stats.tparsed) + "/" + Math.round(8 * stats.loaded / (stats.tbuffered - stats.trequest)));
                        this._bwEstimator.sample(fragLoadingProcessingMs, stats.loaded);
                        stats.bwEstimate = this._bwEstimator.getEstimate(); // if fragment has been loaded to perform a bitrate test, (hls.startLevel = -1), store bitrate test delay duration
                        if (frag.bitrateTest) this.bitrateTestDelay = fragLoadingProcessingMs / 1000;
                        else this.bitrateTestDelay = 0;
                    }
                };
                _proto.onError = function onError(data) {
                    // stop timer in case of frag loading error
                    switch(data.details){
                        case errors["ErrorDetails"].FRAG_LOAD_ERROR:
                        case errors["ErrorDetails"].FRAG_LOAD_TIMEOUT:
                            this.clearTimer();
                            break;
                        default:
                            break;
                    }
                };
                _proto.clearTimer = function clearTimer() {
                    clearInterval(this.timer);
                    this.timer = null;
                } // return next auto level
                ;
                _proto._findBestLevel = function _findBestLevel(currentLevel, currentFragDuration, currentBw, minAutoLevel, maxAutoLevel, maxFetchDuration, bwFactor, bwUpFactor, levels) {
                    for(var i = maxAutoLevel; i >= minAutoLevel; i--){
                        var levelInfo = levels[i];
                        if (!levelInfo) continue;
                        var levelDetails = levelInfo.details;
                        var avgDuration = levelDetails ? levelDetails.totalduration / levelDetails.fragments.length : currentFragDuration;
                        var live = levelDetails ? levelDetails.live : false;
                        var adjustedbw = void 0; // follow algorithm captured from stagefright :
                        // https://android.googlesource.com/platform/frameworks/av/+/master/media/libstagefright/httplive/LiveSession.cpp
                        // Pick the highest bandwidth stream below or equal to estimated bandwidth.
                        // consider only 80% of the available bandwidth, but if we are switching up,
                        // be even more conservative (70%) to avoid overestimating and immediately
                        // switching back.
                        if (i <= currentLevel) adjustedbw = bwFactor * currentBw;
                        else adjustedbw = bwUpFactor * currentBw;
                        var bitrate = levels[i].realBitrate ? Math.max(levels[i].realBitrate, levels[i].bitrate) : levels[i].bitrate;
                        var fetchDuration = bitrate * avgDuration / adjustedbw;
                        logger1["logger"].trace("level/adjustedbw/bitrate/avgDuration/maxFetchDuration/fetchDuration: " + i + "/" + Math.round(adjustedbw) + "/" + bitrate + "/" + avgDuration + "/" + maxFetchDuration + "/" + fetchDuration); // if adjusted bw is greater than level bitrate AND
                        if (adjustedbw > bitrate && // we don't account for max Fetch Duration for live streams, this is to avoid switching down when near the edge of live sliding window ...
                        // special case to support startLevel = -1 (bitrateTest) on live streams : in that case we should not exit loop so that _findBestLevel will return -1
                        (!fetchDuration || live && !this.bitrateTestDelay || fetchDuration < maxFetchDuration)) // as we are looping from highest to lowest, this will return the best achievable quality level
                        return i;
                    } // not enough time budget even with quality level 0 ... rebuffering might happen
                    return -1;
                };
                abr_controller_createClass(AbrController, [
                    {
                        key: "nextAutoLevel",
                        get: function get() {
                            var forcedAutoLevel = this._nextAutoLevel;
                            var bwEstimator = this._bwEstimator; // in case next auto level has been forced, and bw not available or not reliable, return forced value
                            if (forcedAutoLevel !== -1 && (!bwEstimator || !bwEstimator.canEstimate())) return forcedAutoLevel;
                             // compute next level using ABR logic
                            var nextABRAutoLevel = this._nextABRAutoLevel; // if forced auto level has been defined, use it to cap ABR computed quality level
                            if (forcedAutoLevel !== -1) nextABRAutoLevel = Math.min(forcedAutoLevel, nextABRAutoLevel);
                            return nextABRAutoLevel;
                        },
                        set: function set(nextLevel) {
                            this._nextAutoLevel = nextLevel;
                        }
                    },
                    {
                        key: "_nextABRAutoLevel",
                        get: function get() {
                            var hls = this.hls;
                            var maxAutoLevel = hls.maxAutoLevel, levels = hls.levels, config = hls.config, minAutoLevel = hls.minAutoLevel;
                            var video = hls.media;
                            var currentLevel = this.lastLoadedFragLevel;
                            var currentFragDuration = this.fragCurrent ? this.fragCurrent.duration : 0;
                            var pos = video ? video.currentTime : 0; // playbackRate is the absolute value of the playback rate; if video.playbackRate is 0, we use 1 to load as
                            // if we're playing back at the normal rate.
                            var playbackRate = video && video.playbackRate !== 0 ? Math.abs(video.playbackRate) : 1;
                            var avgbw = this._bwEstimator ? this._bwEstimator.getEstimate() : config.abrEwmaDefaultEstimate; // bufferStarvationDelay is the wall-clock time left until the playback buffer is exhausted.
                            var bufferStarvationDelay = (BufferHelper1.bufferInfo(video, pos, config.maxBufferHole).end - pos) / playbackRate; // First, look to see if we can find a level matching with our avg bandwidth AND that could also guarantee no rebuffering at all
                            var bestLevel = this._findBestLevel(currentLevel, currentFragDuration, avgbw, minAutoLevel, maxAutoLevel, bufferStarvationDelay, config.abrBandWidthFactor, config.abrBandWidthUpFactor, levels);
                            if (bestLevel >= 0) return bestLevel;
                            else {
                                logger1["logger"].trace('rebuffering expected to happen, lets try to find a quality level minimizing the rebuffering'); // not possible to get rid of rebuffering ... let's try to find level that will guarantee less than maxStarvationDelay of rebuffering
                                // if no matching level found, logic will return 0
                                var maxStarvationDelay = currentFragDuration ? Math.min(currentFragDuration, config.maxStarvationDelay) : config.maxStarvationDelay;
                                var bwFactor = config.abrBandWidthFactor;
                                var bwUpFactor = config.abrBandWidthUpFactor;
                                if (bufferStarvationDelay === 0) {
                                    // in case buffer is empty, let's check if previous fragment was loaded to perform a bitrate test
                                    var bitrateTestDelay = this.bitrateTestDelay;
                                    if (bitrateTestDelay) {
                                        // if it is the case, then we need to adjust our max starvation delay using maxLoadingDelay config value
                                        // max video loading delay used in  automatic start level selection :
                                        // in that mode ABR controller will ensure that video loading time (ie the time to fetch the first fragment at lowest quality level +
                                        // the time to fetch the fragment at the appropriate quality level is less than ```maxLoadingDelay``` )
                                        // cap maxLoadingDelay and ensure it is not bigger 'than bitrate test' frag duration
                                        var maxLoadingDelay = currentFragDuration ? Math.min(currentFragDuration, config.maxLoadingDelay) : config.maxLoadingDelay;
                                        maxStarvationDelay = maxLoadingDelay - bitrateTestDelay;
                                        logger1["logger"].trace("bitrate test took " + Math.round(1000 * bitrateTestDelay) + "ms, set first fragment max fetchDuration to " + Math.round(1000 * maxStarvationDelay) + " ms"); // don't use conservative factor on bitrate test
                                        bwFactor = bwUpFactor = 1;
                                    }
                                }
                                bestLevel = this._findBestLevel(currentLevel, currentFragDuration, avgbw, minAutoLevel, maxAutoLevel, bufferStarvationDelay + maxStarvationDelay, bwFactor, bwUpFactor, levels);
                                return Math.max(bestLevel, 0);
                            }
                        }
                    }
                ]);
                return AbrController;
            }(event_handler);
            /* harmony default export */ var abr_controller = abr_controller_AbrController;
            // CONCATENATED MODULE: ./src/controller/buffer-controller.ts
            function buffer_controller_inheritsLoose(subClass, superClass) {
                subClass.prototype = Object.create(superClass.prototype);
                subClass.prototype.constructor = subClass;
                subClass.__proto__ = superClass;
            }
            /*
 * Buffer Controller
 */ var buffer_controller_MediaSource = getMediaSource();
            var buffer_controller_BufferController = /*#__PURE__*/ function(_EventHandler) {
                buffer_controller_inheritsLoose(BufferController, _EventHandler);
                // the value that we have set mediasource.duration to
                // (the actual duration may be tweaked slighly by the browser)
                // the value that we want to set mediaSource.duration to
                // the target duration of the current media playlist
                // current stream state: true - for live broadcast, false - for VoD content
                // cache the self generated object url to detect hijack of video tag
                // signals that the sourceBuffers need to be flushed
                // signals that mediaSource should have endOfStream called
                // this is optional because this property is removed from the class sometimes
                // The number of BUFFER_CODEC events received before any sourceBuffers are created
                // The total number of BUFFER_CODEC events received
                // A reference to the attached media element
                // A reference to the active media source
                // List of pending segments to be appended to source buffer
                // A guard to see if we are currently appending to the source buffer
                // counters
                function BufferController(hls) {
                    var _this;
                    _this = _EventHandler.call(this, hls, events1["default"].MEDIA_ATTACHING, events1["default"].MEDIA_DETACHING, events1["default"].MANIFEST_PARSED, events1["default"].BUFFER_RESET, events1["default"].BUFFER_APPENDING, events1["default"].BUFFER_CODECS, events1["default"].BUFFER_EOS, events1["default"].BUFFER_FLUSHING, events1["default"].LEVEL_PTS_UPDATED, events1["default"].LEVEL_UPDATED) || this;
                    _this._msDuration = null;
                    _this._levelDuration = null;
                    _this._levelTargetDuration = 10;
                    _this._live = null;
                    _this._objectUrl = null;
                    _this._needsFlush = false;
                    _this._needsEos = false;
                    _this.config = void 0;
                    _this.audioTimestampOffset = void 0;
                    _this.bufferCodecEventsExpected = 0;
                    _this._bufferCodecEventsTotal = 0;
                    _this.media = null;
                    _this.mediaSource = null;
                    _this.segments = [];
                    _this.parent = void 0;
                    _this.appending = false;
                    _this.appended = 0;
                    _this.appendError = 0;
                    _this.flushBufferCounter = 0;
                    _this.tracks = {
                    };
                    _this.pendingTracks = {
                    };
                    _this.sourceBuffer = {
                    };
                    _this.flushRange = [];
                    _this._onMediaSourceOpen = function() {
                        logger1["logger"].log('media source opened');
                        _this.hls.trigger(events1["default"].MEDIA_ATTACHED, {
                            media: _this.media
                        });
                        var mediaSource = _this.mediaSource;
                        if (mediaSource) // once received, don't listen anymore to sourceopen event
                        mediaSource.removeEventListener('sourceopen', _this._onMediaSourceOpen);
                        _this.checkPendingTracks();
                    };
                    _this._onMediaSourceClose = function() {
                        logger1["logger"].log('media source closed');
                    };
                    _this._onMediaSourceEnded = function() {
                        logger1["logger"].log('media source ended');
                    };
                    _this._onSBUpdateEnd = function() {
                        // update timestampOffset
                        if (_this.audioTimestampOffset && _this.sourceBuffer.audio) {
                            var audioBuffer = _this.sourceBuffer.audio;
                            logger1["logger"].warn("change mpeg audio timestamp offset from " + audioBuffer.timestampOffset + " to " + _this.audioTimestampOffset);
                            audioBuffer.timestampOffset = _this.audioTimestampOffset;
                            delete _this.audioTimestampOffset;
                        }
                        if (_this._needsFlush) _this.doFlush();
                        if (_this._needsEos) _this.checkEos();
                        _this.appending = false;
                        var parent = _this.parent; // count nb of pending segments waiting for appending on this sourcebuffer
                        var pending = _this.segments.reduce(function(counter, segment) {
                            return segment.parent === parent ? counter + 1 : counter;
                        }, 0); // this.sourceBuffer is better to use than media.buffered as it is closer to the PTS data from the fragments
                        var timeRanges = {
                        };
                        var sbSet = _this.sourceBuffer;
                        for(var streamType in sbSet){
                            var sb = sbSet[streamType];
                            if (!sb) throw Error("handling source buffer update end error: source buffer for " + streamType + " uninitilized and unable to update buffered TimeRanges.");
                            timeRanges[streamType] = sb.buffered;
                        }
                        _this.hls.trigger(events1["default"].BUFFER_APPENDED, {
                            parent: parent,
                            pending: pending,
                            timeRanges: timeRanges
                        }); // don't append in flushing mode
                        if (!_this._needsFlush) _this.doAppending();
                        _this.updateMediaElementDuration(); // appending goes first
                        if (pending === 0) _this.flushLiveBackBuffer();
                    };
                    _this._onSBUpdateError = function(event) {
                        logger1["logger"].error('sourceBuffer error:', event); // according to http://www.w3.org/TR/media-source/#sourcebuffer-append-error
                        // this error might not always be fatal (it is fatal if decode error is set, in that case
                        // it will be followed by a mediaElement error ...)
                        _this.hls.trigger(events1["default"].ERROR, {
                            type: errors["ErrorTypes"].MEDIA_ERROR,
                            details: errors["ErrorDetails"].BUFFER_APPENDING_ERROR,
                            fatal: false
                        }); // we don't need to do more than that, as accordin to the spec, updateend will be fired just after
                    };
                    _this.config = hls.config;
                    return _this;
                }
                var _proto = BufferController.prototype;
                _proto.destroy = function destroy() {
                    event_handler.prototype.destroy.call(this);
                };
                _proto.onLevelPtsUpdated = function onLevelPtsUpdated(data) {
                    var type = data.type;
                    var audioTrack = this.tracks.audio; // Adjusting `SourceBuffer.timestampOffset` (desired point in the timeline where the next frames should be appended)
                    // in Chrome browser when we detect MPEG audio container and time delta between level PTS and `SourceBuffer.timestampOffset`
                    // is greater than 100ms (this is enough to handle seek for VOD or level change for LIVE videos). At the time of change we issue
                    // `SourceBuffer.abort()` and adjusting `SourceBuffer.timestampOffset` if `SourceBuffer.updating` is false or awaiting `updateend`
                    // event if SB is in updating state.
                    // More info here: https://github.com/video-dev/hls.js/issues/332#issuecomment-257986486
                    if (type === 'audio' && audioTrack && audioTrack.container === 'audio/mpeg') {
                        // Chrome audio mp3 track
                        var audioBuffer = this.sourceBuffer.audio;
                        if (!audioBuffer) throw Error('Level PTS Updated and source buffer for audio uninitalized');
                        var delta = Math.abs(audioBuffer.timestampOffset - data.start); // adjust timestamp offset if time delta is greater than 100ms
                        if (delta > 0.1) {
                            var updating = audioBuffer.updating;
                            try {
                                audioBuffer.abort();
                            } catch (err) {
                                logger1["logger"].warn('can not abort audio buffer: ' + err);
                            }
                            if (!updating) {
                                logger1["logger"].warn('change mpeg audio timestamp offset from ' + audioBuffer.timestampOffset + ' to ' + data.start);
                                audioBuffer.timestampOffset = data.start;
                            } else this.audioTimestampOffset = data.start;
                        }
                    }
                };
                _proto.onManifestParsed = function onManifestParsed(data) {
                    // in case of alt audio (where all tracks have urls) 2 BUFFER_CODECS events will be triggered, one per stream controller
                    // sourcebuffers will be created all at once when the expected nb of tracks will be reached
                    // in case alt audio is not used, only one BUFFER_CODEC event will be fired from main stream controller
                    // it will contain the expected nb of source buffers, no need to compute it
                    var codecEvents = 2;
                    if (data.audio && !data.video || !data.altAudio) codecEvents = 1;
                    this.bufferCodecEventsExpected = this._bufferCodecEventsTotal = codecEvents;
                    logger1["logger"].log(this.bufferCodecEventsExpected + " bufferCodec event(s) expected");
                };
                _proto.onMediaAttaching = function onMediaAttaching(data) {
                    var media = this.media = data.media;
                    if (media && buffer_controller_MediaSource) {
                        // setup the media source
                        var ms = this.mediaSource = new buffer_controller_MediaSource(); // Media Source listeners
                        ms.addEventListener('sourceopen', this._onMediaSourceOpen);
                        ms.addEventListener('sourceended', this._onMediaSourceEnded);
                        ms.addEventListener('sourceclose', this._onMediaSourceClose); // link video and media Source
                        media.src = window.URL.createObjectURL(ms); // cache the locally generated object url
                        this._objectUrl = media.src;
                    }
                };
                _proto.onMediaDetaching = function onMediaDetaching() {
                    logger1["logger"].log('media source detaching');
                    var ms = this.mediaSource;
                    if (ms) {
                        if (ms.readyState === 'open') try {
                            // endOfStream could trigger exception if any sourcebuffer is in updating state
                            // we don't really care about checking sourcebuffer state here,
                            // as we are anyway detaching the MediaSource
                            // let's just avoid this exception to propagate
                            ms.endOfStream();
                        } catch (err) {
                            logger1["logger"].warn("onMediaDetaching:" + err.message + " while calling endOfStream");
                        }
                        ms.removeEventListener('sourceopen', this._onMediaSourceOpen);
                        ms.removeEventListener('sourceended', this._onMediaSourceEnded);
                        ms.removeEventListener('sourceclose', this._onMediaSourceClose); // Detach properly the MediaSource from the HTMLMediaElement as
                        // suggested in https://github.com/w3c/media-source/issues/53.
                        if (this.media) {
                            if (this._objectUrl) window.URL.revokeObjectURL(this._objectUrl);
                             // clean up video tag src only if it's our own url. some external libraries might
                            // hijack the video tag and change its 'src' without destroying the Hls instance first
                            if (this.media.src === this._objectUrl) {
                                this.media.removeAttribute('src');
                                this.media.load();
                            } else logger1["logger"].warn('media.src was changed by a third party - skip cleanup');
                        }
                        this.mediaSource = null;
                        this.media = null;
                        this._objectUrl = null;
                        this.bufferCodecEventsExpected = this._bufferCodecEventsTotal;
                        this.pendingTracks = {
                        };
                        this.tracks = {
                        };
                        this.sourceBuffer = {
                        };
                        this.flushRange = [];
                        this.segments = [];
                        this.appended = 0;
                    }
                    this.hls.trigger(events1["default"].MEDIA_DETACHED);
                };
                _proto.checkPendingTracks = function checkPendingTracks() {
                    var bufferCodecEventsExpected = this.bufferCodecEventsExpected, pendingTracks = this.pendingTracks; // Check if we've received all of the expected bufferCodec events. When none remain, create all the sourceBuffers at once.
                    // This is important because the MSE spec allows implementations to throw QuotaExceededErrors if creating new sourceBuffers after
                    // data has been appended to existing ones.
                    // 2 tracks is the max (one for audio, one for video). If we've reach this max go ahead and create the buffers.
                    var pendingTracksCount = Object.keys(pendingTracks).length;
                    if (pendingTracksCount && !bufferCodecEventsExpected || pendingTracksCount === 2) {
                        // ok, let's create them now !
                        this.createSourceBuffers(pendingTracks);
                        this.pendingTracks = {
                        }; // append any pending segments now !
                        this.doAppending();
                    }
                };
                _proto.onBufferReset = function onBufferReset() {
                    var sourceBuffer = this.sourceBuffer;
                    for(var type in sourceBuffer){
                        var sb = sourceBuffer[type];
                        try {
                            if (sb) {
                                if (this.mediaSource) this.mediaSource.removeSourceBuffer(sb);
                                sb.removeEventListener('updateend', this._onSBUpdateEnd);
                                sb.removeEventListener('error', this._onSBUpdateError);
                            }
                        } catch (err) {
                        }
                    }
                    this.sourceBuffer = {
                    };
                    this.flushRange = [];
                    this.segments = [];
                    this.appended = 0;
                };
                _proto.onBufferCodecs = function onBufferCodecs(tracks) {
                    var _this2 = this;
                    // if source buffer(s) not created yet, appended buffer tracks in this.pendingTracks
                    // if sourcebuffers already created, do nothing ...
                    if (Object.keys(this.sourceBuffer).length) return;
                    Object.keys(tracks).forEach(function(trackName) {
                        _this2.pendingTracks[trackName] = tracks[trackName];
                    });
                    this.bufferCodecEventsExpected = Math.max(this.bufferCodecEventsExpected - 1, 0);
                    if (this.mediaSource && this.mediaSource.readyState === 'open') this.checkPendingTracks();
                };
                _proto.createSourceBuffers = function createSourceBuffers(tracks) {
                    var sourceBuffer = this.sourceBuffer, mediaSource = this.mediaSource;
                    if (!mediaSource) throw Error('createSourceBuffers called when mediaSource was null');
                    for(var trackName in tracks)if (!sourceBuffer[trackName]) {
                        var track = tracks[trackName];
                        if (!track) throw Error("source buffer exists for track " + trackName + ", however track does not");
                         // use levelCodec as first priority
                        var codec = track.levelCodec || track.codec;
                        var mimeType = track.container + ";codecs=" + codec;
                        logger1["logger"].log("creating sourceBuffer(" + mimeType + ")");
                        try {
                            var sb = sourceBuffer[trackName] = mediaSource.addSourceBuffer(mimeType);
                            sb.addEventListener('updateend', this._onSBUpdateEnd);
                            sb.addEventListener('error', this._onSBUpdateError);
                            this.tracks[trackName] = {
                                buffer: sb,
                                codec: codec,
                                id: track.id,
                                container: track.container,
                                levelCodec: track.levelCodec
                            };
                        } catch (err) {
                            logger1["logger"].error("error while trying to add sourceBuffer:" + err.message);
                            this.hls.trigger(events1["default"].ERROR, {
                                type: errors["ErrorTypes"].MEDIA_ERROR,
                                details: errors["ErrorDetails"].BUFFER_ADD_CODEC_ERROR,
                                fatal: false,
                                err: err,
                                mimeType: mimeType
                            });
                        }
                    }
                    this.hls.trigger(events1["default"].BUFFER_CREATED, {
                        tracks: this.tracks
                    });
                };
                _proto.onBufferAppending = function onBufferAppending(data) {
                    if (!this._needsFlush) {
                        if (!this.segments) this.segments = [
                            data
                        ];
                        else this.segments.push(data);
                        this.doAppending();
                    }
                } // on BUFFER_EOS mark matching sourcebuffer(s) as ended and trigger checkEos()
                ;
                _proto.onBufferEos = function onBufferEos(data) {
                    for(var type in this.sourceBuffer)if (!data.type || data.type === type) {
                        var sb = this.sourceBuffer[type];
                        if (sb && !sb.ended) {
                            sb.ended = true;
                            logger1["logger"].log(type + " sourceBuffer now EOS");
                        }
                    }
                    this.checkEos();
                } // if all source buffers are marked as ended, signal endOfStream() to MediaSource.
                ;
                _proto.checkEos = function checkEos() {
                    var sourceBuffer = this.sourceBuffer, mediaSource = this.mediaSource;
                    if (!mediaSource || mediaSource.readyState !== 'open') {
                        this._needsEos = false;
                        return;
                    }
                    for(var type in sourceBuffer){
                        var sb = sourceBuffer[type];
                        if (!sb) continue;
                        if (!sb.ended) return;
                        if (sb.updating) {
                            this._needsEos = true;
                            return;
                        }
                    }
                    logger1["logger"].log('all media data are available, signal endOfStream() to MediaSource and stop loading fragment'); // Notify the media element that it now has all of the media data
                    try {
                        mediaSource.endOfStream();
                    } catch (e) {
                        logger1["logger"].warn('exception while calling mediaSource.endOfStream()');
                    }
                    this._needsEos = false;
                };
                _proto.onBufferFlushing = function onBufferFlushing(data) {
                    if (data.type) this.flushRange.push({
                        start: data.startOffset,
                        end: data.endOffset,
                        type: data.type
                    });
                    else {
                        this.flushRange.push({
                            start: data.startOffset,
                            end: data.endOffset,
                            type: 'video'
                        });
                        this.flushRange.push({
                            start: data.startOffset,
                            end: data.endOffset,
                            type: 'audio'
                        });
                    } // attempt flush immediately
                    this.flushBufferCounter = 0;
                    this.doFlush();
                };
                _proto.flushLiveBackBuffer = function flushLiveBackBuffer() {
                    // clear back buffer for live only
                    if (!this._live) return;
                    var liveBackBufferLength = this.config.liveBackBufferLength;
                    if (!isFinite(liveBackBufferLength) || liveBackBufferLength < 0) return;
                    if (!this.media) {
                        logger1["logger"].error('flushLiveBackBuffer called without attaching media');
                        return;
                    }
                    var currentTime = this.media.currentTime;
                    var sourceBuffer = this.sourceBuffer;
                    var bufferTypes = Object.keys(sourceBuffer);
                    var targetBackBufferPosition = currentTime - Math.max(liveBackBufferLength, this._levelTargetDuration);
                    for(var index = bufferTypes.length - 1; index >= 0; index--){
                        var bufferType = bufferTypes[index];
                        var sb = sourceBuffer[bufferType];
                        if (sb) {
                            var buffered = sb.buffered; // when target buffer start exceeds actual buffer start
                            if (buffered.length > 0 && targetBackBufferPosition > buffered.start(0)) // remove buffer up until current time minus minimum back buffer length (removing buffer too close to current
                            // time will lead to playback freezing)
                            // credits for level target duration - https://github.com/videojs/http-streaming/blob/3132933b6aa99ddefab29c10447624efd6fd6e52/src/segment-loader.js#L91
                            {
                                if (this.removeBufferRange(bufferType, sb, 0, targetBackBufferPosition)) this.hls.trigger(events1["default"].LIVE_BACK_BUFFER_REACHED, {
                                    bufferEnd: targetBackBufferPosition
                                });
                            }
                        }
                    }
                };
                _proto.onLevelUpdated = function onLevelUpdated(_ref) {
                    var details = _ref.details;
                    if (details.fragments.length > 0) {
                        this._levelDuration = details.totalduration + details.fragments[0].start;
                        this._levelTargetDuration = details.averagetargetduration || details.targetduration || 10;
                        this._live = details.live;
                        this.updateMediaElementDuration();
                    }
                };
                _proto.updateMediaElementDuration = function updateMediaElementDuration() {
                    var config = this.config;
                    var duration;
                    if (this._levelDuration === null || !this.media || !this.mediaSource || !this.sourceBuffer || this.media.readyState === 0 || this.mediaSource.readyState !== 'open') return;
                    for(var type in this.sourceBuffer){
                        var sb = this.sourceBuffer[type];
                        if (sb && sb.updating === true) // can't set duration whilst a buffer is updating
                        return;
                    }
                    duration = this.media.duration; // initialise to the value that the media source is reporting
                    if (this._msDuration === null) this._msDuration = this.mediaSource.duration;
                    if (this._live === true && config.liveDurationInfinity === true) {
                        // Override duration to Infinity
                        logger1["logger"].log('Media Source duration is set to Infinity');
                        this._msDuration = this.mediaSource.duration = Infinity;
                    } else if (this._levelDuration > this._msDuration && this._levelDuration > duration || !Object(number["isFiniteNumber"])(duration)) {
                        // levelDuration was the last value we set.
                        // not using mediaSource.duration as the browser may tweak this value
                        // only update Media Source duration if its value increase, this is to avoid
                        // flushing already buffered portion when switching between quality level
                        logger1["logger"].log("Updating Media Source duration to " + this._levelDuration.toFixed(3));
                        this._msDuration = this.mediaSource.duration = this._levelDuration;
                    }
                };
                _proto.doFlush = function doFlush() {
                    // loop through all buffer ranges to flush
                    while(this.flushRange.length){
                        var range = this.flushRange[0]; // flushBuffer will abort any buffer append in progress and flush Audio/Video Buffer
                        if (this.flushBuffer(range.start, range.end, range.type)) {
                            // range flushed, remove from flush array
                            this.flushRange.shift();
                            this.flushBufferCounter = 0;
                        } else {
                            this._needsFlush = true; // avoid looping, wait for SB update end to retrigger a flush
                            return;
                        }
                    }
                    if (this.flushRange.length === 0) {
                        // everything flushed
                        this._needsFlush = false; // let's recompute this.appended, which is used to avoid flush looping
                        var appended = 0;
                        var sourceBuffer = this.sourceBuffer;
                        try {
                            for(var type in sourceBuffer){
                                var sb = sourceBuffer[type];
                                if (sb) appended += sb.buffered.length;
                            }
                        } catch (error) {
                            // error could be thrown while accessing buffered, in case sourcebuffer has already been removed from MediaSource
                            // this is harmess at this stage, catch this to avoid reporting an internal exception
                            logger1["logger"].error('error while accessing sourceBuffer.buffered');
                        }
                        this.appended = appended;
                        this.hls.trigger(events1["default"].BUFFER_FLUSHED);
                    }
                };
                _proto.doAppending = function doAppending() {
                    var config = this.config, hls = this.hls, segments = this.segments, sourceBuffer = this.sourceBuffer;
                    if (!Object.keys(sourceBuffer).length) // early exit if no source buffers have been initialized yet
                    return;
                    if (!this.media || this.media.error) {
                        this.segments = [];
                        logger1["logger"].error('trying to append although a media error occured, flush segment and abort');
                        return;
                    }
                    if (this.appending) // logger.log(`sb appending in progress`);
                    return;
                    var segment = segments.shift();
                    if (!segment) // handle undefined shift
                    return;
                    try {
                        var sb = sourceBuffer[segment.type];
                        if (!sb) {
                            // in case we don't have any source buffer matching with this segment type,
                            // it means that Mediasource fails to create sourcebuffer
                            // discard this segment, and trigger update end
                            this._onSBUpdateEnd();
                            return;
                        }
                        if (sb.updating) {
                            // if we are still updating the source buffer from the last segment, place this back at the front of the queue
                            segments.unshift(segment);
                            return;
                        } // reset sourceBuffer ended flag before appending segment
                        sb.ended = false; // logger.log(`appending ${segment.content} ${type} SB, size:${segment.data.length}, ${segment.parent}`);
                        this.parent = segment.parent;
                        sb.appendBuffer(segment.data);
                        this.appendError = 0;
                        this.appended++;
                        this.appending = true;
                    } catch (err) {
                        // in case any error occured while appending, put back segment in segments table
                        logger1["logger"].error("error while trying to append buffer:" + err.message);
                        segments.unshift(segment);
                        var event = {
                            type: errors["ErrorTypes"].MEDIA_ERROR,
                            parent: segment.parent,
                            details: '',
                            fatal: false
                        };
                        if (err.code === 22) {
                            // QuotaExceededError: http://www.w3.org/TR/html5/infrastructure.html#quotaexceedederror
                            // let's stop appending any segments, and report BUFFER_FULL_ERROR error
                            this.segments = [];
                            event.details = errors["ErrorDetails"].BUFFER_FULL_ERROR;
                        } else {
                            this.appendError++;
                            event.details = errors["ErrorDetails"].BUFFER_APPEND_ERROR;
                            /* with UHD content, we could get loop of quota exceeded error until
          browser is able to evict some data from sourcebuffer. retrying help recovering this
        */ if (this.appendError > config.appendErrorMaxRetry) {
                                logger1["logger"].log("fail " + config.appendErrorMaxRetry + " times to append segment in sourceBuffer");
                                this.segments = [];
                                event.fatal = true;
                            }
                        }
                        hls.trigger(events1["default"].ERROR, event);
                    }
                };
                _proto.flushBuffer = function flushBuffer(startOffset, endOffset, sbType) {
                    var sourceBuffer = this.sourceBuffer; // exit if no sourceBuffers are initialized
                    if (!Object.keys(sourceBuffer).length) return true;
                    var currentTime = 'null';
                    if (this.media) currentTime = this.media.currentTime.toFixed(3);
                    logger1["logger"].log("flushBuffer,pos/start/end: " + currentTime + "/" + startOffset + "/" + endOffset); // safeguard to avoid infinite looping : don't try to flush more than the nb of appended segments
                    if (this.flushBufferCounter >= this.appended) {
                        logger1["logger"].warn('abort flushing too many retries');
                        return true;
                    }
                    var sb = sourceBuffer[sbType]; // we are going to flush buffer, mark source buffer as 'not ended'
                    if (sb) {
                        sb.ended = false;
                        if (!sb.updating) {
                            if (this.removeBufferRange(sbType, sb, startOffset, endOffset)) {
                                this.flushBufferCounter++;
                                return false;
                            }
                        } else {
                            logger1["logger"].warn('cannot flush, sb updating in progress');
                            return false;
                        }
                    }
                    logger1["logger"].log('buffer flushed'); // everything flushed !
                    return true;
                };
                _proto.removeBufferRange = function removeBufferRange(type, sb, startOffset, endOffset) {
                    try {
                        for(var i = 0; i < sb.buffered.length; i++){
                            var bufStart = sb.buffered.start(i);
                            var bufEnd = sb.buffered.end(i);
                            var removeStart = Math.max(bufStart, startOffset);
                            var removeEnd = Math.min(bufEnd, endOffset);
                            /* sometimes sourcebuffer.remove() does not flush
          the exact expected time range.
          to avoid rounding issues/infinite loop,
          only flush buffer range of length greater than 500ms.
        */ if (Math.min(removeEnd, bufEnd) - removeStart > 0.5) {
                                var currentTime = 'null';
                                if (this.media) currentTime = this.media.currentTime.toString();
                                logger1["logger"].log("sb remove " + type + " [" + removeStart + "," + removeEnd + "], of [" + bufStart + "," + bufEnd + "], pos:" + currentTime);
                                sb.remove(removeStart, removeEnd);
                                return true;
                            }
                        }
                    } catch (error) {
                        logger1["logger"].warn('removeBufferRange failed', error);
                    }
                    return false;
                };
                return BufferController;
            }(event_handler);
            /* harmony default export */ var buffer_controller = buffer_controller_BufferController;
            // CONCATENATED MODULE: ./src/controller/cap-level-controller.js
            function cap_level_controller_defineProperties(target, props) {
                for(var i = 0; i < props.length; i++){
                    var descriptor = props[i];
                    descriptor.enumerable = descriptor.enumerable || false;
                    descriptor.configurable = true;
                    if ("value" in descriptor) descriptor.writable = true;
                    Object.defineProperty(target, descriptor.key, descriptor);
                }
            }
            function cap_level_controller_createClass(Constructor, protoProps, staticProps) {
                if (protoProps) cap_level_controller_defineProperties(Constructor.prototype, protoProps);
                if (staticProps) cap_level_controller_defineProperties(Constructor, staticProps);
                return Constructor;
            }
            function cap_level_controller_inheritsLoose(subClass, superClass) {
                subClass.prototype = Object.create(superClass.prototype);
                subClass.prototype.constructor = subClass;
                subClass.__proto__ = superClass;
            }
            /*
 * cap stream level to media size dimension controller
*/ var cap_level_controller_CapLevelController = /*#__PURE__*/ function(_EventHandler) {
                cap_level_controller_inheritsLoose(CapLevelController, _EventHandler);
                function CapLevelController(hls) {
                    var _this;
                    _this = _EventHandler.call(this, hls, events1["default"].FPS_DROP_LEVEL_CAPPING, events1["default"].MEDIA_ATTACHING, events1["default"].MANIFEST_PARSED, events1["default"].LEVELS_UPDATED, events1["default"].BUFFER_CODECS, events1["default"].MEDIA_DETACHING) || this;
                    _this.autoLevelCapping = Number.POSITIVE_INFINITY;
                    _this.firstLevel = null;
                    _this.levels = [];
                    _this.media = null;
                    _this.restrictedLevels = [];
                    _this.timer = null;
                    _this.clientRect = null;
                    return _this;
                }
                var _proto = CapLevelController.prototype;
                _proto.destroy = function destroy() {
                    if (this.hls.config.capLevelToPlayerSize) {
                        this.media = null;
                        this.clientRect = null;
                        this.stopCapping();
                    }
                };
                _proto.onFpsDropLevelCapping = function onFpsDropLevelCapping(data) {
                    // Don't add a restricted level more than once
                    if (CapLevelController.isLevelAllowed(data.droppedLevel, this.restrictedLevels)) this.restrictedLevels.push(data.droppedLevel);
                };
                _proto.onMediaAttaching = function onMediaAttaching(data) {
                    this.media = data.media instanceof window.HTMLVideoElement ? data.media : null;
                };
                _proto.onManifestParsed = function onManifestParsed(data) {
                    var hls = this.hls;
                    this.restrictedLevels = [];
                    this.levels = data.levels;
                    this.firstLevel = data.firstLevel;
                    if (hls.config.capLevelToPlayerSize && data.video) // Start capping immediately if the manifest has signaled video codecs
                    this.startCapping();
                } // Only activate capping when playing a video stream; otherwise, multi-bitrate audio-only streams will be restricted
                ;
                _proto.onBufferCodecs = function onBufferCodecs(data) {
                    var hls = this.hls;
                    if (hls.config.capLevelToPlayerSize && data.video) // If the manifest did not signal a video codec capping has been deferred until we're certain video is present
                    this.startCapping();
                };
                _proto.onLevelsUpdated = function onLevelsUpdated(data) {
                    this.levels = data.levels;
                };
                _proto.onMediaDetaching = function onMediaDetaching() {
                    this.stopCapping();
                };
                _proto.detectPlayerSize = function detectPlayerSize() {
                    if (this.media) {
                        var levelsLength = this.levels ? this.levels.length : 0;
                        if (levelsLength) {
                            var hls = this.hls;
                            hls.autoLevelCapping = this.getMaxLevel(levelsLength - 1);
                            if (hls.autoLevelCapping > this.autoLevelCapping) // if auto level capping has a higher value for the previous one, flush the buffer using nextLevelSwitch
                            // usually happen when the user go to the fullscreen mode.
                            hls.streamController.nextLevelSwitch();
                            this.autoLevelCapping = hls.autoLevelCapping;
                        }
                    }
                };
                _proto.getMaxLevel = function getMaxLevel(capLevelIndex) {
                    var _this2 = this;
                    if (!this.levels) return -1;
                    var validLevels = this.levels.filter(function(level, index) {
                        return CapLevelController.isLevelAllowed(index, _this2.restrictedLevels) && index <= capLevelIndex;
                    });
                    this.clientRect = null;
                    return CapLevelController.getMaxLevelByMediaSize(validLevels, this.mediaWidth, this.mediaHeight);
                };
                _proto.startCapping = function startCapping() {
                    if (this.timer) // Don't reset capping if started twice; this can happen if the manifest signals a video codec
                    return;
                    this.autoLevelCapping = Number.POSITIVE_INFINITY;
                    this.hls.firstLevel = this.getMaxLevel(this.firstLevel);
                    clearInterval(this.timer);
                    this.timer = setInterval(this.detectPlayerSize.bind(this), 1000);
                    this.detectPlayerSize();
                };
                _proto.stopCapping = function stopCapping() {
                    this.restrictedLevels = [];
                    this.firstLevel = null;
                    this.autoLevelCapping = Number.POSITIVE_INFINITY;
                    if (this.timer) {
                        this.timer = clearInterval(this.timer);
                        this.timer = null;
                    }
                };
                _proto.getDimensions = function getDimensions() {
                    if (this.clientRect) return this.clientRect;
                    var media = this.media;
                    var boundsRect = {
                        width: 0,
                        height: 0
                    };
                    if (media) {
                        var clientRect = media.getBoundingClientRect();
                        boundsRect.width = clientRect.width;
                        boundsRect.height = clientRect.height;
                        if (!boundsRect.width && !boundsRect.height) {
                            // When the media element has no width or height (equivalent to not being in the DOM),
                            // then use its width and height attributes (media.width, media.height)
                            boundsRect.width = clientRect.right - clientRect.left || media.width || 0;
                            boundsRect.height = clientRect.bottom - clientRect.top || media.height || 0;
                        }
                    }
                    this.clientRect = boundsRect;
                    return boundsRect;
                };
                CapLevelController.isLevelAllowed = function isLevelAllowed(level, restrictedLevels) {
                    if (restrictedLevels === void 0) restrictedLevels = [];
                    return restrictedLevels.indexOf(level) === -1;
                };
                CapLevelController.getMaxLevelByMediaSize = function getMaxLevelByMediaSize(levels, width, height) {
                    if (!levels || levels && !levels.length) return -1;
                     // Levels can have the same dimensions but differing bandwidths - since levels are ordered, we can look to the next
                    // to determine whether we've chosen the greatest bandwidth for the media's dimensions
                    var atGreatestBandiwdth = function atGreatestBandiwdth(curLevel, nextLevel) {
                        if (!nextLevel) return true;
                        return curLevel.width !== nextLevel.width || curLevel.height !== nextLevel.height;
                    }; // If we run through the loop without breaking, the media's dimensions are greater than every level, so default to
                    // the max level
                    var maxLevelIndex = levels.length - 1;
                    for(var i = 0; i < levels.length; i += 1){
                        var level = levels[i];
                        if ((level.width >= width || level.height >= height) && atGreatestBandiwdth(level, levels[i + 1])) {
                            maxLevelIndex = i;
                            break;
                        }
                    }
                    return maxLevelIndex;
                };
                cap_level_controller_createClass(CapLevelController, [
                    {
                        key: "mediaWidth",
                        get: function get() {
                            return this.getDimensions().width * CapLevelController.contentScaleFactor;
                        }
                    },
                    {
                        key: "mediaHeight",
                        get: function get() {
                            return this.getDimensions().height * CapLevelController.contentScaleFactor;
                        }
                    }
                ], [
                    {
                        key: "contentScaleFactor",
                        get: function get() {
                            var pixelRatio = 1;
                            try {
                                pixelRatio = window.devicePixelRatio;
                            } catch (e) {
                            }
                            return pixelRatio;
                        }
                    }
                ]);
                return CapLevelController;
            }(event_handler);
            /* harmony default export */ var cap_level_controller = cap_level_controller_CapLevelController;
            // CONCATENATED MODULE: ./src/controller/fps-controller.js
            function fps_controller_inheritsLoose(subClass, superClass) {
                subClass.prototype = Object.create(superClass.prototype);
                subClass.prototype.constructor = subClass;
                subClass.__proto__ = superClass;
            }
            /*
 * FPS Controller
*/ var fps_controller_window = window, fps_controller_performance = fps_controller_window.performance;
            var fps_controller_FPSController = /*#__PURE__*/ function(_EventHandler) {
                fps_controller_inheritsLoose(FPSController, _EventHandler);
                function FPSController(hls) {
                    return _EventHandler.call(this, hls, events1["default"].MEDIA_ATTACHING) || this;
                }
                var _proto = FPSController.prototype;
                _proto.destroy = function destroy() {
                    if (this.timer) clearInterval(this.timer);
                    this.isVideoPlaybackQualityAvailable = false;
                };
                _proto.onMediaAttaching = function onMediaAttaching(data) {
                    var config = this.hls.config;
                    if (config.capLevelOnFPSDrop) {
                        var video = this.video = data.media instanceof window.HTMLVideoElement ? data.media : null;
                        if (typeof video.getVideoPlaybackQuality === 'function') this.isVideoPlaybackQualityAvailable = true;
                        clearInterval(this.timer);
                        this.timer = setInterval(this.checkFPSInterval.bind(this), config.fpsDroppedMonitoringPeriod);
                    }
                };
                _proto.checkFPS = function checkFPS(video, decodedFrames, droppedFrames) {
                    var currentTime = fps_controller_performance.now();
                    if (decodedFrames) {
                        if (this.lastTime) {
                            var currentPeriod = currentTime - this.lastTime, currentDropped = droppedFrames - this.lastDroppedFrames, currentDecoded = decodedFrames - this.lastDecodedFrames, droppedFPS = 1000 * currentDropped / currentPeriod, hls = this.hls;
                            hls.trigger(events1["default"].FPS_DROP, {
                                currentDropped: currentDropped,
                                currentDecoded: currentDecoded,
                                totalDroppedFrames: droppedFrames
                            });
                            if (droppedFPS > 0) // logger.log('checkFPS : droppedFPS/decodedFPS:' + droppedFPS/(1000 * currentDecoded / currentPeriod));
                            {
                                if (currentDropped > hls.config.fpsDroppedMonitoringThreshold * currentDecoded) {
                                    var currentLevel = hls.currentLevel;
                                    logger1["logger"].warn('drop FPS ratio greater than max allowed value for currentLevel: ' + currentLevel);
                                    if (currentLevel > 0 && (hls.autoLevelCapping === -1 || hls.autoLevelCapping >= currentLevel)) {
                                        currentLevel = currentLevel - 1;
                                        hls.trigger(events1["default"].FPS_DROP_LEVEL_CAPPING, {
                                            level: currentLevel,
                                            droppedLevel: hls.currentLevel
                                        });
                                        hls.autoLevelCapping = currentLevel;
                                        hls.streamController.nextLevelSwitch();
                                    }
                                }
                            }
                        }
                        this.lastTime = currentTime;
                        this.lastDroppedFrames = droppedFrames;
                        this.lastDecodedFrames = decodedFrames;
                    }
                };
                _proto.checkFPSInterval = function checkFPSInterval() {
                    var video = this.video;
                    if (video) {
                        if (this.isVideoPlaybackQualityAvailable) {
                            var videoPlaybackQuality = video.getVideoPlaybackQuality();
                            this.checkFPS(video, videoPlaybackQuality.totalVideoFrames, videoPlaybackQuality.droppedVideoFrames);
                        } else this.checkFPS(video, video.webkitDecodedFrameCount, video.webkitDroppedFrameCount);
                    }
                };
                return FPSController;
            }(event_handler);
            /* harmony default export */ var fps_controller = fps_controller_FPSController;
            // CONCATENATED MODULE: ./src/utils/xhr-loader.js
            /**
 * XHR based logger
*/ var xhr_loader_XhrLoader = /*#__PURE__*/ function() {
                function XhrLoader(config) {
                    if (config && config.xhrSetup) this.xhrSetup = config.xhrSetup;
                }
                var _proto = XhrLoader.prototype;
                _proto.destroy = function destroy() {
                    this.abort();
                    this.loader = null;
                };
                _proto.abort = function abort() {
                    var loader = this.loader;
                    if (loader && loader.readyState !== 4) {
                        this.stats.aborted = true;
                        loader.abort();
                    }
                    window.clearTimeout(this.requestTimeout);
                    this.requestTimeout = null;
                    window.clearTimeout(this.retryTimeout);
                    this.retryTimeout = null;
                };
                _proto.load = function load(context, config, callbacks) {
                    this.context = context;
                    this.config = config;
                    this.callbacks = callbacks;
                    this.stats = {
                        trequest: window.performance.now(),
                        retry: 0
                    };
                    this.retryDelay = config.retryDelay;
                    this.loadInternal();
                };
                _proto.loadInternal = function loadInternal() {
                    var xhr, context = this.context;
                    xhr = this.loader = new window.XMLHttpRequest();
                    var stats = this.stats;
                    stats.tfirst = 0;
                    stats.loaded = 0;
                    var xhrSetup = this.xhrSetup;
                    try {
                        if (xhrSetup) try {
                            xhrSetup(xhr, context.url);
                        } catch (e) {
                            // fix xhrSetup: (xhr, url) => {xhr.setRequestHeader("Content-Language", "test");}
                            // not working, as xhr.setRequestHeader expects xhr.readyState === OPEN
                            xhr.open('GET', context.url, true);
                            xhrSetup(xhr, context.url);
                        }
                        if (!xhr.readyState) xhr.open('GET', context.url, true);
                    } catch (e) {
                        // IE11 throws an exception on xhr.open if attempting to access an HTTP resource over HTTPS
                        this.callbacks.onError({
                            code: xhr.status,
                            text: e.message
                        }, context, xhr);
                        return;
                    }
                    if (context.rangeEnd) xhr.setRequestHeader('Range', 'bytes=' + context.rangeStart + '-' + (context.rangeEnd - 1));
                    xhr.onreadystatechange = this.readystatechange.bind(this);
                    xhr.onprogress = this.loadprogress.bind(this);
                    xhr.responseType = context.responseType; // setup timeout before we perform request
                    this.requestTimeout = window.setTimeout(this.loadtimeout.bind(this), this.config.timeout);
                    xhr.send();
                };
                _proto.readystatechange = function readystatechange(event) {
                    var xhr = event.currentTarget, readyState = xhr.readyState, stats = this.stats, context = this.context, config = this.config; // don't proceed if xhr has been aborted
                    if (stats.aborted) return;
                     // >= HEADERS_RECEIVED
                    if (readyState >= 2) {
                        // clear xhr timeout and rearm it if readyState less than 4
                        window.clearTimeout(this.requestTimeout);
                        if (stats.tfirst === 0) stats.tfirst = Math.max(window.performance.now(), stats.trequest);
                        if (readyState === 4) {
                            var status = xhr.status; // http status between 200 to 299 are all successful
                            if (status >= 200 && status < 300) {
                                stats.tload = Math.max(stats.tfirst, window.performance.now());
                                var data, len;
                                if (context.responseType === 'arraybuffer') {
                                    data = xhr.response;
                                    len = data.byteLength;
                                } else {
                                    data = xhr.responseText;
                                    len = data.length;
                                }
                                stats.loaded = stats.total = len;
                                var response = {
                                    url: xhr.responseURL,
                                    data: data
                                };
                                this.callbacks.onSuccess(response, stats, context, xhr);
                            } else // if max nb of retries reached or if http status between 400 and 499 (such error cannot be recovered, retrying is useless), return error
                            if (stats.retry >= config.maxRetry || status >= 400 && status < 499) {
                                logger1["logger"].error(status + " while loading " + context.url);
                                this.callbacks.onError({
                                    code: status,
                                    text: xhr.statusText
                                }, context, xhr);
                            } else {
                                // retry
                                logger1["logger"].warn(status + " while loading " + context.url + ", retrying in " + this.retryDelay + "..."); // aborts and resets internal state
                                this.destroy(); // schedule retry
                                this.retryTimeout = window.setTimeout(this.loadInternal.bind(this), this.retryDelay); // set exponential backoff
                                this.retryDelay = Math.min(2 * this.retryDelay, config.maxRetryDelay);
                                stats.retry++;
                            }
                        } else // readyState >= 2 AND readyState !==4 (readyState = HEADERS_RECEIVED || LOADING) rearm timeout as xhr not finished yet
                        this.requestTimeout = window.setTimeout(this.loadtimeout.bind(this), config.timeout);
                    }
                };
                _proto.loadtimeout = function loadtimeout() {
                    logger1["logger"].warn("timeout while loading " + this.context.url);
                    this.callbacks.onTimeout(this.stats, this.context, null);
                };
                _proto.loadprogress = function loadprogress(event) {
                    var xhr = event.currentTarget, stats = this.stats;
                    stats.loaded = event.loaded;
                    if (event.lengthComputable) stats.total = event.total;
                    var onProgress = this.callbacks.onProgress;
                    if (onProgress) // third arg is to provide on progress data
                    onProgress(stats, this.context, null, xhr);
                };
                return XhrLoader;
            }();
            /* harmony default export */ var xhr_loader = xhr_loader_XhrLoader;
            // CONCATENATED MODULE: ./src/controller/audio-track-controller.js
            function audio_track_controller_defineProperties(target, props) {
                for(var i = 0; i < props.length; i++){
                    var descriptor = props[i];
                    descriptor.enumerable = descriptor.enumerable || false;
                    descriptor.configurable = true;
                    if ("value" in descriptor) descriptor.writable = true;
                    Object.defineProperty(target, descriptor.key, descriptor);
                }
            }
            function audio_track_controller_createClass(Constructor, protoProps, staticProps) {
                if (protoProps) audio_track_controller_defineProperties(Constructor.prototype, protoProps);
                if (staticProps) audio_track_controller_defineProperties(Constructor, staticProps);
                return Constructor;
            }
            function audio_track_controller_inheritsLoose(subClass, superClass) {
                subClass.prototype = Object.create(superClass.prototype);
                subClass.prototype.constructor = subClass;
                subClass.__proto__ = superClass;
            }
            /**
 * @class AudioTrackController
 * @implements {EventHandler}
 *
 * Handles main manifest and audio-track metadata loaded,
 * owns and exposes the selectable audio-tracks data-models.
 *
 * Exposes internal interface to select available audio-tracks.
 *
 * Handles errors on loading audio-track playlists. Manages fallback mechanism
 * with redundants tracks (group-IDs).
 *
 * Handles level-loading and group-ID switches for video (fallback on video levels),
 * and eventually adapts the audio-track group-ID to match.
 *
 * @fires AUDIO_TRACK_LOADING
 * @fires AUDIO_TRACK_SWITCHING
 * @fires AUDIO_TRACKS_UPDATED
 * @fires ERROR
 *
 */ var audio_track_controller_AudioTrackController = /*#__PURE__*/ function(_TaskLoop) {
                audio_track_controller_inheritsLoose(AudioTrackController, _TaskLoop);
                function AudioTrackController(hls) {
                    var _this;
                    _this = _TaskLoop.call(this, hls, events1["default"].MANIFEST_LOADING, events1["default"].MANIFEST_PARSED, events1["default"].AUDIO_TRACK_LOADED, events1["default"].AUDIO_TRACK_SWITCHED, events1["default"].LEVEL_LOADED, events1["default"].ERROR) || this;
                    /**
     * @private
     * Currently selected index in `tracks`
     * @member {number} trackId
     */ _this._trackId = -1;
                    /**
     * @private
     * If should select tracks according to default track attribute
     * @member {boolean} _selectDefaultTrack
     */ _this._selectDefaultTrack = true;
                    /**
     * @public
     * All tracks available
     * @member {AudioTrack[]}
     */ _this.tracks = [];
                    /**
     * @public
     * List of blacklisted audio track IDs (that have caused failure)
     * @member {number[]}
     */ _this.trackIdBlacklist = Object.create(null);
                    /**
     * @public
     * The currently running group ID for audio
     * (we grab this on manifest-parsed and new level-loaded)
     * @member {string}
     */ _this.audioGroupId = null;
                    return _this;
                }
                /**
   * Reset audio tracks on new manifest loading.
   */ var _proto = AudioTrackController.prototype;
                _proto.onManifestLoading = function onManifestLoading() {
                    this.tracks = [];
                    this._trackId = -1;
                    this._selectDefaultTrack = true;
                };
                _proto.onManifestParsed = function onManifestParsed(data) {
                    var tracks = this.tracks = data.audioTracks || [];
                    this.hls.trigger(events1["default"].AUDIO_TRACKS_UPDATED, {
                        audioTracks: tracks
                    });
                    this._selectAudioGroup(this.hls.nextLoadLevel);
                };
                _proto.onAudioTrackLoaded = function onAudioTrackLoaded(data) {
                    if (data.id >= this.tracks.length) {
                        logger1["logger"].warn('Invalid audio track id:', data.id);
                        return;
                    }
                    logger1["logger"].log("audioTrack " + data.id + " loaded");
                    this.tracks[data.id].details = data.details; // check if current playlist is a live playlist
                    // and if we have already our reload interval setup
                    if (data.details.live && !this.hasInterval()) {
                        // if live playlist we will have to reload it periodically
                        // set reload period to playlist target duration
                        var updatePeriodMs = data.details.targetduration * 1000;
                        this.setInterval(updatePeriodMs);
                    }
                    if (!data.details.live && this.hasInterval()) // playlist is not live and timer is scheduled: cancel it
                    this.clearInterval();
                };
                _proto.onAudioTrackSwitched = function onAudioTrackSwitched(data) {
                    var audioGroupId = this.tracks[data.id].groupId;
                    if (audioGroupId && this.audioGroupId !== audioGroupId) this.audioGroupId = audioGroupId;
                };
                _proto.onLevelLoaded = function onLevelLoaded(data) {
                    this._selectAudioGroup(data.level);
                };
                _proto.onError = function onError(data) {
                    // Only handle network errors
                    if (data.type !== errors["ErrorTypes"].NETWORK_ERROR) return;
                     // If fatal network error, cancel update task
                    if (data.fatal) this.clearInterval();
                     // If not an audio-track loading error don't handle further
                    if (data.details !== errors["ErrorDetails"].AUDIO_TRACK_LOAD_ERROR) return;
                    logger1["logger"].warn('Network failure on audio-track id:', data.context.id);
                    this._handleLoadError();
                };
                /**
   * @private
   * @param {number} newId
   */ _proto._setAudioTrack = function _setAudioTrack(newId) {
                    // noop on same audio track id as already set
                    if (this._trackId === newId && this.tracks[this._trackId].details) {
                        logger1["logger"].debug('Same id as current audio-track passed, and track details available -> no-op');
                        return;
                    } // check if level idx is valid
                    if (newId < 0 || newId >= this.tracks.length) {
                        logger1["logger"].warn('Invalid id passed to audio-track controller');
                        return;
                    }
                    var audioTrack = this.tracks[newId];
                    logger1["logger"].log("Now switching to audio-track index " + newId); // stopping live reloading timer if any
                    this.clearInterval();
                    this._trackId = newId;
                    var url = audioTrack.url, type = audioTrack.type, id = audioTrack.id;
                    this.hls.trigger(events1["default"].AUDIO_TRACK_SWITCHING, {
                        id: id,
                        type: type,
                        url: url
                    });
                    this._loadTrackDetailsIfNeeded(audioTrack);
                };
                _proto.doTick = function doTick() {
                    this._updateTrack(this._trackId);
                };
                _proto._selectAudioGroup = function _selectAudioGroup(levelId) {
                    var levelInfo = this.hls.levels[levelId];
                    if (!levelInfo || !levelInfo.audioGroupIds) return;
                    var audioGroupId = levelInfo.audioGroupIds[levelInfo.urlId];
                    if (this.audioGroupId !== audioGroupId) {
                        this.audioGroupId = audioGroupId;
                        this._selectInitialAudioTrack();
                    }
                };
                _proto._selectInitialAudioTrack = function _selectInitialAudioTrack() {
                    var _this2 = this;
                    var tracks = this.tracks;
                    if (!tracks.length) return;
                    var currentAudioTrack = this.tracks[this._trackId];
                    var name = null;
                    if (currentAudioTrack) name = currentAudioTrack.name;
                     // Pre-select default tracks if there are any
                    if (this._selectDefaultTrack) {
                        var defaultTracks = tracks.filter(function(track) {
                            return track.default;
                        });
                        if (defaultTracks.length) tracks = defaultTracks;
                        else logger1["logger"].warn('No default audio tracks defined');
                    }
                    var trackFound = false;
                    var traverseTracks = function traverseTracks() {
                        // Select track with right group ID
                        tracks.forEach(function(track) {
                            if (trackFound) return;
                             // We need to match the (pre-)selected group ID
                            // and the NAME of the current track.
                            if ((!_this2.audioGroupId || track.groupId === _this2.audioGroupId) && (!name || name === track.name)) {
                                // If there was a previous track try to stay with the same `NAME`.
                                // It should be unique across tracks of same group, and consistent through redundant track groups.
                                _this2._setAudioTrack(track.id);
                                trackFound = true;
                            }
                        });
                    };
                    traverseTracks();
                    if (!trackFound) {
                        name = null;
                        traverseTracks();
                    }
                    if (!trackFound) {
                        logger1["logger"].error("No track found for running audio group-ID: " + this.audioGroupId);
                        this.hls.trigger(events1["default"].ERROR, {
                            type: errors["ErrorTypes"].MEDIA_ERROR,
                            details: errors["ErrorDetails"].AUDIO_TRACK_LOAD_ERROR,
                            fatal: true
                        });
                    }
                };
                _proto._needsTrackLoading = function _needsTrackLoading(audioTrack) {
                    var details = audioTrack.details, url = audioTrack.url;
                    if (!details || details.live) // check if we face an audio track embedded in main playlist (audio track without URI attribute)
                    return !!url;
                    return false;
                };
                _proto._loadTrackDetailsIfNeeded = function _loadTrackDetailsIfNeeded(audioTrack) {
                    if (this._needsTrackLoading(audioTrack)) {
                        var url = audioTrack.url, id = audioTrack.id; // track not retrieved yet, or live playlist we need to (re)load it
                        logger1["logger"].log("loading audio-track playlist for id: " + id);
                        this.hls.trigger(events1["default"].AUDIO_TRACK_LOADING, {
                            url: url,
                            id: id
                        });
                    }
                };
                _proto._updateTrack = function _updateTrack(newId) {
                    // check if level idx is valid
                    if (newId < 0 || newId >= this.tracks.length) return;
                     // stopping live reloading timer if any
                    this.clearInterval();
                    this._trackId = newId;
                    logger1["logger"].log("trying to update audio-track " + newId);
                    var audioTrack = this.tracks[newId];
                    this._loadTrackDetailsIfNeeded(audioTrack);
                };
                _proto._handleLoadError = function _handleLoadError() {
                    // First, let's black list current track id
                    this.trackIdBlacklist[this._trackId] = true; // Let's try to fall back on a functional audio-track with the same group ID
                    var previousId = this._trackId;
                    var _this$tracks$previous = this.tracks[previousId], name = _this$tracks$previous.name, language = _this$tracks$previous.language, groupId = _this$tracks$previous.groupId;
                    logger1["logger"].warn("Loading failed on audio track id: " + previousId + ", group-id: " + groupId + ", name/language: \"" + name + "\" / \"" + language + "\""); // Find a non-blacklisted track ID with the same NAME
                    // At least a track that is not blacklisted, thus on another group-ID.
                    var newId = previousId;
                    for(var i = 0; i < this.tracks.length; i++){
                        if (this.trackIdBlacklist[i]) continue;
                        var newTrack = this.tracks[i];
                        if (newTrack.name === name) {
                            newId = i;
                            break;
                        }
                    }
                    if (newId === previousId) {
                        logger1["logger"].warn("No fallback audio-track found for name/language: \"" + name + "\" / \"" + language + "\"");
                        return;
                    }
                    logger1["logger"].log('Attempting audio-track fallback id:', newId, 'group-id:', this.tracks[newId].groupId);
                    this._setAudioTrack(newId);
                };
                audio_track_controller_createClass(AudioTrackController, [
                    {
                        key: "audioTracks",
                        get: function get() {
                            return this.tracks;
                        }
                    },
                    {
                        key: "audioTrack",
                        get: function get() {
                            return this._trackId;
                        },
                        set: function set(newId) {
                            this._setAudioTrack(newId); // If audio track is selected from API then don't choose from the manifest default track
                            this._selectDefaultTrack = false;
                        }
                    }
                ]);
                return AudioTrackController;
            }(TaskLoop1);
            /* harmony default export */ var audio_track_controller = audio_track_controller_AudioTrackController;
            // CONCATENATED MODULE: ./src/controller/audio-stream-controller.js
            function audio_stream_controller_defineProperties(target, props) {
                for(var i = 0; i < props.length; i++){
                    var descriptor = props[i];
                    descriptor.enumerable = descriptor.enumerable || false;
                    descriptor.configurable = true;
                    if ("value" in descriptor) descriptor.writable = true;
                    Object.defineProperty(target, descriptor.key, descriptor);
                }
            }
            function audio_stream_controller_createClass(Constructor, protoProps, staticProps) {
                if (protoProps) audio_stream_controller_defineProperties(Constructor.prototype, protoProps);
                if (staticProps) audio_stream_controller_defineProperties(Constructor, staticProps);
                return Constructor;
            }
            function audio_stream_controller_inheritsLoose(subClass, superClass) {
                subClass.prototype = Object.create(superClass.prototype);
                subClass.prototype.constructor = subClass;
                subClass.__proto__ = superClass;
            }
            /*
 * Audio Stream Controller
*/ var audio_stream_controller_window = window, audio_stream_controller_performance = audio_stream_controller_window.performance;
            var audio_stream_controller_TICK_INTERVAL = 100; // how often to tick in ms
            var audio_stream_controller_AudioStreamController = /*#__PURE__*/ function(_BaseStreamController) {
                audio_stream_controller_inheritsLoose(AudioStreamController, _BaseStreamController);
                function AudioStreamController(hls, fragmentTracker) {
                    var _this;
                    _this = _BaseStreamController.call(this, hls, events1["default"].MEDIA_ATTACHED, events1["default"].MEDIA_DETACHING, events1["default"].AUDIO_TRACKS_UPDATED, events1["default"].AUDIO_TRACK_SWITCHING, events1["default"].AUDIO_TRACK_LOADED, events1["default"].KEY_LOADED, events1["default"].FRAG_LOADED, events1["default"].FRAG_PARSING_INIT_SEGMENT, events1["default"].FRAG_PARSING_DATA, events1["default"].FRAG_PARSED, events1["default"].ERROR, events1["default"].BUFFER_RESET, events1["default"].BUFFER_CREATED, events1["default"].BUFFER_APPENDED, events1["default"].BUFFER_FLUSHED, events1["default"].INIT_PTS_FOUND) || this;
                    _this.fragmentTracker = fragmentTracker;
                    _this.config = hls.config;
                    _this.audioCodecSwap = false;
                    _this._state = State.STOPPED;
                    _this.initPTS = [];
                    _this.waitingFragment = null;
                    _this.videoTrackCC = null;
                    _this.waitingVideoCC = null;
                    return _this;
                } // Signal that video PTS was found
                var _proto = AudioStreamController.prototype;
                _proto.onInitPtsFound = function onInitPtsFound(data) {
                    var demuxerId = data.id, cc = data.frag.cc, initPTS = data.initPTS;
                    if (demuxerId === 'main') {
                        // Always update the new INIT PTS
                        // Can change due level switch
                        this.initPTS[cc] = initPTS;
                        this.videoTrackCC = cc;
                        logger1["logger"].log("InitPTS for cc: " + cc + " found from main: " + initPTS); // If we are waiting we need to demux/remux the waiting frag
                        // With the new initPTS
                        if (this.state === State.WAITING_INIT_PTS) this.tick();
                    }
                };
                _proto.startLoad = function startLoad(startPosition) {
                    if (this.tracks) {
                        var lastCurrentTime = this.lastCurrentTime;
                        this.stopLoad();
                        this.setInterval(audio_stream_controller_TICK_INTERVAL);
                        this.fragLoadError = 0;
                        if (lastCurrentTime > 0 && startPosition === -1) {
                            logger1["logger"].log("audio:override startPosition with lastCurrentTime @" + lastCurrentTime.toFixed(3));
                            this.state = State.IDLE;
                        } else {
                            this.lastCurrentTime = this.startPosition ? this.startPosition : startPosition;
                            this.state = State.STARTING;
                        }
                        this.nextLoadPosition = this.startPosition = this.lastCurrentTime;
                        this.tick();
                    } else {
                        this.startPosition = startPosition;
                        this.state = State.STOPPED;
                    }
                };
                _proto.doTick = function doTick() {
                    var pos, track, trackDetails, hls = this.hls, config = hls.config; // logger.log('audioStream:' + this.state);
                    switch(this.state){
                        case State.ERROR:
                        case State.PAUSED:
                        case State.BUFFER_FLUSHING:
                            break;
                        case State.STARTING:
                            this.state = State.WAITING_TRACK;
                            this.loadedmetadata = false;
                            break;
                        case State.IDLE:
                            var tracks = this.tracks; // audio tracks not received => exit loop
                            if (!tracks) break;
                             // if video not attached AND
                            // start fragment already requested OR start frag prefetch disable
                            // exit loop
                            // => if media not attached but start frag prefetch is enabled and start frag not requested yet, we will not exit loop
                            if (!this.media && (this.startFragRequested || !config.startFragPrefetch)) break;
                             // determine next candidate fragment to be loaded, based on current position and
                            //  end of buffer position
                            // if we have not yet loaded any fragment, start loading from start position
                            if (this.loadedmetadata) pos = this.media.currentTime;
                            else {
                                pos = this.nextLoadPosition;
                                if (pos === undefined) break;
                            }
                            var media = this.mediaBuffer ? this.mediaBuffer : this.media;
                            var videoBuffer = this.videoBuffer ? this.videoBuffer : this.media;
                            var maxBufferHole = pos < config.maxBufferHole ? Math.max(MAX_START_GAP_JUMP, config.maxBufferHole) : config.maxBufferHole;
                            var bufferInfo = BufferHelper1.bufferInfo(media, pos, maxBufferHole);
                            var mainBufferInfo = BufferHelper1.bufferInfo(videoBuffer, pos, maxBufferHole);
                            var bufferLen = bufferInfo.len;
                            var bufferEnd = bufferInfo.end;
                            var fragPrevious = this.fragPrevious; // ensure we buffer at least config.maxBufferLength (default 30s) or config.maxMaxBufferLength (default: 600s)
                            // whichever is smaller.
                            // once we reach that threshold, don't buffer more than video (mainBufferInfo.len)
                            var maxConfigBuffer = Math.min(config.maxBufferLength, config.maxMaxBufferLength);
                            var maxBufLen = Math.max(maxConfigBuffer, mainBufferInfo.len);
                            var audioSwitch = this.audioSwitch;
                            var trackId = this.trackId; // if buffer length is less than maxBufLen try to load a new fragment
                            if ((bufferLen < maxBufLen || audioSwitch) && trackId < tracks.length) {
                                trackDetails = tracks[trackId].details; // if track info not retrieved yet, switch state and wait for track retrieval
                                if (typeof trackDetails === 'undefined') {
                                    this.state = State.WAITING_TRACK;
                                    break;
                                }
                                if (!audioSwitch && this._streamEnded(bufferInfo, trackDetails)) {
                                    this.hls.trigger(events1["default"].BUFFER_EOS, {
                                        type: 'audio'
                                    });
                                    this.state = State.ENDED;
                                    return;
                                } // find fragment index, contiguous with end of buffer position
                                var fragments = trackDetails.fragments, fragLen = fragments.length, start = fragments[0].start, end = fragments[fragLen - 1].start + fragments[fragLen - 1].duration, frag3; // When switching audio track, reload audio as close as possible to currentTime
                                if (audioSwitch) {
                                    if (trackDetails.live && !trackDetails.PTSKnown) {
                                        logger1["logger"].log('switching audiotrack, live stream, unknown PTS,load first fragment');
                                        bufferEnd = 0;
                                    } else {
                                        bufferEnd = pos; // if currentTime (pos) is less than alt audio playlist start time, it means that alt audio is ahead of currentTime
                                        if (trackDetails.PTSKnown && pos < start) {
                                            // if everything is buffered from pos to start or if audio buffer upfront, let's seek to start
                                            if (bufferInfo.end > start || bufferInfo.nextStart) {
                                                logger1["logger"].log('alt audio track ahead of main track, seek to start of alt audio track');
                                                this.media.currentTime = start + 0.05;
                                            } else return;
                                        }
                                    }
                                }
                                if (trackDetails.initSegment && !trackDetails.initSegment.data) frag3 = trackDetails.initSegment;
                                else if (bufferEnd <= start) {
                                    frag3 = fragments[0];
                                    if (this.videoTrackCC !== null && frag3.cc !== this.videoTrackCC) // Ensure we find a fragment which matches the continuity of the video track
                                    frag3 = findFragWithCC(fragments, this.videoTrackCC);
                                    if (trackDetails.live && frag3.loadIdx && frag3.loadIdx === this.fragLoadIdx) {
                                        // we just loaded this first fragment, and we are still lagging behind the start of the live playlist
                                        // let's force seek to start
                                        var nextBuffered = bufferInfo.nextStart ? bufferInfo.nextStart : start;
                                        logger1["logger"].log("no alt audio available @currentTime:" + this.media.currentTime + ", seeking @" + (nextBuffered + 0.05));
                                        this.media.currentTime = nextBuffered + 0.05;
                                        return;
                                    }
                                } else {
                                    var foundFrag;
                                    var maxFragLookUpTolerance = config.maxFragLookUpTolerance;
                                    var fragNext = fragPrevious ? fragments[fragPrevious.sn - fragments[0].sn + 1] : undefined;
                                    if (bufferEnd < end) {
                                        if (bufferEnd > end - maxFragLookUpTolerance) maxFragLookUpTolerance = 0;
                                         // Prefer the next fragment if it's within tolerance
                                        if (fragNext && !fragmentWithinToleranceTest(bufferEnd, maxFragLookUpTolerance, fragNext)) foundFrag = fragNext;
                                        else foundFrag = binary_search.search(fragments, function(frag) {
                                            return fragmentWithinToleranceTest(bufferEnd, maxFragLookUpTolerance, frag);
                                        });
                                    } else // reach end of playlist
                                    foundFrag = fragments[fragLen - 1];
                                    if (foundFrag) {
                                        frag3 = foundFrag;
                                        start = foundFrag.start; // logger.log('find SN matching with pos:' +  bufferEnd + ':' + frag.sn);
                                        if (fragPrevious && frag3.level === fragPrevious.level && frag3.sn === fragPrevious.sn) {
                                            if (frag3.sn < trackDetails.endSN) {
                                                frag3 = fragments[frag3.sn + 1 - trackDetails.startSN];
                                                if (this.fragmentTracker.getState(frag3) !== FragmentState.OK) logger1["logger"].log("SN just loaded, load next one: " + frag3.sn);
                                            } else frag3 = null;
                                        }
                                    }
                                }
                                if (frag3) {
                                    // logger.log('      loading frag ' + i +',pos/bufEnd:' + pos.toFixed(3) + '/' + bufferEnd.toFixed(3));
                                    if (frag3.encrypted) {
                                        logger1["logger"].log("Loading key for " + frag3.sn + " of [" + trackDetails.startSN + " ," + trackDetails.endSN + "],track " + trackId);
                                        this.state = State.KEY_LOADING;
                                        hls.trigger(events1["default"].KEY_LOADING, {
                                            frag: frag3
                                        });
                                    } else {
                                        // only load if fragment is not loaded or if in audio switch
                                        // we force a frag loading in audio switch as fragment tracker might not have evicted previous frags in case of quick audio switch
                                        this.fragCurrent = frag3;
                                        if (audioSwitch || this.fragmentTracker.getState(frag3) === FragmentState.NOT_LOADED) {
                                            logger1["logger"].log("Loading " + frag3.sn + ", cc: " + frag3.cc + " of [" + trackDetails.startSN + " ," + trackDetails.endSN + "],track " + trackId + ", " + (this.loadedmetadata ? 'currentTime' : 'nextLoadPosition') + ": " + pos + ", bufferEnd: " + bufferEnd.toFixed(3));
                                            if (frag3.sn !== 'initSegment') this.startFragRequested = true;
                                            if (Object(number["isFiniteNumber"])(frag3.sn)) this.nextLoadPosition = frag3.start + frag3.duration;
                                            hls.trigger(events1["default"].FRAG_LOADING, {
                                                frag: frag3
                                            });
                                            this.state = State.FRAG_LOADING;
                                        }
                                    }
                                }
                            }
                            break;
                        case State.WAITING_TRACK:
                            track = this.tracks[this.trackId]; // check if playlist is already loaded
                            if (track && track.details) this.state = State.IDLE;
                            break;
                        case State.FRAG_LOADING_WAITING_RETRY:
                            var now = audio_stream_controller_performance.now();
                            var retryDate = this.retryDate;
                            media = this.media;
                            var isSeeking = media && media.seeking; // if current time is gt than retryDate, or if media seeking let's switch to IDLE state to retry loading
                            if (!retryDate || now >= retryDate || isSeeking) {
                                logger1["logger"].log('audioStreamController: retryDate reached, switch back to IDLE state');
                                this.state = State.IDLE;
                            }
                            break;
                        case State.WAITING_INIT_PTS:
                            // Ensure we don't get stuck in the WAITING_INIT_PTS state if the waiting frag CC doesn't match any initPTS
                            var waitingFrag = this.waitingFragment;
                            if (waitingFrag) {
                                var waitingFragCC = waitingFrag.frag.cc;
                                if (this.initPTS[waitingFragCC] !== undefined) {
                                    this.waitingFragment = null;
                                    this.state = State.FRAG_LOADING;
                                    this.onFragLoaded(waitingFrag);
                                } else if (this.videoTrackCC !== this.waitingVideoCC) {
                                    // Drop waiting fragment if videoTrackCC has changed since waitingFragment was set and initPTS was not found
                                    logger1["logger"].log("Waiting fragment cc (" + waitingFragCC + ") cancelled because video is at cc " + this.videoTrackCC);
                                    this.clearWaitingFragment();
                                } else {
                                    // Drop waiting fragment if an earlier fragment is needed
                                    var _bufferInfo = BufferHelper1.bufferInfo(this.mediaBuffer, this.media.currentTime, config.maxBufferHole);
                                    var waitingFragmentAtPosition = fragmentWithinToleranceTest(_bufferInfo.end, config.maxFragLookUpTolerance, waitingFrag.frag);
                                    if (waitingFragmentAtPosition < 0) {
                                        logger1["logger"].log("Waiting fragment cc (" + waitingFragCC + ") @ " + waitingFrag.frag.start + " cancelled because another fragment at " + _bufferInfo.end + " is needed");
                                        this.clearWaitingFragment();
                                    }
                                }
                            } else this.state = State.IDLE;
                            break;
                        case State.STOPPED:
                        case State.FRAG_LOADING:
                        case State.PARSING:
                        case State.PARSED:
                        case State.ENDED:
                            break;
                        default:
                            break;
                    }
                };
                _proto.clearWaitingFragment = function clearWaitingFragment() {
                    var waitingFrag = this.waitingFragment;
                    if (waitingFrag) {
                        this.fragmentTracker.removeFragment(waitingFrag.frag);
                        this.waitingFragment = null;
                        this.waitingVideoCC = null;
                        this.state = State.IDLE;
                    }
                };
                _proto.onMediaAttached = function onMediaAttached(data) {
                    var media = this.media = this.mediaBuffer = data.media;
                    this.onvseeking = this.onMediaSeeking.bind(this);
                    this.onvended = this.onMediaEnded.bind(this);
                    media.addEventListener('seeking', this.onvseeking);
                    media.addEventListener('ended', this.onvended);
                    var config = this.config;
                    if (this.tracks && config.autoStartLoad) this.startLoad(config.startPosition);
                };
                _proto.onMediaDetaching = function onMediaDetaching() {
                    var media = this.media;
                    if (media && media.ended) {
                        logger1["logger"].log('MSE detaching and video ended, reset startPosition');
                        this.startPosition = this.lastCurrentTime = 0;
                    } // remove video listeners
                    if (media) {
                        media.removeEventListener('seeking', this.onvseeking);
                        media.removeEventListener('ended', this.onvended);
                        this.onvseeking = this.onvseeked = this.onvended = null;
                    }
                    this.media = this.mediaBuffer = this.videoBuffer = null;
                    this.loadedmetadata = false;
                    this.fragmentTracker.removeAllFragments();
                    this.stopLoad();
                };
                _proto.onAudioTracksUpdated = function onAudioTracksUpdated(data) {
                    logger1["logger"].log('audio tracks updated');
                    this.tracks = data.audioTracks;
                };
                _proto.onAudioTrackSwitching = function onAudioTrackSwitching(data) {
                    // if any URL found on new audio track, it is an alternate audio track
                    var altAudio = !!data.url;
                    this.trackId = data.id;
                    this.fragCurrent = null;
                    this.clearWaitingFragment();
                    this.state = State.PAUSED; // destroy useless demuxer when switching audio to main
                    if (!altAudio) {
                        if (this.demuxer) {
                            this.demuxer.destroy();
                            this.demuxer = null;
                        }
                    } else // switching to audio track, start timer if not already started
                    this.setInterval(audio_stream_controller_TICK_INTERVAL);
                     // should we switch tracks ?
                    if (altAudio) {
                        this.audioSwitch = true; // main audio track are handled by stream-controller, just do something if switching to alt audio track
                        this.state = State.IDLE;
                    }
                    this.tick();
                };
                _proto.onAudioTrackLoaded = function onAudioTrackLoaded(data) {
                    var newDetails = data.details, trackId = data.id, track = this.tracks[trackId], curDetails = track.details, duration = newDetails.totalduration, sliding = 0;
                    logger1["logger"].log("track " + trackId + " loaded [" + newDetails.startSN + "," + newDetails.endSN + "],duration:" + duration);
                    if (newDetails.live || curDetails && curDetails.live) {
                        if (curDetails && newDetails.fragments.length > 0) {
                            // we already have details for that level, merge them
                            mergeDetails(curDetails, newDetails);
                            sliding = newDetails.fragments[0].start; // TODO
                            // this.liveSyncPosition = this.computeLivePosition(sliding, curDetails);
                            if (newDetails.PTSKnown) logger1["logger"].log("live audio playlist sliding:" + sliding.toFixed(3));
                            else logger1["logger"].log('live audio playlist - outdated PTS, unknown sliding');
                        } else {
                            newDetails.PTSKnown = false;
                            logger1["logger"].log('live audio playlist - first load, unknown sliding');
                        }
                    } else newDetails.PTSKnown = false;
                    track.details = newDetails; // compute start position
                    if (!this.startFragRequested) {
                        // compute start position if set to -1. use it straight away if value is defined
                        if (this.startPosition === -1) {
                            // first, check if start time offset has been set in playlist, if yes, use this value
                            var startTimeOffset = newDetails.startTimeOffset;
                            if (Object(number["isFiniteNumber"])(startTimeOffset)) {
                                logger1["logger"].log("start time offset found in playlist, adjust startPosition to " + startTimeOffset);
                                this.startPosition = startTimeOffset;
                            } else if (newDetails.live) {
                                this.startPosition = this.computeLivePosition(sliding, newDetails);
                                logger1["logger"].log("compute startPosition for audio-track to " + this.startPosition);
                            } else this.startPosition = 0;
                        }
                        this.nextLoadPosition = this.startPosition;
                    } // only switch batck to IDLE state if we were waiting for track to start downloading a new fragment
                    if (this.state === State.WAITING_TRACK) this.state = State.IDLE;
                     // trigger handler right now
                    this.tick();
                };
                _proto.onKeyLoaded = function onKeyLoaded() {
                    if (this.state === State.KEY_LOADING) {
                        this.state = State.IDLE;
                        this.tick();
                    }
                };
                _proto.onFragLoaded = function onFragLoaded(data) {
                    var fragCurrent = this.fragCurrent, fragLoaded = data.frag;
                    if (this.state === State.FRAG_LOADING && fragCurrent && fragLoaded.type === 'audio' && fragLoaded.level === fragCurrent.level && fragLoaded.sn === fragCurrent.sn) {
                        var track = this.tracks[this.trackId], details = track.details, duration = details.totalduration, trackId = fragCurrent.level, sn = fragCurrent.sn, cc = fragCurrent.cc, audioCodec = this.config.defaultAudioCodec || track.audioCodec || 'mp4a.40.2', stats = this.stats = data.stats;
                        if (sn === 'initSegment') {
                            this.state = State.IDLE;
                            stats.tparsed = stats.tbuffered = audio_stream_controller_performance.now();
                            details.initSegment.data = data.payload;
                            this.hls.trigger(events1["default"].FRAG_BUFFERED, {
                                stats: stats,
                                frag: fragCurrent,
                                id: 'audio'
                            });
                            this.tick();
                        } else {
                            this.state = State.PARSING; // transmux the MPEG-TS data to ISO-BMFF segments
                            this.appended = false;
                            if (!this.demuxer) this.demuxer = new demux_demuxer(this.hls, 'audio');
                             // Check if we have video initPTS
                            // If not we need to wait for it
                            var initPTS = this.initPTS[cc];
                            var initSegmentData = details.initSegment ? details.initSegment.data : [];
                            if (initPTS !== undefined) {
                                this.pendingBuffering = true;
                                logger1["logger"].log("Demuxing " + sn + " of [" + details.startSN + " ," + details.endSN + "],track " + trackId); // time Offset is accurate if level PTS is known, or if playlist is not sliding (not live)
                                var accurateTimeOffset = false; // details.PTSKnown || !details.live;
                                this.demuxer.push(data.payload, initSegmentData, audioCodec, null, fragCurrent, duration, accurateTimeOffset, initPTS);
                            } else {
                                logger1["logger"].log("Unknown video PTS for cc " + cc + ", waiting for video PTS before demuxing audio frag " + sn + " of [" + details.startSN + " ," + details.endSN + "],track " + trackId);
                                this.waitingFragment = data;
                                this.waitingVideoCC = this.videoTrackCC;
                                this.state = State.WAITING_INIT_PTS;
                            }
                        }
                    }
                    this.fragLoadError = 0;
                };
                _proto.onFragParsingInitSegment = function onFragParsingInitSegment(data) {
                    var fragCurrent = this.fragCurrent;
                    var fragNew = data.frag;
                    if (fragCurrent && data.id === 'audio' && fragNew.sn === fragCurrent.sn && fragNew.level === fragCurrent.level && this.state === State.PARSING) {
                        var tracks = data.tracks, track; // delete any video track found on audio demuxer
                        if (tracks.video) delete tracks.video;
                         // include levelCodec in audio and video tracks
                        track = tracks.audio;
                        if (track) {
                            track.levelCodec = track.codec;
                            track.id = data.id;
                            this.hls.trigger(events1["default"].BUFFER_CODECS, tracks);
                            logger1["logger"].log("audio track:audio,container:" + track.container + ",codecs[level/parsed]=[" + track.levelCodec + "/" + track.codec + "]");
                            var initSegment = track.initSegment;
                            if (initSegment) {
                                var appendObj = {
                                    type: 'audio',
                                    data: initSegment,
                                    parent: 'audio',
                                    content: 'initSegment'
                                };
                                if (this.audioSwitch) this.pendingData = [
                                    appendObj
                                ];
                                else {
                                    this.appended = true; // arm pending Buffering flag before appending a segment
                                    this.pendingBuffering = true;
                                    this.hls.trigger(events1["default"].BUFFER_APPENDING, appendObj);
                                }
                            } // trigger handler right now
                            this.tick();
                        }
                    }
                };
                _proto.onFragParsingData = function onFragParsingData(data) {
                    var _this2 = this;
                    var fragCurrent = this.fragCurrent;
                    var fragNew = data.frag;
                    if (fragCurrent && data.id === 'audio' && data.type === 'audio' && fragNew.sn === fragCurrent.sn && fragNew.level === fragCurrent.level && this.state === State.PARSING) {
                        var trackId = this.trackId, track = this.tracks[trackId], hls = this.hls;
                        if (!Object(number["isFiniteNumber"])(data.endPTS)) {
                            data.endPTS = data.startPTS + fragCurrent.duration;
                            data.endDTS = data.startDTS + fragCurrent.duration;
                        }
                        fragCurrent.addElementaryStream(ElementaryStreamTypes1.AUDIO);
                        logger1["logger"].log("parsed " + data.type + ",PTS:[" + data.startPTS.toFixed(3) + "," + data.endPTS.toFixed(3) + "],DTS:[" + data.startDTS.toFixed(3) + "/" + data.endDTS.toFixed(3) + "],nb:" + data.nb);
                        updateFragPTSDTS(track.details, fragCurrent, data.startPTS, data.endPTS);
                        var media = this.media;
                        var appendOnBufferFlush = false; // Only flush audio from old audio tracks when PTS is known on new audio track
                        if (this.audioSwitch) {
                            if (media && media.readyState) {
                                var currentTime = media.currentTime;
                                logger1["logger"].log('switching audio track : currentTime:' + currentTime);
                                if (currentTime >= data.startPTS) {
                                    logger1["logger"].log('switching audio track : flushing all audio');
                                    this.state = State.BUFFER_FLUSHING;
                                    hls.trigger(events1["default"].BUFFER_FLUSHING, {
                                        startOffset: 0,
                                        endOffset: Number.POSITIVE_INFINITY,
                                        type: 'audio'
                                    });
                                    appendOnBufferFlush = true; // Lets announce that the initial audio track switch flush occur
                                    this.audioSwitch = false;
                                    hls.trigger(events1["default"].AUDIO_TRACK_SWITCHED, {
                                        id: trackId
                                    });
                                }
                            } else {
                                // Lets announce that the initial audio track switch flush occur
                                this.audioSwitch = false;
                                hls.trigger(events1["default"].AUDIO_TRACK_SWITCHED, {
                                    id: trackId
                                });
                            }
                        }
                        var pendingData = this.pendingData;
                        if (!pendingData) {
                            logger1["logger"].warn('Apparently attempt to enqueue media payload without codec initialization data upfront');
                            hls.trigger(events1["default"].ERROR, {
                                type: errors["ErrorTypes"].MEDIA_ERROR,
                                details: null,
                                fatal: true
                            });
                            return;
                        }
                        if (!this.audioSwitch) {
                            [
                                data.data1,
                                data.data2
                            ].forEach(function(buffer) {
                                if (buffer && buffer.length) pendingData.push({
                                    type: data.type,
                                    data: buffer,
                                    parent: 'audio',
                                    content: 'data'
                                });
                            });
                            if (!appendOnBufferFlush && pendingData.length) {
                                pendingData.forEach(function(appendObj) {
                                    // only append in PARSING state (rationale is that an appending error could happen synchronously on first segment appending)
                                    // in that case it is useless to append following segments
                                    if (_this2.state === State.PARSING) {
                                        // arm pending Buffering flag before appending a segment
                                        _this2.pendingBuffering = true;
                                        _this2.hls.trigger(events1["default"].BUFFER_APPENDING, appendObj);
                                    }
                                });
                                this.pendingData = [];
                                this.appended = true;
                            }
                        } // trigger handler right now
                        this.tick();
                    }
                };
                _proto.onFragParsed = function onFragParsed(data) {
                    var fragCurrent = this.fragCurrent;
                    var fragNew = data.frag;
                    if (fragCurrent && data.id === 'audio' && fragNew.sn === fragCurrent.sn && fragNew.level === fragCurrent.level && this.state === State.PARSING) {
                        this.stats.tparsed = audio_stream_controller_performance.now();
                        this.state = State.PARSED;
                        this._checkAppendedParsed();
                    }
                };
                _proto.onBufferReset = function onBufferReset() {
                    // reset reference to sourcebuffers
                    this.mediaBuffer = this.videoBuffer = null;
                    this.loadedmetadata = false;
                };
                _proto.onBufferCreated = function onBufferCreated(data) {
                    var audioTrack = data.tracks.audio;
                    if (audioTrack) {
                        this.mediaBuffer = audioTrack.buffer;
                        this.loadedmetadata = true;
                    }
                    if (data.tracks.video) this.videoBuffer = data.tracks.video.buffer;
                };
                _proto.onBufferAppended = function onBufferAppended(data) {
                    if (data.parent === 'audio') {
                        var state = this.state;
                        if (state === State.PARSING || state === State.PARSED) {
                            // check if all buffers have been appended
                            this.pendingBuffering = data.pending > 0;
                            this._checkAppendedParsed();
                        }
                    }
                };
                _proto._checkAppendedParsed = function _checkAppendedParsed() {
                    // trigger handler right now
                    if (this.state === State.PARSED && (!this.appended || !this.pendingBuffering)) {
                        var frag = this.fragCurrent, stats = this.stats, hls = this.hls;
                        if (frag) {
                            this.fragPrevious = frag;
                            stats.tbuffered = audio_stream_controller_performance.now();
                            hls.trigger(events1["default"].FRAG_BUFFERED, {
                                stats: stats,
                                frag: frag,
                                id: 'audio'
                            });
                            var media = this.mediaBuffer ? this.mediaBuffer : this.media;
                            if (media) logger1["logger"].log("audio buffered : " + time_ranges.toString(media.buffered));
                            if (this.audioSwitch && this.appended) {
                                this.audioSwitch = false;
                                hls.trigger(events1["default"].AUDIO_TRACK_SWITCHED, {
                                    id: this.trackId
                                });
                            }
                            this.state = State.IDLE;
                        }
                        this.tick();
                    }
                };
                _proto.onError = function onError(data) {
                    var frag = data.frag; // don't handle frag error not related to audio fragment
                    if (frag && frag.type !== 'audio') return;
                    switch(data.details){
                        case errors["ErrorDetails"].FRAG_LOAD_ERROR:
                        case errors["ErrorDetails"].FRAG_LOAD_TIMEOUT:
                            var _frag = data.frag; // don't handle frag error not related to audio fragment
                            if (_frag && _frag.type !== 'audio') break;
                            if (!data.fatal) {
                                var loadError = this.fragLoadError;
                                if (loadError) loadError++;
                                else loadError = 1;
                                var config = this.config;
                                if (loadError <= config.fragLoadingMaxRetry) {
                                    this.fragLoadError = loadError; // exponential backoff capped to config.fragLoadingMaxRetryTimeout
                                    var delay = Math.min(Math.pow(2, loadError - 1) * config.fragLoadingRetryDelay, config.fragLoadingMaxRetryTimeout);
                                    logger1["logger"].warn("AudioStreamController: frag loading failed, retry in " + delay + " ms");
                                    this.retryDate = audio_stream_controller_performance.now() + delay; // retry loading state
                                    this.state = State.FRAG_LOADING_WAITING_RETRY;
                                } else {
                                    logger1["logger"].error("AudioStreamController: " + data.details + " reaches max retry, redispatch as fatal ..."); // switch error to fatal
                                    data.fatal = true;
                                    this.state = State.ERROR;
                                }
                            }
                            break;
                        case errors["ErrorDetails"].AUDIO_TRACK_LOAD_ERROR:
                        case errors["ErrorDetails"].AUDIO_TRACK_LOAD_TIMEOUT:
                        case errors["ErrorDetails"].KEY_LOAD_ERROR:
                        case errors["ErrorDetails"].KEY_LOAD_TIMEOUT:
                            //  when in ERROR state, don't switch back to IDLE state in case a non-fatal error is received
                            if (this.state !== State.ERROR) {
                                // if fatal error, stop processing, otherwise move to IDLE to retry loading
                                this.state = data.fatal ? State.ERROR : State.IDLE;
                                logger1["logger"].warn("AudioStreamController: " + data.details + " while loading frag, now switching to " + this.state + " state ...");
                            }
                            break;
                        case errors["ErrorDetails"].BUFFER_FULL_ERROR:
                            // if in appending state
                            if (data.parent === 'audio' && (this.state === State.PARSING || this.state === State.PARSED)) {
                                var media = this.mediaBuffer, currentTime = this.media.currentTime, mediaBuffered = media && BufferHelper1.isBuffered(media, currentTime) && BufferHelper1.isBuffered(media, currentTime + 0.5); // reduce max buf len if current position is buffered
                                if (mediaBuffered) {
                                    var _config = this.config;
                                    if (_config.maxMaxBufferLength >= _config.maxBufferLength) {
                                        // reduce max buffer length as it might be too high. we do this to avoid loop flushing ...
                                        _config.maxMaxBufferLength /= 2;
                                        logger1["logger"].warn("AudioStreamController: reduce max buffer length to " + _config.maxMaxBufferLength + "s");
                                    }
                                    this.state = State.IDLE;
                                } else {
                                    // current position is not buffered, but browser is still complaining about buffer full error
                                    // this happens on IE/Edge, refer to https://github.com/video-dev/hls.js/pull/708
                                    // in that case flush the whole audio buffer to recover
                                    logger1["logger"].warn('AudioStreamController: buffer full error also media.currentTime is not buffered, flush audio buffer');
                                    this.fragCurrent = null; // flush everything
                                    this.state = State.BUFFER_FLUSHING;
                                    this.hls.trigger(events1["default"].BUFFER_FLUSHING, {
                                        startOffset: 0,
                                        endOffset: Number.POSITIVE_INFINITY,
                                        type: 'audio'
                                    });
                                }
                            }
                            break;
                        default:
                            break;
                    }
                };
                _proto.onBufferFlushed = function onBufferFlushed() {
                    var _this3 = this;
                    var pendingData = this.pendingData;
                    if (pendingData && pendingData.length) {
                        logger1["logger"].log('AudioStreamController: appending pending audio data after buffer flushed');
                        pendingData.forEach(function(appendObj) {
                            _this3.hls.trigger(events1["default"].BUFFER_APPENDING, appendObj);
                        });
                        this.appended = true;
                        this.pendingData = [];
                        this.state = State.PARSED;
                    } else {
                        // move to IDLE once flush complete. this should trigger new fragment loading
                        this.state = State.IDLE; // reset reference to frag
                        this.fragPrevious = null;
                        this.tick();
                    }
                };
                audio_stream_controller_createClass(AudioStreamController, [
                    {
                        key: "state",
                        set: function set(nextState) {
                            if (this.state !== nextState) {
                                var previousState = this.state;
                                this._state = nextState;
                                logger1["logger"].log("audio stream:" + previousState + "->" + nextState);
                            }
                        },
                        get: function get() {
                            return this._state;
                        }
                    }
                ]);
                return AudioStreamController;
            }(base_stream_controller_BaseStreamController);
            /* harmony default export */ var audio_stream_controller = audio_stream_controller_AudioStreamController;
            // CONCATENATED MODULE: ./src/utils/vttcue.js
            /**
 * Copyright 2013 vtt.js Contributors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */ /* harmony default export */ var vttcue = function() {
                if (typeof window !== 'undefined' && window.VTTCue) return window.VTTCue;
                var autoKeyword = 'auto';
                var directionSetting = {
                    '': true,
                    lr: true,
                    rl: true
                };
                var alignSetting = {
                    start: true,
                    middle: true,
                    end: true,
                    left: true,
                    right: true
                };
                function findDirectionSetting(value) {
                    if (typeof value !== 'string') return false;
                    var dir = directionSetting[value.toLowerCase()];
                    return dir ? value.toLowerCase() : false;
                }
                function findAlignSetting(value) {
                    if (typeof value !== 'string') return false;
                    var align = alignSetting[value.toLowerCase()];
                    return align ? value.toLowerCase() : false;
                }
                function extend(obj) {
                    var i = 1;
                    for(; i < arguments.length; i++){
                        var cobj = arguments[i];
                        for(var p in cobj)obj[p] = cobj[p];
                    }
                    return obj;
                }
                function VTTCue(startTime, endTime, text) {
                    var cue = this;
                    var baseObj = {
                    };
                    baseObj.enumerable = true;
                    /**
     * Shim implementation specific properties. These properties are not in
     * the spec.
     */ // Lets us know when the VTTCue's data has changed in such a way that we need
                    // to recompute its display state. This lets us compute its display state
                    // lazily.
                    cue.hasBeenReset = false;
                    /**
     * VTTCue and TextTrackCue properties
     * http://dev.w3.org/html5/webvtt/#vttcue-interface
     */ var _id = '';
                    var _pauseOnExit = false;
                    var _startTime = startTime;
                    var _endTime = endTime;
                    var _text = text;
                    var _region = null;
                    var _vertical = '';
                    var _snapToLines = true;
                    var _line = 'auto';
                    var _lineAlign = 'start';
                    var _position = 50;
                    var _positionAlign = 'middle';
                    var _size = 50;
                    var _align = 'middle';
                    Object.defineProperty(cue, 'id', extend({
                    }, baseObj, {
                        get: function get() {
                            return _id;
                        },
                        set: function set(value) {
                            _id = '' + value;
                        }
                    }));
                    Object.defineProperty(cue, 'pauseOnExit', extend({
                    }, baseObj, {
                        get: function get() {
                            return _pauseOnExit;
                        },
                        set: function set(value) {
                            _pauseOnExit = !!value;
                        }
                    }));
                    Object.defineProperty(cue, 'startTime', extend({
                    }, baseObj, {
                        get: function get() {
                            return _startTime;
                        },
                        set: function set(value) {
                            if (typeof value !== 'number') throw new TypeError('Start time must be set to a number.');
                            _startTime = value;
                            this.hasBeenReset = true;
                        }
                    }));
                    Object.defineProperty(cue, 'endTime', extend({
                    }, baseObj, {
                        get: function get() {
                            return _endTime;
                        },
                        set: function set(value) {
                            if (typeof value !== 'number') throw new TypeError('End time must be set to a number.');
                            _endTime = value;
                            this.hasBeenReset = true;
                        }
                    }));
                    Object.defineProperty(cue, 'text', extend({
                    }, baseObj, {
                        get: function get() {
                            return _text;
                        },
                        set: function set(value) {
                            _text = '' + value;
                            this.hasBeenReset = true;
                        }
                    }));
                    Object.defineProperty(cue, 'region', extend({
                    }, baseObj, {
                        get: function get() {
                            return _region;
                        },
                        set: function set(value) {
                            _region = value;
                            this.hasBeenReset = true;
                        }
                    }));
                    Object.defineProperty(cue, 'vertical', extend({
                    }, baseObj, {
                        get: function get() {
                            return _vertical;
                        },
                        set: function set(value) {
                            var setting = findDirectionSetting(value); // Have to check for false because the setting an be an empty string.
                            if (setting === false) throw new SyntaxError('An invalid or illegal string was specified.');
                            _vertical = setting;
                            this.hasBeenReset = true;
                        }
                    }));
                    Object.defineProperty(cue, 'snapToLines', extend({
                    }, baseObj, {
                        get: function get() {
                            return _snapToLines;
                        },
                        set: function set(value) {
                            _snapToLines = !!value;
                            this.hasBeenReset = true;
                        }
                    }));
                    Object.defineProperty(cue, 'line', extend({
                    }, baseObj, {
                        get: function get() {
                            return _line;
                        },
                        set: function set(value) {
                            if (typeof value !== 'number' && value !== autoKeyword) throw new SyntaxError('An invalid number or illegal string was specified.');
                            _line = value;
                            this.hasBeenReset = true;
                        }
                    }));
                    Object.defineProperty(cue, 'lineAlign', extend({
                    }, baseObj, {
                        get: function get() {
                            return _lineAlign;
                        },
                        set: function set(value) {
                            var setting = findAlignSetting(value);
                            if (!setting) throw new SyntaxError('An invalid or illegal string was specified.');
                            _lineAlign = setting;
                            this.hasBeenReset = true;
                        }
                    }));
                    Object.defineProperty(cue, 'position', extend({
                    }, baseObj, {
                        get: function get() {
                            return _position;
                        },
                        set: function set(value) {
                            if (value < 0 || value > 100) throw new Error('Position must be between 0 and 100.');
                            _position = value;
                            this.hasBeenReset = true;
                        }
                    }));
                    Object.defineProperty(cue, 'positionAlign', extend({
                    }, baseObj, {
                        get: function get() {
                            return _positionAlign;
                        },
                        set: function set(value) {
                            var setting = findAlignSetting(value);
                            if (!setting) throw new SyntaxError('An invalid or illegal string was specified.');
                            _positionAlign = setting;
                            this.hasBeenReset = true;
                        }
                    }));
                    Object.defineProperty(cue, 'size', extend({
                    }, baseObj, {
                        get: function get() {
                            return _size;
                        },
                        set: function set(value) {
                            if (value < 0 || value > 100) throw new Error('Size must be between 0 and 100.');
                            _size = value;
                            this.hasBeenReset = true;
                        }
                    }));
                    Object.defineProperty(cue, 'align', extend({
                    }, baseObj, {
                        get: function get() {
                            return _align;
                        },
                        set: function set(value) {
                            var setting = findAlignSetting(value);
                            if (!setting) throw new SyntaxError('An invalid or illegal string was specified.');
                            _align = setting;
                            this.hasBeenReset = true;
                        }
                    }));
                    /**
     * Other <track> spec defined properties
     */ // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#text-track-cue-display-state
                    cue.displayState = void 0;
                }
                /**
   * VTTCue methods
   */ VTTCue.prototype.getCueAsHTML = function() {
                    // Assume WebVTT.convertCueToDOMTree is on the global.
                    var WebVTT = window.WebVTT;
                    return WebVTT.convertCueToDOMTree(window, this.text);
                };
                return VTTCue;
            }();
            // CONCATENATED MODULE: ./src/utils/vttparser.js
            /*
 * Source: https://github.com/mozilla/vtt.js/blob/master/dist/vtt.js#L1716
 */ var StringDecoder = function StringDecoder() {
                return {
                    decode: function decode(data) {
                        if (!data) return '';
                        if (typeof data !== 'string') throw new Error('Error - expected string data.');
                        return decodeURIComponent(encodeURIComponent(data));
                    }
                };
            };
            function VTTParser() {
                this.window = window;
                this.state = 'INITIAL';
                this.buffer = '';
                this.decoder = new StringDecoder();
                this.regionList = [];
            } // Try to parse input as a time stamp.
            function parseTimeStamp(input) {
                function computeSeconds(h, m, s, f) {
                    return (h | 0) * 3600 + (m | 0) * 60 + (s | 0) + (f | 0) / 1000;
                }
                var m1 = input.match(/^(\d+):(\d{2})(:\d{2})?\.(\d{3})/);
                if (!m1) return null;
                if (m1[3]) // Timestamp takes the form of [hours]:[minutes]:[seconds].[milliseconds]
                return computeSeconds(m1[1], m1[2], m1[3].replace(':', ''), m1[4]);
                else if (m1[1] > 59) // Timestamp takes the form of [hours]:[minutes].[milliseconds]
                // First position is hours as it's over 59.
                return computeSeconds(m1[1], m1[2], 0, m1[4]);
                else // Timestamp takes the form of [minutes]:[seconds].[milliseconds]
                return computeSeconds(0, m1[1], m1[2], m1[4]);
            } // A settings object holds key/value pairs and will ignore anything but the first
            // assignment to a specific key.
            function Settings() {
                this.values = Object.create(null);
            }
            Settings.prototype = {
                // Only accept the first assignment to any key.
                set: function set(k, v) {
                    if (!this.get(k) && v !== '') this.values[k] = v;
                },
                // Return the value for a key, or a default value.
                // If 'defaultKey' is passed then 'dflt' is assumed to be an object with
                // a number of possible default values as properties where 'defaultKey' is
                // the key of the property that will be chosen; otherwise it's assumed to be
                // a single value.
                get: function get(k, dflt, defaultKey) {
                    if (defaultKey) return this.has(k) ? this.values[k] : dflt[defaultKey];
                    return this.has(k) ? this.values[k] : dflt;
                },
                // Check whether we have a value for a key.
                has: function has(k) {
                    return k in this.values;
                },
                // Accept a setting if its one of the given alternatives.
                alt: function alt(k, v, a) {
                    for(var n = 0; n < a.length; ++n)if (v === a[n]) {
                        this.set(k, v);
                        break;
                    }
                },
                // Accept a setting if its a valid (signed) integer.
                integer: function integer(k, v) {
                    if (/^-?\d+$/.test(v)) // integer
                    this.set(k, parseInt(v, 10));
                },
                // Accept a setting if its a valid percentage.
                percent: function percent(k, v) {
                    var m;
                    if (m = v.match(/^([\d]{1,3})(\.[\d]*)?%$/)) {
                        v = parseFloat(v);
                        if (v >= 0 && v <= 100) {
                            this.set(k, v);
                            return true;
                        }
                    }
                    return false;
                }
            }; // Helper function to parse input into groups separated by 'groupDelim', and
            // interprete each group as a key/value pair separated by 'keyValueDelim'.
            function parseOptions(input, callback, keyValueDelim, groupDelim) {
                var groups = groupDelim ? input.split(groupDelim) : [
                    input
                ];
                for(var i in groups){
                    if (typeof groups[i] !== 'string') continue;
                    var kv = groups[i].split(keyValueDelim);
                    if (kv.length !== 2) continue;
                    var k = kv[0];
                    var v = kv[1];
                    callback(k, v);
                }
            }
            var defaults = new vttcue(0, 0, 0); // 'middle' was changed to 'center' in the spec: https://github.com/w3c/webvtt/pull/244
            //  Safari doesn't yet support this change, but FF and Chrome do.
            var center = defaults.align === 'middle' ? 'middle' : 'center';
            function parseCue(input1, cue1, regionList) {
                // Remember the original input if we need to throw an error.
                var oInput = input1; // 4.1 WebVTT timestamp
                function consumeTimeStamp() {
                    var ts = parseTimeStamp(input1);
                    if (ts === null) throw new Error('Malformed timestamp: ' + oInput);
                     // Remove time stamp from input.
                    input1 = input1.replace(/^[^\sa-zA-Z-]+/, '');
                    return ts;
                } // 4.4.2 WebVTT cue settings
                function consumeCueSettings(input, cue) {
                    var settings = new Settings();
                    parseOptions(input, function(k, v) {
                        switch(k){
                            case 'region':
                                // Find the last region we parsed with the same region id.
                                for(var i = regionList.length - 1; i >= 0; i--)if (regionList[i].id === v) {
                                    settings.set(k, regionList[i].region);
                                    break;
                                }
                                break;
                            case 'vertical':
                                settings.alt(k, v, [
                                    'rl',
                                    'lr'
                                ]);
                                break;
                            case 'line':
                                var vals = v.split(','), vals0 = vals[0];
                                settings.integer(k, vals0);
                                if (settings.percent(k, vals0)) settings.set('snapToLines', false);
                                settings.alt(k, vals0, [
                                    'auto'
                                ]);
                                if (vals.length === 2) settings.alt('lineAlign', vals[1], [
                                    'start',
                                    center,
                                    'end'
                                ]);
                                break;
                            case 'position':
                                vals = v.split(',');
                                settings.percent(k, vals[0]);
                                if (vals.length === 2) settings.alt('positionAlign', vals[1], [
                                    'start',
                                    center,
                                    'end',
                                    'line-left',
                                    'line-right',
                                    'auto'
                                ]);
                                break;
                            case 'size':
                                settings.percent(k, v);
                                break;
                            case 'align':
                                settings.alt(k, v, [
                                    'start',
                                    center,
                                    'end',
                                    'left',
                                    'right'
                                ]);
                                break;
                        }
                    }, /:/, /\s/); // Apply default values for any missing fields.
                    cue.region = settings.get('region', null);
                    cue.vertical = settings.get('vertical', '');
                    var line = settings.get('line', 'auto');
                    if (line === 'auto' && defaults.line === -1) // set numeric line number for Safari
                    line = -1;
                    cue.line = line;
                    cue.lineAlign = settings.get('lineAlign', 'start');
                    cue.snapToLines = settings.get('snapToLines', true);
                    cue.size = settings.get('size', 100);
                    cue.align = settings.get('align', center);
                    var position = settings.get('position', 'auto');
                    if (position === 'auto' && defaults.position === 50) // set numeric position for Safari
                    position = cue.align === 'start' || cue.align === 'left' ? 0 : cue.align === 'end' || cue.align === 'right' ? 100 : 50;
                    cue.position = position;
                }
                function skipWhitespace() {
                    input1 = input1.replace(/^\s+/, '');
                } // 4.1 WebVTT cue timings.
                skipWhitespace();
                cue1.startTime = consumeTimeStamp(); // (1) collect cue start time
                skipWhitespace();
                if (input1.substr(0, 3) !== '-->') // (3) next characters must match '-->'
                throw new Error('Malformed time stamp (time stamps must be separated by \'-->\'): ' + oInput);
                input1 = input1.substr(3);
                skipWhitespace();
                cue1.endTime = consumeTimeStamp(); // (5) collect cue end time
                // 4.1 WebVTT cue settings list.
                skipWhitespace();
                consumeCueSettings(input1, cue1);
            }
            function fixLineBreaks(input) {
                return input.replace(/<br(?: \/)?>/gi, '\n');
            }
            VTTParser.prototype = {
                parse: function parse(data) {
                    var self = this; // If there is no data then we won't decode it, but will just try to parse
                    // whatever is in buffer already. This may occur in circumstances, for
                    // example when flush() is called.
                    if (data) // Try to decode the data that we received.
                    self.buffer += self.decoder.decode(data, {
                        stream: true
                    });
                    function collectNextLine() {
                        var buffer = self.buffer;
                        var pos = 0;
                        buffer = fixLineBreaks(buffer);
                        while(pos < buffer.length && buffer[pos] !== '\r' && buffer[pos] !== '\n')++pos;
                        var line = buffer.substr(0, pos); // Advance the buffer early in case we fail below.
                        if (buffer[pos] === '\r') ++pos;
                        if (buffer[pos] === '\n') ++pos;
                        self.buffer = buffer.substr(pos);
                        return line;
                    } // 3.2 WebVTT metadata header syntax
                    function parseHeader(input) {
                        parseOptions(input, function(k, v) {
                        }, /:/);
                    } // 5.1 WebVTT file parsing.
                    try {
                        var line1;
                        if (self.state === 'INITIAL') {
                            // We can't start parsing until we have the first line.
                            if (!/\r\n|\n/.test(self.buffer)) return this;
                            line1 = collectNextLine(); // strip of UTF-8 BOM if any
                            // https://en.wikipedia.org/wiki/Byte_order_mark#UTF-8
                            var m = line1.match(/^(ï»¿)?WEBVTT([ \t].*)?$/);
                            if (!m || !m[0]) throw new Error('Malformed WebVTT signature.');
                            self.state = 'HEADER';
                        }
                        var alreadyCollectedLine = false;
                        while(self.buffer){
                            // We can't parse a line until we have the full line.
                            if (!/\r\n|\n/.test(self.buffer)) return this;
                            if (!alreadyCollectedLine) line1 = collectNextLine();
                            else alreadyCollectedLine = false;
                            switch(self.state){
                                case 'HEADER':
                                    // 13-18 - Allow a header (metadata) under the WEBVTT line.
                                    if (/:/.test(line1)) parseHeader(line1);
                                    else if (!line1) // An empty line terminates the header and starts the body (cues).
                                    self.state = 'ID';
                                    continue;
                                case 'NOTE':
                                    // Ignore NOTE blocks.
                                    if (!line1) self.state = 'ID';
                                    continue;
                                case 'ID':
                                    // Check for the start of NOTE blocks.
                                    if (/^NOTE($|[ \t])/.test(line1)) {
                                        self.state = 'NOTE';
                                        break;
                                    } // 19-29 - Allow any number of line terminators, then initialize new cue values.
                                    if (!line1) continue;
                                    self.cue = new vttcue(0, 0, '');
                                    self.state = 'CUE'; // 30-39 - Check if self line contains an optional identifier or timing data.
                                    if (line1.indexOf('-->') === -1) {
                                        self.cue.id = line1;
                                        continue;
                                    }
                                // Process line as start of a cue.
                                /* falls through */ case 'CUE':
                                    // 40 - Collect cue timings and settings.
                                    try {
                                        parseCue(line1, self.cue, self.regionList);
                                    } catch (e) {
                                        // In case of an error ignore rest of the cue.
                                        self.cue = null;
                                        self.state = 'BADCUE';
                                        continue;
                                    }
                                    self.state = 'CUETEXT';
                                    continue;
                                case 'CUETEXT':
                                    var hasSubstring = line1.indexOf('-->') !== -1; // 34 - If we have an empty line then report the cue.
                                    // 35 - If we have the special substring '-->' then report the cue,
                                    // but do not collect the line as we need to process the current
                                    // one as a new cue.
                                    if (!line1 || hasSubstring && (alreadyCollectedLine = true)) {
                                        // We are done parsing self cue.
                                        if (self.oncue) self.oncue(self.cue);
                                        self.cue = null;
                                        self.state = 'ID';
                                        continue;
                                    }
                                    if (self.cue.text) self.cue.text += '\n';
                                    self.cue.text += line1;
                                    continue;
                                case 'BADCUE':
                                    // BADCUE
                                    // 54-62 - Collect and discard the remaining cue.
                                    if (!line1) self.state = 'ID';
                                    continue;
                            }
                        }
                    } catch (e) {
                        // If we are currently parsing a cue, report what we have.
                        if (self.state === 'CUETEXT' && self.cue && self.oncue) self.oncue(self.cue);
                        self.cue = null; // Enter BADWEBVTT state if header was not parsed correctly otherwise
                        // another exception occurred so enter BADCUE state.
                        self.state = self.state === 'INITIAL' ? 'BADWEBVTT' : 'BADCUE';
                    }
                    return this;
                },
                flush: function flush() {
                    var self = this;
                    try {
                        // Finish decoding the stream.
                        self.buffer += self.decoder.decode(); // Synthesize the end of the current cue or region.
                        if (self.cue || self.state === 'HEADER') {
                            self.buffer += '\n\n';
                            self.parse();
                        } // If we've flushed, parsed, and we're still on the INITIAL state then
                        // that means we don't have enough of the stream to parse the first
                        // line.
                        if (self.state === 'INITIAL') throw new Error('Malformed WebVTT signature.');
                    } catch (e) {
                        throw e;
                    }
                    if (self.onflush) self.onflush();
                    return this;
                }
            };
            /* harmony default export */ var vttparser = VTTParser;
            // CONCATENATED MODULE: ./src/utils/cues.ts
            function newCue(track, startTime, endTime, captionScreen) {
                var result = [];
                var row; // the type data states this is VTTCue, but it can potentially be a TextTrackCue on old browsers
                var cue;
                var indenting;
                var indent;
                var text;
                var VTTCue = window.VTTCue || TextTrackCue;
                for(var r = 0; r < captionScreen.rows.length; r++){
                    row = captionScreen.rows[r];
                    indenting = true;
                    indent = 0;
                    text = '';
                    if (!row.isEmpty()) {
                        for(var c = 0; c < row.chars.length; c++)if (row.chars[c].uchar.match(/\s/) && indenting) indent++;
                        else {
                            text += row.chars[c].uchar;
                            indenting = false;
                        }
                         // To be used for cleaning-up orphaned roll-up captions
                        row.cueStartTime = startTime; // Give a slight bump to the endTime if it's equal to startTime to avoid a SyntaxError in IE
                        if (startTime === endTime) endTime += 0.0001;
                        cue = new VTTCue(startTime, endTime, fixLineBreaks(text.trim()));
                        if (indent >= 16) indent--;
                        else indent++;
                         // VTTCue.line get's flakey when using controls, so let's now include line 13&14
                        // also, drop line 1 since it's to close to the top
                        if (navigator.userAgent.match(/Firefox\//)) cue.line = r + 1;
                        else cue.line = r > 7 ? r - 2 : r + 1;
                        cue.align = 'left'; // Clamp the position between 0 and 100 - if out of these bounds, Firefox throws an exception and captions break
                        cue.position = Math.max(0, Math.min(100, 100 * (indent / 32)));
                        result.push(cue);
                        if (track) track.addCue(cue);
                    }
                }
                return result;
            }
            // CONCATENATED MODULE: ./src/utils/cea-608-parser.ts
            /**
 *
 * This code was ported from the dash.js project at:
 *   https://github.com/Dash-Industry-Forum/dash.js/blob/development/externals/cea608-parser.js
 *   https://github.com/Dash-Industry-Forum/dash.js/commit/8269b26a761e0853bb21d78780ed945144ecdd4d#diff-71bc295a2d6b6b7093a1d3290d53a4b2
 *
 * The original copyright appears below:
 *
 * The copyright in this software is being made available under the BSD License,
 * included below. This software may be subject to other third party and contributor
 * rights, including patent rights, and no such rights are granted under this license.
 *
 * Copyright (c) 2015-2016, DASH Industry Forum.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *  1. Redistributions of source code must retain the above copyright notice, this
 *  list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright notice,
 *  this list of conditions and the following disclaimer in the documentation and/or
 *  other materials provided with the distribution.
 *  2. Neither the name of Dash Industry Forum nor the names of its
 *  contributors may be used to endorse or promote products derived from this software
 *  without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY
 *  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 *  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 *  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 *  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 *  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 *  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 */ /**
 *  Exceptions from regular ASCII. CodePoints are mapped to UTF-16 codes
 */ var specialCea608CharsCodes = {
                42: 225,
                // lowercase a, acute accent
                92: 233,
                // lowercase e, acute accent
                94: 237,
                // lowercase i, acute accent
                95: 243,
                // lowercase o, acute accent
                96: 250,
                // lowercase u, acute accent
                123: 231,
                // lowercase c with cedilla
                124: 247,
                // division symbol
                125: 209,
                // uppercase N tilde
                126: 241,
                // lowercase n tilde
                127: 9608,
                // Full block
                // THIS BLOCK INCLUDES THE 16 EXTENDED (TWO-BYTE) LINE 21 CHARACTERS
                // THAT COME FROM HI BYTE=0x11 AND LOW BETWEEN 0x30 AND 0x3F
                // THIS MEANS THAT \x50 MUST BE ADDED TO THE VALUES
                128: 174,
                // Registered symbol (R)
                129: 176,
                // degree sign
                130: 189,
                // 1/2 symbol
                131: 191,
                // Inverted (open) question mark
                132: 8482,
                // Trademark symbol (TM)
                133: 162,
                // Cents symbol
                134: 163,
                // Pounds sterling
                135: 9834,
                // Music 8'th note
                136: 224,
                // lowercase a, grave accent
                137: 32,
                // transparent space (regular)
                138: 232,
                // lowercase e, grave accent
                139: 226,
                // lowercase a, circumflex accent
                140: 234,
                // lowercase e, circumflex accent
                141: 238,
                // lowercase i, circumflex accent
                142: 244,
                // lowercase o, circumflex accent
                143: 251,
                // lowercase u, circumflex accent
                // THIS BLOCK INCLUDES THE 32 EXTENDED (TWO-BYTE) LINE 21 CHARACTERS
                // THAT COME FROM HI BYTE=0x12 AND LOW BETWEEN 0x20 AND 0x3F
                144: 193,
                // capital letter A with acute
                145: 201,
                // capital letter E with acute
                146: 211,
                // capital letter O with acute
                147: 218,
                // capital letter U with acute
                148: 220,
                // capital letter U with diaresis
                149: 252,
                // lowercase letter U with diaeresis
                150: 8216,
                // opening single quote
                151: 161,
                // inverted exclamation mark
                152: 42,
                // asterisk
                153: 8217,
                // closing single quote
                154: 9473,
                // box drawings heavy horizontal
                155: 169,
                // copyright sign
                156: 8480,
                // Service mark
                157: 8226,
                // (round) bullet
                158: 8220,
                // Left double quotation mark
                159: 8221,
                // Right double quotation mark
                160: 192,
                // uppercase A, grave accent
                161: 194,
                // uppercase A, circumflex
                162: 199,
                // uppercase C with cedilla
                163: 200,
                // uppercase E, grave accent
                164: 202,
                // uppercase E, circumflex
                165: 203,
                // capital letter E with diaresis
                166: 235,
                // lowercase letter e with diaresis
                167: 206,
                // uppercase I, circumflex
                168: 207,
                // uppercase I, with diaresis
                169: 239,
                // lowercase i, with diaresis
                170: 212,
                // uppercase O, circumflex
                171: 217,
                // uppercase U, grave accent
                172: 249,
                // lowercase u, grave accent
                173: 219,
                // uppercase U, circumflex
                174: 171,
                // left-pointing double angle quotation mark
                175: 187,
                // right-pointing double angle quotation mark
                // THIS BLOCK INCLUDES THE 32 EXTENDED (TWO-BYTE) LINE 21 CHARACTERS
                // THAT COME FROM HI BYTE=0x13 AND LOW BETWEEN 0x20 AND 0x3F
                176: 195,
                // Uppercase A, tilde
                177: 227,
                // Lowercase a, tilde
                178: 205,
                // Uppercase I, acute accent
                179: 204,
                // Uppercase I, grave accent
                180: 236,
                // Lowercase i, grave accent
                181: 210,
                // Uppercase O, grave accent
                182: 242,
                // Lowercase o, grave accent
                183: 213,
                // Uppercase O, tilde
                184: 245,
                // Lowercase o, tilde
                185: 123,
                // Open curly brace
                186: 125,
                // Closing curly brace
                187: 92,
                // Backslash
                188: 94,
                // Caret
                189: 95,
                // Underscore
                190: 124,
                // Pipe (vertical line)
                191: 8764,
                // Tilde operator
                192: 196,
                // Uppercase A, umlaut
                193: 228,
                // Lowercase A, umlaut
                194: 214,
                // Uppercase O, umlaut
                195: 246,
                // Lowercase o, umlaut
                196: 223,
                // Esszett (sharp S)
                197: 165,
                // Yen symbol
                198: 164,
                // Generic currency sign
                199: 9475,
                // Box drawings heavy vertical
                200: 197,
                // Uppercase A, ring
                201: 229,
                // Lowercase A, ring
                202: 216,
                // Uppercase O, stroke
                203: 248,
                // Lowercase o, strok
                204: 9487,
                // Box drawings heavy down and right
                205: 9491,
                // Box drawings heavy down and left
                206: 9495,
                // Box drawings heavy up and right
                207: 9499 // Box drawings heavy up and left
            };
            /**
 * Utils
 */ var getCharForByte = function getCharForByte(_byte) {
                var charCode = _byte;
                if (specialCea608CharsCodes.hasOwnProperty(_byte)) charCode = specialCea608CharsCodes[_byte];
                return String.fromCharCode(charCode);
            };
            var NR_ROWS = 15;
            var NR_COLS = 100; // Tables to look up row from PAC data
            var rowsLowCh1 = {
                17: 1,
                18: 3,
                21: 5,
                22: 7,
                23: 9,
                16: 11,
                19: 12,
                20: 14
            };
            var rowsHighCh1 = {
                17: 2,
                18: 4,
                21: 6,
                22: 8,
                23: 10,
                19: 13,
                20: 15
            };
            var rowsLowCh2 = {
                25: 1,
                26: 3,
                29: 5,
                30: 7,
                31: 9,
                24: 11,
                27: 12,
                28: 14
            };
            var rowsHighCh2 = {
                25: 2,
                26: 4,
                29: 6,
                30: 8,
                31: 10,
                27: 13,
                28: 15
            };
            var backgroundColors = [
                'white',
                'green',
                'blue',
                'cyan',
                'red',
                'yellow',
                'magenta',
                'black',
                'transparent'
            ];
            var VerboseLevel1;
            (function(VerboseLevel) {
                VerboseLevel[VerboseLevel["ERROR"] = 0] = "ERROR";
                VerboseLevel[VerboseLevel["TEXT"] = 1] = "TEXT";
                VerboseLevel[VerboseLevel["WARNING"] = 2] = "WARNING";
                VerboseLevel[VerboseLevel["INFO"] = 2] = "INFO";
                VerboseLevel[VerboseLevel["DEBUG"] = 3] = "DEBUG";
                VerboseLevel[VerboseLevel["DATA"] = 3] = "DATA";
            })(VerboseLevel1 || (VerboseLevel1 = {
            }));
            var cea_608_parser_CaptionsLogger = /*#__PURE__*/ function() {
                function CaptionsLogger() {
                    this.time = null;
                    this.verboseLevel = VerboseLevel1.ERROR;
                }
                var _proto = CaptionsLogger.prototype;
                _proto.log = function log(severity, msg) {
                    if (this.verboseLevel >= severity) logger1["logger"].log(this.time + " [" + severity + "] " + msg);
                };
                return CaptionsLogger;
            }();
            var numArrayToHexArray = function numArrayToHexArray(numArray) {
                var hexArray = [];
                for(var j = 0; j < numArray.length; j++)hexArray.push(numArray[j].toString(16));
                return hexArray;
            };
            var PenState1 = /*#__PURE__*/ function() {
                function PenState(foreground, underline, italics, background, flash) {
                    this.foreground = void 0;
                    this.underline = void 0;
                    this.italics = void 0;
                    this.background = void 0;
                    this.flash = void 0;
                    this.foreground = foreground || 'white';
                    this.underline = underline || false;
                    this.italics = italics || false;
                    this.background = background || 'black';
                    this.flash = flash || false;
                }
                var _proto2 = PenState.prototype;
                _proto2.reset = function reset() {
                    this.foreground = 'white';
                    this.underline = false;
                    this.italics = false;
                    this.background = 'black';
                    this.flash = false;
                };
                _proto2.setStyles = function setStyles(styles) {
                    var attribs = [
                        'foreground',
                        'underline',
                        'italics',
                        'background',
                        'flash'
                    ];
                    for(var i = 0; i < attribs.length; i++){
                        var style = attribs[i];
                        if (styles.hasOwnProperty(style)) this[style] = styles[style];
                    }
                };
                _proto2.isDefault = function isDefault() {
                    return this.foreground === 'white' && !this.underline && !this.italics && this.background === 'black' && !this.flash;
                };
                _proto2.equals = function equals(other) {
                    return this.foreground === other.foreground && this.underline === other.underline && this.italics === other.italics && this.background === other.background && this.flash === other.flash;
                };
                _proto2.copy = function copy(newPenState) {
                    this.foreground = newPenState.foreground;
                    this.underline = newPenState.underline;
                    this.italics = newPenState.italics;
                    this.background = newPenState.background;
                    this.flash = newPenState.flash;
                };
                _proto2.toString = function toString() {
                    return 'color=' + this.foreground + ', underline=' + this.underline + ', italics=' + this.italics + ', background=' + this.background + ', flash=' + this.flash;
                };
                return PenState;
            }();
            /**
 * Unicode character with styling and background.
 * @constructor
 */ var StyledUnicodeChar1 = /*#__PURE__*/ function() {
                function StyledUnicodeChar(uchar, foreground, underline, italics, background, flash) {
                    this.uchar = void 0;
                    this.penState = void 0;
                    this.uchar = uchar || ' '; // unicode character
                    this.penState = new PenState1(foreground, underline, italics, background, flash);
                }
                var _proto3 = StyledUnicodeChar.prototype;
                _proto3.reset = function reset() {
                    this.uchar = ' ';
                    this.penState.reset();
                };
                _proto3.setChar = function setChar(uchar, newPenState) {
                    this.uchar = uchar;
                    this.penState.copy(newPenState);
                };
                _proto3.setPenState = function setPenState(newPenState) {
                    this.penState.copy(newPenState);
                };
                _proto3.equals = function equals(other) {
                    return this.uchar === other.uchar && this.penState.equals(other.penState);
                };
                _proto3.copy = function copy(newChar) {
                    this.uchar = newChar.uchar;
                    this.penState.copy(newChar.penState);
                };
                _proto3.isEmpty = function isEmpty() {
                    return this.uchar === ' ' && this.penState.isDefault();
                };
                return StyledUnicodeChar;
            }();
            /**
 * CEA-608 row consisting of NR_COLS instances of StyledUnicodeChar.
 * @constructor
 */ var Row1 = /*#__PURE__*/ function() {
                function Row(logger) {
                    this.chars = void 0;
                    this.pos = void 0;
                    this.currPenState = void 0;
                    this.cueStartTime = void 0;
                    this.logger = void 0;
                    this.chars = [];
                    for(var i = 0; i < NR_COLS; i++)this.chars.push(new StyledUnicodeChar1());
                    this.logger = logger;
                    this.pos = 0;
                    this.currPenState = new PenState1();
                }
                var _proto4 = Row.prototype;
                _proto4.equals = function equals(other) {
                    var equal = true;
                    for(var i = 0; i < NR_COLS; i++)if (!this.chars[i].equals(other.chars[i])) {
                        equal = false;
                        break;
                    }
                    return equal;
                };
                _proto4.copy = function copy(other) {
                    for(var i = 0; i < NR_COLS; i++)this.chars[i].copy(other.chars[i]);
                };
                _proto4.isEmpty = function isEmpty() {
                    var empty = true;
                    for(var i = 0; i < NR_COLS; i++)if (!this.chars[i].isEmpty()) {
                        empty = false;
                        break;
                    }
                    return empty;
                };
                _proto4.setCursor = function setCursor(absPos) {
                    if (this.pos !== absPos) this.pos = absPos;
                    if (this.pos < 0) {
                        this.logger.log(VerboseLevel1.DEBUG, 'Negative cursor position ' + this.pos);
                        this.pos = 0;
                    } else if (this.pos > NR_COLS) {
                        this.logger.log(VerboseLevel1.DEBUG, 'Too large cursor position ' + this.pos);
                        this.pos = NR_COLS;
                    }
                };
                _proto4.moveCursor = function moveCursor(relPos) {
                    var newPos = this.pos + relPos;
                    if (relPos > 1) for(var i = this.pos + 1; i < newPos + 1; i++)this.chars[i].setPenState(this.currPenState);
                    this.setCursor(newPos);
                };
                _proto4.backSpace = function backSpace() {
                    this.moveCursor(-1);
                    this.chars[this.pos].setChar(' ', this.currPenState);
                };
                _proto4.insertChar = function insertChar(_byte2) {
                    if (_byte2 >= 144) // Extended char
                    this.backSpace();
                    var _char = getCharForByte(_byte2);
                    if (this.pos >= NR_COLS) {
                        this.logger.log(VerboseLevel1.ERROR, 'Cannot insert ' + _byte2.toString(16) + ' (' + _char + ') at position ' + this.pos + '. Skipping it!');
                        return;
                    }
                    this.chars[this.pos].setChar(_char, this.currPenState);
                    this.moveCursor(1);
                };
                _proto4.clearFromPos = function clearFromPos(startPos) {
                    var i;
                    for(i = startPos; i < NR_COLS; i++)this.chars[i].reset();
                };
                _proto4.clear = function clear() {
                    this.clearFromPos(0);
                    this.pos = 0;
                    this.currPenState.reset();
                };
                _proto4.clearToEndOfRow = function clearToEndOfRow() {
                    this.clearFromPos(this.pos);
                };
                _proto4.getTextString = function getTextString() {
                    var chars = [];
                    var empty = true;
                    for(var i = 0; i < NR_COLS; i++){
                        var _char2 = this.chars[i].uchar;
                        if (_char2 !== ' ') empty = false;
                        chars.push(_char2);
                    }
                    if (empty) return '';
                    else return chars.join('');
                };
                _proto4.setPenStyles = function setPenStyles(styles) {
                    this.currPenState.setStyles(styles);
                    var currChar = this.chars[this.pos];
                    currChar.setPenState(this.currPenState);
                };
                return Row;
            }();
            /**
 * Keep a CEA-608 screen of 32x15 styled characters
 * @constructor
 */ var CaptionScreen1 = /*#__PURE__*/ function() {
                function CaptionScreen(logger) {
                    this.rows = void 0;
                    this.currRow = void 0;
                    this.nrRollUpRows = void 0;
                    this.lastOutputScreen = void 0;
                    this.logger = void 0;
                    this.rows = [];
                    for(var i = 0; i < NR_ROWS; i++)this.rows.push(new Row1(logger));
                     // Note that we use zero-based numbering (0-14)
                    this.logger = logger;
                    this.currRow = NR_ROWS - 1;
                    this.nrRollUpRows = null;
                    this.lastOutputScreen = null;
                    this.reset();
                }
                var _proto5 = CaptionScreen.prototype;
                _proto5.reset = function reset() {
                    for(var i = 0; i < NR_ROWS; i++)this.rows[i].clear();
                    this.currRow = NR_ROWS - 1;
                };
                _proto5.equals = function equals(other) {
                    var equal = true;
                    for(var i = 0; i < NR_ROWS; i++)if (!this.rows[i].equals(other.rows[i])) {
                        equal = false;
                        break;
                    }
                    return equal;
                };
                _proto5.copy = function copy(other) {
                    for(var i = 0; i < NR_ROWS; i++)this.rows[i].copy(other.rows[i]);
                };
                _proto5.isEmpty = function isEmpty() {
                    var empty = true;
                    for(var i = 0; i < NR_ROWS; i++)if (!this.rows[i].isEmpty()) {
                        empty = false;
                        break;
                    }
                    return empty;
                };
                _proto5.backSpace = function backSpace() {
                    var row = this.rows[this.currRow];
                    row.backSpace();
                };
                _proto5.clearToEndOfRow = function clearToEndOfRow() {
                    var row = this.rows[this.currRow];
                    row.clearToEndOfRow();
                };
                _proto5.insertChar = function insertChar(_char3) {
                    var row = this.rows[this.currRow];
                    row.insertChar(_char3);
                };
                _proto5.setPen = function setPen(styles) {
                    var row = this.rows[this.currRow];
                    row.setPenStyles(styles);
                };
                _proto5.moveCursor = function moveCursor(relPos) {
                    var row = this.rows[this.currRow];
                    row.moveCursor(relPos);
                };
                _proto5.setCursor = function setCursor(absPos) {
                    this.logger.log(VerboseLevel1.INFO, 'setCursor: ' + absPos);
                    var row = this.rows[this.currRow];
                    row.setCursor(absPos);
                };
                _proto5.setPAC = function setPAC(pacData) {
                    this.logger.log(VerboseLevel1.INFO, 'pacData = ' + JSON.stringify(pacData));
                    var newRow = pacData.row - 1;
                    if (this.nrRollUpRows && newRow < this.nrRollUpRows - 1) newRow = this.nrRollUpRows - 1;
                     // Make sure this only affects Roll-up Captions by checking this.nrRollUpRows
                    if (this.nrRollUpRows && this.currRow !== newRow) {
                        // clear all rows first
                        for(var i = 0; i < NR_ROWS; i++)this.rows[i].clear();
                         // Copy this.nrRollUpRows rows from lastOutputScreen and place it in the newRow location
                        // topRowIndex - the start of rows to copy (inclusive index)
                        var topRowIndex = this.currRow + 1 - this.nrRollUpRows; // We only copy if the last position was already shown.
                        // We use the cueStartTime value to check this.
                        var lastOutputScreen = this.lastOutputScreen;
                        if (lastOutputScreen) {
                            var prevLineTime = lastOutputScreen.rows[topRowIndex].cueStartTime;
                            var time = this.logger.time;
                            if (prevLineTime && time !== null && prevLineTime < time) for(var _i = 0; _i < this.nrRollUpRows; _i++)this.rows[newRow - this.nrRollUpRows + _i + 1].copy(lastOutputScreen.rows[topRowIndex + _i]);
                        }
                    }
                    this.currRow = newRow;
                    var row = this.rows[this.currRow];
                    if (pacData.indent !== null) {
                        var indent = pacData.indent;
                        var prevPos = Math.max(indent - 1, 0);
                        row.setCursor(pacData.indent);
                        pacData.color = row.chars[prevPos].penState.foreground;
                    }
                    var styles = {
                        foreground: pacData.color,
                        underline: pacData.underline,
                        italics: pacData.italics,
                        background: 'black',
                        flash: false
                    };
                    this.setPen(styles);
                };
                _proto5.setBkgData = function setBkgData(bkgData) {
                    this.logger.log(VerboseLevel1.INFO, 'bkgData = ' + JSON.stringify(bkgData));
                    this.backSpace();
                    this.setPen(bkgData);
                    this.insertChar(32); // Space
                };
                _proto5.setRollUpRows = function setRollUpRows(nrRows) {
                    this.nrRollUpRows = nrRows;
                };
                _proto5.rollUp = function rollUp() {
                    if (this.nrRollUpRows === null) {
                        this.logger.log(VerboseLevel1.DEBUG, 'roll_up but nrRollUpRows not set yet');
                        return; // Not properly setup
                    }
                    this.logger.log(VerboseLevel1.TEXT, this.getDisplayText());
                    var topRowIndex = this.currRow + 1 - this.nrRollUpRows;
                    var topRow = this.rows.splice(topRowIndex, 1)[0];
                    topRow.clear();
                    this.rows.splice(this.currRow, 0, topRow);
                    this.logger.log(VerboseLevel1.INFO, 'Rolling up'); // this.logger.log(VerboseLevel.TEXT, this.get_display_text())
                };
                _proto5.getDisplayText = function getDisplayText(asOneRow) {
                    asOneRow = asOneRow || false;
                    var displayText = [];
                    var text = '';
                    var rowNr = -1;
                    for(var i = 0; i < NR_ROWS; i++){
                        var rowText = this.rows[i].getTextString();
                        if (rowText) {
                            rowNr = i + 1;
                            if (asOneRow) displayText.push('Row ' + rowNr + ': \'' + rowText + '\'');
                            else displayText.push(rowText.trim());
                        }
                    }
                    if (displayText.length > 0) {
                        if (asOneRow) text = '[' + displayText.join(' | ') + ']';
                        else text = displayText.join('\n');
                    }
                    return text;
                };
                _proto5.getTextAndFormat = function getTextAndFormat() {
                    return this.rows;
                };
                return CaptionScreen;
            }(); // var modes = ['MODE_ROLL-UP', 'MODE_POP-ON', 'MODE_PAINT-ON', 'MODE_TEXT'];
            var Cea608Channel1 = /*#__PURE__*/ function() {
                function Cea608Channel(channelNumber, outputFilter, logger) {
                    this.chNr = void 0;
                    this.outputFilter = void 0;
                    this.mode = void 0;
                    this.verbose = void 0;
                    this.displayedMemory = void 0;
                    this.nonDisplayedMemory = void 0;
                    this.lastOutputScreen = void 0;
                    this.currRollUpRow = void 0;
                    this.writeScreen = void 0;
                    this.cueStartTime = void 0;
                    this.logger = void 0;
                    this.chNr = channelNumber;
                    this.outputFilter = outputFilter;
                    this.mode = null;
                    this.verbose = 0;
                    this.displayedMemory = new CaptionScreen1(logger);
                    this.nonDisplayedMemory = new CaptionScreen1(logger);
                    this.lastOutputScreen = new CaptionScreen1(logger);
                    this.currRollUpRow = this.displayedMemory.rows[NR_ROWS - 1];
                    this.writeScreen = this.displayedMemory;
                    this.mode = null;
                    this.cueStartTime = null; // Keeps track of where a cue started.
                    this.logger = logger;
                }
                var _proto6 = Cea608Channel.prototype;
                _proto6.reset = function reset() {
                    this.mode = null;
                    this.displayedMemory.reset();
                    this.nonDisplayedMemory.reset();
                    this.lastOutputScreen.reset();
                    this.outputFilter.reset();
                    this.currRollUpRow = this.displayedMemory.rows[NR_ROWS - 1];
                    this.writeScreen = this.displayedMemory;
                    this.mode = null;
                    this.cueStartTime = null;
                };
                _proto6.getHandler = function getHandler() {
                    return this.outputFilter;
                };
                _proto6.setHandler = function setHandler(newHandler) {
                    this.outputFilter = newHandler;
                };
                _proto6.setPAC = function setPAC(pacData) {
                    this.writeScreen.setPAC(pacData);
                };
                _proto6.setBkgData = function setBkgData(bkgData) {
                    this.writeScreen.setBkgData(bkgData);
                };
                _proto6.setMode = function setMode(newMode) {
                    if (newMode === this.mode) return;
                    this.mode = newMode;
                    this.logger.log(VerboseLevel1.INFO, 'MODE=' + newMode);
                    if (this.mode === 'MODE_POP-ON') this.writeScreen = this.nonDisplayedMemory;
                    else {
                        this.writeScreen = this.displayedMemory;
                        this.writeScreen.reset();
                    }
                    if (this.mode !== 'MODE_ROLL-UP') {
                        this.displayedMemory.nrRollUpRows = null;
                        this.nonDisplayedMemory.nrRollUpRows = null;
                    }
                    this.mode = newMode;
                };
                _proto6.insertChars = function insertChars(chars) {
                    for(var i = 0; i < chars.length; i++)this.writeScreen.insertChar(chars[i]);
                    var screen = this.writeScreen === this.displayedMemory ? 'DISP' : 'NON_DISP';
                    this.logger.log(VerboseLevel1.INFO, screen + ': ' + this.writeScreen.getDisplayText(true));
                    if (this.mode === 'MODE_PAINT-ON' || this.mode === 'MODE_ROLL-UP') {
                        this.logger.log(VerboseLevel1.TEXT, 'DISPLAYED: ' + this.displayedMemory.getDisplayText(true));
                        this.outputDataUpdate();
                    }
                };
                _proto6.ccRCL = function ccRCL() {
                    // Resume Caption Loading (switch mode to Pop On)
                    this.logger.log(VerboseLevel1.INFO, 'RCL - Resume Caption Loading');
                    this.setMode('MODE_POP-ON');
                };
                _proto6.ccBS = function ccBS() {
                    // BackSpace
                    this.logger.log(VerboseLevel1.INFO, 'BS - BackSpace');
                    if (this.mode === 'MODE_TEXT') return;
                    this.writeScreen.backSpace();
                    if (this.writeScreen === this.displayedMemory) this.outputDataUpdate();
                };
                _proto6.ccAOF = function ccAOF() {
                };
                _proto6.ccAON = function ccAON() {
                };
                _proto6.ccDER = function ccDER() {
                    // Delete to End of Row
                    this.logger.log(VerboseLevel1.INFO, 'DER- Delete to End of Row');
                    this.writeScreen.clearToEndOfRow();
                    this.outputDataUpdate();
                };
                _proto6.ccRU = function ccRU(nrRows) {
                    // Roll-Up Captions-2,3,or 4 Rows
                    this.logger.log(VerboseLevel1.INFO, 'RU(' + nrRows + ') - Roll Up');
                    this.writeScreen = this.displayedMemory;
                    this.setMode('MODE_ROLL-UP');
                    this.writeScreen.setRollUpRows(nrRows);
                };
                _proto6.ccFON = function ccFON() {
                    // Flash On
                    this.logger.log(VerboseLevel1.INFO, 'FON - Flash On');
                    this.writeScreen.setPen({
                        flash: true
                    });
                };
                _proto6.ccRDC = function ccRDC() {
                    // Resume Direct Captioning (switch mode to PaintOn)
                    this.logger.log(VerboseLevel1.INFO, 'RDC - Resume Direct Captioning');
                    this.setMode('MODE_PAINT-ON');
                };
                _proto6.ccTR = function ccTR() {
                    // Text Restart in text mode (not supported, however)
                    this.logger.log(VerboseLevel1.INFO, 'TR');
                    this.setMode('MODE_TEXT');
                };
                _proto6.ccRTD = function ccRTD() {
                    // Resume Text Display in Text mode (not supported, however)
                    this.logger.log(VerboseLevel1.INFO, 'RTD');
                    this.setMode('MODE_TEXT');
                };
                _proto6.ccEDM = function ccEDM() {
                    // Erase Displayed Memory
                    this.logger.log(VerboseLevel1.INFO, 'EDM - Erase Displayed Memory');
                    this.displayedMemory.reset();
                    this.outputDataUpdate(true);
                };
                _proto6.ccCR = function ccCR() {
                    // Carriage Return
                    this.logger.log(VerboseLevel1.INFO, 'CR - Carriage Return');
                    this.writeScreen.rollUp();
                    this.outputDataUpdate(true);
                };
                _proto6.ccENM = function ccENM() {
                    // Erase Non-Displayed Memory
                    this.logger.log(VerboseLevel1.INFO, 'ENM - Erase Non-displayed Memory');
                    this.nonDisplayedMemory.reset();
                };
                _proto6.ccEOC = function ccEOC() {
                    // End of Caption (Flip Memories)
                    this.logger.log(VerboseLevel1.INFO, 'EOC - End Of Caption');
                    if (this.mode === 'MODE_POP-ON') {
                        var tmp = this.displayedMemory;
                        this.displayedMemory = this.nonDisplayedMemory;
                        this.nonDisplayedMemory = tmp;
                        this.writeScreen = this.nonDisplayedMemory;
                        this.logger.log(VerboseLevel1.TEXT, 'DISP: ' + this.displayedMemory.getDisplayText());
                    }
                    this.outputDataUpdate(true);
                };
                _proto6.ccTO = function ccTO(nrCols) {
                    // Tab Offset 1,2, or 3 columns
                    this.logger.log(VerboseLevel1.INFO, 'TO(' + nrCols + ') - Tab Offset');
                    this.writeScreen.moveCursor(nrCols);
                };
                _proto6.ccMIDROW = function ccMIDROW(secondByte) {
                    // Parse MIDROW command
                    var styles = {
                        flash: false
                    };
                    styles.underline = secondByte % 2 === 1;
                    styles.italics = secondByte >= 46;
                    if (!styles.italics) {
                        var colorIndex = Math.floor(secondByte / 2) - 16;
                        var colors = [
                            'white',
                            'green',
                            'blue',
                            'cyan',
                            'red',
                            'yellow',
                            'magenta'
                        ];
                        styles.foreground = colors[colorIndex];
                    } else styles.foreground = 'white';
                    this.logger.log(VerboseLevel1.INFO, 'MIDROW: ' + JSON.stringify(styles));
                    this.writeScreen.setPen(styles);
                };
                _proto6.outputDataUpdate = function outputDataUpdate(dispatch) {
                    if (dispatch === void 0) dispatch = false;
                    var time = this.logger.time;
                    if (time === null) return;
                    if (this.outputFilter) {
                        if (this.cueStartTime === null && !this.displayedMemory.isEmpty()) // Start of a new cue
                        this.cueStartTime = time;
                        else if (!this.displayedMemory.equals(this.lastOutputScreen)) {
                            this.outputFilter.newCue(this.cueStartTime, time, this.lastOutputScreen);
                            if (dispatch && this.outputFilter.dispatchCue) this.outputFilter.dispatchCue();
                            this.cueStartTime = this.displayedMemory.isEmpty() ? null : time;
                        }
                        this.lastOutputScreen.copy(this.displayedMemory);
                    }
                };
                _proto6.cueSplitAtTime = function cueSplitAtTime(t) {
                    if (this.outputFilter) {
                        if (!this.displayedMemory.isEmpty()) {
                            if (this.outputFilter.newCue) this.outputFilter.newCue(this.cueStartTime, t, this.displayedMemory);
                            this.cueStartTime = t;
                        }
                    }
                };
                return Cea608Channel;
            }();
            var Cea608Parser1 = /*#__PURE__*/ function() {
                function Cea608Parser(field, out1, out2) {
                    this.channels = void 0;
                    this.currentChannel = 0;
                    this.cmdHistory = void 0;
                    this.logger = void 0;
                    var logger = new cea_608_parser_CaptionsLogger();
                    this.channels = [
                        null,
                        new Cea608Channel1(field, out1, logger),
                        new Cea608Channel1(field + 1, out2, logger)
                    ];
                    this.cmdHistory = createCmdHistory();
                    this.logger = logger;
                }
                var _proto7 = Cea608Parser.prototype;
                _proto7.getHandler = function getHandler(channel) {
                    return this.channels[channel].getHandler();
                };
                _proto7.setHandler = function setHandler(channel, newHandler) {
                    this.channels[channel].setHandler(newHandler);
                };
                _proto7.addData = function addData(time, byteList) {
                    var cmdFound;
                    var a;
                    var b;
                    var charsFound = false;
                    this.logger.time = time;
                    for(var i = 0; i < byteList.length; i += 2){
                        a = byteList[i] & 127;
                        b = byteList[i + 1] & 127;
                        if (a === 0 && b === 0) continue;
                        else this.logger.log(VerboseLevel1.DATA, '[' + numArrayToHexArray([
                            byteList[i],
                            byteList[i + 1]
                        ]) + '] -> (' + numArrayToHexArray([
                            a,
                            b
                        ]) + ')');
                        cmdFound = this.parseCmd(a, b);
                        if (!cmdFound) cmdFound = this.parseMidrow(a, b);
                        if (!cmdFound) cmdFound = this.parsePAC(a, b);
                        if (!cmdFound) cmdFound = this.parseBackgroundAttributes(a, b);
                        if (!cmdFound) {
                            charsFound = this.parseChars(a, b);
                            if (charsFound) {
                                var currChNr = this.currentChannel;
                                if (currChNr && currChNr > 0) {
                                    var channel = this.channels[currChNr];
                                    channel.insertChars(charsFound);
                                } else this.logger.log(VerboseLevel1.WARNING, 'No channel found yet. TEXT-MODE?');
                            }
                        }
                        if (!cmdFound && !charsFound) this.logger.log(VerboseLevel1.WARNING, 'Couldn\'t parse cleaned data ' + numArrayToHexArray([
                            a,
                            b
                        ]) + ' orig: ' + numArrayToHexArray([
                            byteList[i],
                            byteList[i + 1]
                        ]));
                    }
                };
                _proto7.parseCmd = function parseCmd(a, b) {
                    var cmdHistory = this.cmdHistory;
                    var cond1 = (a === 20 || a === 28 || a === 21 || a === 29) && b >= 32 && b <= 47;
                    var cond2 = (a === 23 || a === 31) && b >= 33 && b <= 35;
                    if (!(cond1 || cond2)) return false;
                    if (hasCmdRepeated(a, b, cmdHistory)) {
                        setLastCmd(null, null, cmdHistory);
                        this.logger.log(VerboseLevel1.DEBUG, 'Repeated command (' + numArrayToHexArray([
                            a,
                            b
                        ]) + ') is dropped');
                        return true;
                    }
                    var chNr = a === 20 || a === 21 || a === 23 ? 1 : 2;
                    var channel = this.channels[chNr];
                    if (a === 20 || a === 21 || a === 28 || a === 29) {
                        if (b === 32) channel.ccRCL();
                        else if (b === 33) channel.ccBS();
                        else if (b === 34) channel.ccAOF();
                        else if (b === 35) channel.ccAON();
                        else if (b === 36) channel.ccDER();
                        else if (b === 37) channel.ccRU(2);
                        else if (b === 38) channel.ccRU(3);
                        else if (b === 39) channel.ccRU(4);
                        else if (b === 40) channel.ccFON();
                        else if (b === 41) channel.ccRDC();
                        else if (b === 42) channel.ccTR();
                        else if (b === 43) channel.ccRTD();
                        else if (b === 44) channel.ccEDM();
                        else if (b === 45) channel.ccCR();
                        else if (b === 46) channel.ccENM();
                        else if (b === 47) channel.ccEOC();
                    } else // a == 0x17 || a == 0x1F
                    channel.ccTO(b - 32);
                    setLastCmd(a, b, cmdHistory);
                    this.currentChannel = chNr;
                    return true;
                };
                _proto7.parseMidrow = function parseMidrow(a, b) {
                    var chNr = 0;
                    if ((a === 17 || a === 25) && b >= 32 && b <= 47) {
                        if (a === 17) chNr = 1;
                        else chNr = 2;
                        if (chNr !== this.currentChannel) {
                            this.logger.log(VerboseLevel1.ERROR, 'Mismatch channel in midrow parsing');
                            return false;
                        }
                        var channel = this.channels[chNr];
                        if (!channel) return false;
                        channel.ccMIDROW(b);
                        this.logger.log(VerboseLevel1.DEBUG, 'MIDROW (' + numArrayToHexArray([
                            a,
                            b
                        ]) + ')');
                        return true;
                    }
                    return false;
                };
                _proto7.parsePAC = function parsePAC(a, b) {
                    var row;
                    var cmdHistory = this.cmdHistory;
                    var case1 = (a >= 17 && a <= 23 || a >= 25 && a <= 31) && b >= 64 && b <= 127;
                    var case2 = (a === 16 || a === 24) && b >= 64 && b <= 95;
                    if (!(case1 || case2)) return false;
                    if (hasCmdRepeated(a, b, cmdHistory)) {
                        setLastCmd(null, null, cmdHistory);
                        return true; // Repeated commands are dropped (once)
                    }
                    var chNr = a <= 23 ? 1 : 2;
                    if (b >= 64 && b <= 95) row = chNr === 1 ? rowsLowCh1[a] : rowsLowCh2[a];
                    else // 0x60 <= b <= 0x7F
                    row = chNr === 1 ? rowsHighCh1[a] : rowsHighCh2[a];
                    var channel = this.channels[chNr];
                    if (!channel) return false;
                    channel.setPAC(this.interpretPAC(row, b));
                    setLastCmd(a, b, cmdHistory);
                    this.currentChannel = chNr;
                    return true;
                };
                _proto7.interpretPAC = function interpretPAC(row, _byte3) {
                    var pacIndex = _byte3;
                    var pacData = {
                        color: null,
                        italics: false,
                        indent: null,
                        underline: false,
                        row: row
                    };
                    if (_byte3 > 95) pacIndex = _byte3 - 96;
                    else pacIndex = _byte3 - 64;
                    pacData.underline = (pacIndex & 1) === 1;
                    if (pacIndex <= 13) pacData.color = [
                        'white',
                        'green',
                        'blue',
                        'cyan',
                        'red',
                        'yellow',
                        'magenta',
                        'white'
                    ][Math.floor(pacIndex / 2)];
                    else if (pacIndex <= 15) {
                        pacData.italics = true;
                        pacData.color = 'white';
                    } else pacData.indent = Math.floor((pacIndex - 16) / 2) * 4;
                    return pacData; // Note that row has zero offset. The spec uses 1.
                };
                _proto7.parseChars = function parseChars(a, b) {
                    var channelNr;
                    var charCodes = null;
                    var charCode1 = null;
                    if (a >= 25) {
                        channelNr = 2;
                        charCode1 = a - 8;
                    } else {
                        channelNr = 1;
                        charCode1 = a;
                    }
                    if (charCode1 >= 17 && charCode1 <= 19) {
                        // Special character
                        var oneCode = b;
                        if (charCode1 === 17) oneCode = b + 80;
                        else if (charCode1 === 18) oneCode = b + 112;
                        else oneCode = b + 144;
                        this.logger.log(VerboseLevel1.INFO, 'Special char \'' + getCharForByte(oneCode) + '\' in channel ' + channelNr);
                        charCodes = [
                            oneCode
                        ];
                    } else if (a >= 32 && a <= 127) charCodes = b === 0 ? [
                        a
                    ] : [
                        a,
                        b
                    ];
                    if (charCodes) {
                        var hexCodes = numArrayToHexArray(charCodes);
                        this.logger.log(VerboseLevel1.DEBUG, 'Char codes =  ' + hexCodes.join(','));
                        setLastCmd(a, b, this.cmdHistory);
                    }
                    return charCodes;
                };
                _proto7.parseBackgroundAttributes = function parseBackgroundAttributes(a, b) {
                    var case1 = (a === 16 || a === 24) && b >= 32 && b <= 47;
                    var case2 = (a === 23 || a === 31) && b >= 45 && b <= 47;
                    if (!(case1 || case2)) return false;
                    var index;
                    var bkgData = {
                    };
                    if (a === 16 || a === 24) {
                        index = Math.floor((b - 32) / 2);
                        bkgData.background = backgroundColors[index];
                        if (b % 2 === 1) bkgData.background = bkgData.background + '_semi';
                    } else if (b === 45) bkgData.background = 'transparent';
                    else {
                        bkgData.foreground = 'black';
                        if (b === 47) bkgData.underline = true;
                    }
                    var chNr = a <= 23 ? 1 : 2;
                    var channel = this.channels[chNr];
                    channel.setBkgData(bkgData);
                    setLastCmd(a, b, this.cmdHistory);
                    return true;
                };
                _proto7.reset = function reset() {
                    for(var i = 0; i < Object.keys(this.channels).length; i++){
                        var channel = this.channels[i];
                        if (channel) channel.reset();
                    }
                    this.cmdHistory = createCmdHistory();
                };
                _proto7.cueSplitAtTime = function cueSplitAtTime(t) {
                    for(var i = 0; i < this.channels.length; i++){
                        var channel = this.channels[i];
                        if (channel) channel.cueSplitAtTime(t);
                    }
                };
                return Cea608Parser;
            }();
            function setLastCmd(a, b, cmdHistory) {
                cmdHistory.a = a;
                cmdHistory.b = b;
            }
            function hasCmdRepeated(a, b, cmdHistory) {
                return cmdHistory.a === a && cmdHistory.b === b;
            }
            function createCmdHistory() {
                return {
                    a: null,
                    b: null
                };
            }
            /* harmony default export */ var cea_608_parser = Cea608Parser1;
            // CONCATENATED MODULE: ./src/utils/output-filter.ts
            var OutputFilter1 = /*#__PURE__*/ function() {
                function OutputFilter(timelineController, trackName) {
                    this.timelineController = void 0;
                    this.cueRanges = [];
                    this.trackName = void 0;
                    this.startTime = null;
                    this.endTime = null;
                    this.screen = null;
                    this.timelineController = timelineController;
                    this.trackName = trackName;
                }
                var _proto = OutputFilter.prototype;
                _proto.dispatchCue = function dispatchCue() {
                    if (this.startTime === null) return;
                    this.timelineController.addCues(this.trackName, this.startTime, this.endTime, this.screen, this.cueRanges);
                    this.startTime = null;
                };
                _proto.newCue = function newCue(startTime, endTime, screen) {
                    if (this.startTime === null || this.startTime > startTime) this.startTime = startTime;
                    this.endTime = endTime;
                    this.screen = screen;
                    this.timelineController.createCaptionsTrack(this.trackName);
                };
                _proto.reset = function reset() {
                    this.cueRanges = [];
                };
                return OutputFilter;
            }();
            // CONCATENATED MODULE: ./src/utils/webvtt-parser.js
            // String.prototype.startsWith is not supported in IE11
            var startsWith = function startsWith(inputString, searchString, position) {
                return inputString.substr(position || 0, searchString.length) === searchString;
            };
            var webvtt_parser_cueString2millis = function cueString2millis(timeString) {
                var ts = parseInt(timeString.substr(-3));
                var secs = parseInt(timeString.substr(-6, 2));
                var mins = parseInt(timeString.substr(-9, 2));
                var hours = timeString.length > 9 ? parseInt(timeString.substr(0, timeString.indexOf(':'))) : 0;
                if (!Object(number["isFiniteNumber"])(ts) || !Object(number["isFiniteNumber"])(secs) || !Object(number["isFiniteNumber"])(mins) || !Object(number["isFiniteNumber"])(hours)) throw Error("Malformed X-TIMESTAMP-MAP: Local:" + timeString);
                ts += 1000 * secs;
                ts += 60000 * mins;
                ts += 3600000 * hours;
                return ts;
            }; // From https://github.com/darkskyapp/string-hash
            var hash1 = function hash(text) {
                var hash = 5381;
                var i = text.length;
                while(i)hash = hash * 33 ^ text.charCodeAt(--i);
                return (hash >>> 0).toString();
            };
            var calculateOffset = function calculateOffset(vttCCs, cc, presentationTime) {
                var currCC = vttCCs[cc];
                var prevCC = vttCCs[currCC.prevCC]; // This is the first discontinuity or cues have been processed since the last discontinuity
                // Offset = current discontinuity time
                if (!prevCC || !prevCC.new && currCC.new) {
                    vttCCs.ccOffset = vttCCs.presentationOffset = currCC.start;
                    currCC.new = false;
                    return;
                } // There have been discontinuities since cues were last parsed.
                // Offset = time elapsed
                while(prevCC && prevCC.new){
                    vttCCs.ccOffset += currCC.start - prevCC.start;
                    currCC.new = false;
                    currCC = prevCC;
                    prevCC = vttCCs[currCC.prevCC];
                }
                vttCCs.presentationOffset = presentationTime;
            };
            var WebVTTParser = {
                parse: function parse(vttByteArray, syncPTS, vttCCs, cc, callBack, errorCallBack) {
                    // Convert byteArray into string, replacing any somewhat exotic linefeeds with "\n", then split on that character.
                    var re = /\r\n|\n\r|\n|\r/g; // Uint8Array.prototype.reduce is not implemented in IE11
                    var vttLines = Object(id3["utf8ArrayToStr"])(new Uint8Array(vttByteArray)).trim().replace(re, '\n').split('\n');
                    var cueTime = '00:00.000';
                    var mpegTs = 0;
                    var localTime = 0;
                    var presentationTime = 0;
                    var cues = [];
                    var parsingError;
                    var inHeader = true;
                    var timestampMap = false; // let VTTCue = VTTCue || window.TextTrackCue;
                    // Create parser object using VTTCue with TextTrackCue fallback on certain browsers.
                    var parser = new vttparser();
                    parser.oncue = function(cue) {
                        // Adjust cue timing; clamp cues to start no earlier than - and drop cues that don't end after - 0 on timeline.
                        var currCC = vttCCs[cc];
                        var cueOffset = vttCCs.ccOffset; // Update offsets for new discontinuities
                        if (currCC && currCC.new) {
                            if (localTime !== undefined) // When local time is provided, offset = discontinuity start time - local time
                            cueOffset = vttCCs.ccOffset = currCC.start;
                            else calculateOffset(vttCCs, cc, presentationTime);
                        }
                        if (presentationTime) // If we have MPEGTS, offset = presentation time + discontinuity offset
                        cueOffset = presentationTime - vttCCs.presentationOffset;
                        if (timestampMap) {
                            cue.startTime += cueOffset - localTime;
                            cue.endTime += cueOffset - localTime;
                        } // Create a unique hash id for a cue based on start/end times and text.
                        // This helps timeline-controller to avoid showing repeated captions.
                        cue.id = hash1(cue.startTime.toString()) + hash1(cue.endTime.toString()) + hash1(cue.text); // Fix encoding of special characters. TODO: Test with all sorts of weird characters.
                        cue.text = decodeURIComponent(encodeURIComponent(cue.text));
                        if (cue.endTime > 0) cues.push(cue);
                    };
                    parser.onparsingerror = function(e) {
                        parsingError = e;
                    };
                    parser.onflush = function() {
                        if (parsingError && errorCallBack) {
                            errorCallBack(parsingError);
                            return;
                        }
                        callBack(cues);
                    }; // Go through contents line by line.
                    vttLines.forEach(function(line) {
                        if (inHeader) {
                            // Look for X-TIMESTAMP-MAP in header.
                            if (startsWith(line, 'X-TIMESTAMP-MAP=')) {
                                // Once found, no more are allowed anyway, so stop searching.
                                inHeader = false;
                                timestampMap = true; // Extract LOCAL and MPEGTS.
                                line.substr(16).split(',').forEach(function(timestamp) {
                                    if (startsWith(timestamp, 'LOCAL:')) cueTime = timestamp.substr(6);
                                    else if (startsWith(timestamp, 'MPEGTS:')) mpegTs = parseInt(timestamp.substr(7));
                                });
                                try {
                                    // Calculate subtitle offset in milliseconds.
                                    if (syncPTS + (vttCCs[cc].start * 90000 || 0) < 0) syncPTS += 8589934592;
                                     // Adjust MPEGTS by sync PTS.
                                    mpegTs -= syncPTS; // Convert cue time to seconds
                                    localTime = webvtt_parser_cueString2millis(cueTime) / 1000; // Convert MPEGTS to seconds from 90kHz.
                                    presentationTime = mpegTs / 90000;
                                } catch (e) {
                                    timestampMap = false;
                                    parsingError = e;
                                } // Return without parsing X-TIMESTAMP-MAP line.
                                return;
                            } else if (line === '') inHeader = false;
                        } // Parse line by default.
                        parser.parse(line + '\n');
                    });
                    parser.flush();
                }
            };
            /* harmony default export */ var webvtt_parser = WebVTTParser;
            // CONCATENATED MODULE: ./src/controller/timeline-controller.ts
            function timeline_controller_assertThisInitialized(self) {
                if (self === void 0) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
                return self;
            }
            function timeline_controller_inheritsLoose(subClass, superClass) {
                subClass.prototype = Object.create(superClass.prototype);
                subClass.prototype.constructor = subClass;
                subClass.__proto__ = superClass;
            }
            var timeline_controller_TimelineController = /*#__PURE__*/ function(_EventHandler) {
                timeline_controller_inheritsLoose(TimelineController, _EventHandler);
                function TimelineController(hls) {
                    var _this;
                    _this = _EventHandler.call(this, hls, events1["default"].MEDIA_ATTACHING, events1["default"].MEDIA_DETACHING, events1["default"].FRAG_PARSING_USERDATA, events1["default"].FRAG_DECRYPTED, events1["default"].MANIFEST_LOADING, events1["default"].MANIFEST_LOADED, events1["default"].FRAG_LOADED, events1["default"].INIT_PTS_FOUND) || this;
                    _this.media = null;
                    _this.config = void 0;
                    _this.enabled = true;
                    _this.Cues = void 0;
                    _this.textTracks = [];
                    _this.tracks = [];
                    _this.initPTS = [];
                    _this.unparsedVttFrags = [];
                    _this.captionsTracks = {
                    };
                    _this.nonNativeCaptionsTracks = {
                    };
                    _this.captionsProperties = void 0;
                    _this.cea608Parser1 = void 0;
                    _this.cea608Parser2 = void 0;
                    _this.lastSn = -1;
                    _this.prevCC = -1;
                    _this.vttCCs = newVTTCCs();
                    _this.hls = hls;
                    _this.config = hls.config;
                    _this.Cues = hls.config.cueHandler;
                    _this.captionsProperties = {
                        textTrack1: {
                            label: _this.config.captionsTextTrack1Label,
                            languageCode: _this.config.captionsTextTrack1LanguageCode
                        },
                        textTrack2: {
                            label: _this.config.captionsTextTrack2Label,
                            languageCode: _this.config.captionsTextTrack2LanguageCode
                        },
                        textTrack3: {
                            label: _this.config.captionsTextTrack3Label,
                            languageCode: _this.config.captionsTextTrack3LanguageCode
                        },
                        textTrack4: {
                            label: _this.config.captionsTextTrack4Label,
                            languageCode: _this.config.captionsTextTrack4LanguageCode
                        }
                    };
                    if (_this.config.enableCEA708Captions) {
                        var channel1 = new OutputFilter1(timeline_controller_assertThisInitialized(_this), 'textTrack1');
                        var channel2 = new OutputFilter1(timeline_controller_assertThisInitialized(_this), 'textTrack2');
                        var channel3 = new OutputFilter1(timeline_controller_assertThisInitialized(_this), 'textTrack3');
                        var channel4 = new OutputFilter1(timeline_controller_assertThisInitialized(_this), 'textTrack4');
                        _this.cea608Parser1 = new cea_608_parser(1, channel1, channel2);
                        _this.cea608Parser2 = new cea_608_parser(3, channel3, channel4);
                    }
                    return _this;
                }
                var _proto = TimelineController.prototype;
                _proto.addCues = function addCues(trackName, startTime, endTime, screen, cueRanges) {
                    // skip cues which overlap more than 50% with previously parsed time ranges
                    var merged = false;
                    for(var i = cueRanges.length; i--;){
                        var cueRange = cueRanges[i];
                        var overlap = intersection(cueRange[0], cueRange[1], startTime, endTime);
                        if (overlap >= 0) {
                            cueRange[0] = Math.min(cueRange[0], startTime);
                            cueRange[1] = Math.max(cueRange[1], endTime);
                            merged = true;
                            if (overlap / (endTime - startTime) > 0.5) return;
                        }
                    }
                    if (!merged) cueRanges.push([
                        startTime,
                        endTime
                    ]);
                    if (this.config.renderTextTracksNatively) this.Cues.newCue(this.captionsTracks[trackName], startTime, endTime, screen);
                    else {
                        var cues = this.Cues.newCue(null, startTime, endTime, screen);
                        this.hls.trigger(events1["default"].CUES_PARSED, {
                            type: 'captions',
                            cues: cues,
                            track: trackName
                        });
                    }
                } // Triggered when an initial PTS is found; used for synchronisation of WebVTT.
                ;
                _proto.onInitPtsFound = function onInitPtsFound(data) {
                    var _this2 = this;
                    var frag4 = data.frag, id = data.id, initPTS = data.initPTS;
                    var unparsedVttFrags = this.unparsedVttFrags;
                    if (id === 'main') this.initPTS[frag4.cc] = initPTS;
                     // Due to asynchronous processing, initial PTS may arrive later than the first VTT fragments are loaded.
                    // Parse any unparsed fragments upon receiving the initial PTS.
                    if (unparsedVttFrags.length) {
                        this.unparsedVttFrags = [];
                        unparsedVttFrags.forEach(function(frag) {
                            _this2.onFragLoaded(frag);
                        });
                    }
                };
                _proto.getExistingTrack = function getExistingTrack(trackName) {
                    var media = this.media;
                    if (media) for(var i = 0; i < media.textTracks.length; i++){
                        var textTrack = media.textTracks[i];
                        if (textTrack[trackName]) return textTrack;
                    }
                    return null;
                };
                _proto.createCaptionsTrack = function createCaptionsTrack(trackName) {
                    if (this.config.renderTextTracksNatively) this.createNativeTrack(trackName);
                    else this.createNonNativeTrack(trackName);
                };
                _proto.createNativeTrack = function createNativeTrack(trackName) {
                    if (this.captionsTracks[trackName]) return;
                    var captionsProperties = this.captionsProperties, captionsTracks = this.captionsTracks, media = this.media;
                    var _captionsProperties$t = captionsProperties[trackName], label = _captionsProperties$t.label, languageCode = _captionsProperties$t.languageCode; // Enable reuse of existing text track.
                    var existingTrack = this.getExistingTrack(trackName);
                    if (!existingTrack) {
                        var textTrack = this.createTextTrack('captions', label, languageCode);
                        if (textTrack) {
                            // Set a special property on the track so we know it's managed by Hls.js
                            textTrack[trackName] = true;
                            captionsTracks[trackName] = textTrack;
                        }
                    } else {
                        captionsTracks[trackName] = existingTrack;
                        clearCurrentCues(captionsTracks[trackName]);
                        sendAddTrackEvent(captionsTracks[trackName], media);
                    }
                };
                _proto.createNonNativeTrack = function createNonNativeTrack(trackName) {
                    if (this.nonNativeCaptionsTracks[trackName]) return;
                     // Create a list of a single track for the provider to consume
                    var trackProperties = this.captionsProperties[trackName];
                    if (!trackProperties) return;
                    var label = trackProperties.label;
                    var track = {
                        _id: trackName,
                        label: label,
                        kind: 'captions',
                        default: trackProperties.media ? !!trackProperties.media.default : false,
                        closedCaptions: trackProperties.media
                    };
                    this.nonNativeCaptionsTracks[trackName] = track;
                    this.hls.trigger(events1["default"].NON_NATIVE_TEXT_TRACKS_FOUND, {
                        tracks: [
                            track
                        ]
                    });
                };
                _proto.createTextTrack = function createTextTrack(kind, label, lang) {
                    var media = this.media;
                    if (!media) return;
                    return media.addTextTrack(kind, label, lang);
                };
                _proto.destroy = function destroy() {
                    _EventHandler.prototype.destroy.call(this);
                };
                _proto.onMediaAttaching = function onMediaAttaching(data) {
                    this.media = data.media;
                    this._cleanTracks();
                };
                _proto.onMediaDetaching = function onMediaDetaching() {
                    var captionsTracks = this.captionsTracks;
                    Object.keys(captionsTracks).forEach(function(trackName) {
                        clearCurrentCues(captionsTracks[trackName]);
                        delete captionsTracks[trackName];
                    });
                    this.nonNativeCaptionsTracks = {
                    };
                };
                _proto.onManifestLoading = function onManifestLoading() {
                    this.lastSn = -1; // Detect discontiguity in fragment parsing
                    this.prevCC = -1;
                    this.vttCCs = newVTTCCs(); // Detect discontinuity in subtitle manifests
                    this._cleanTracks();
                    this.tracks = [];
                    this.captionsTracks = {
                    };
                    this.nonNativeCaptionsTracks = {
                    };
                };
                _proto._cleanTracks = function _cleanTracks() {
                    // clear outdated subtitles
                    var media = this.media;
                    if (!media) return;
                    var textTracks = media.textTracks;
                    if (textTracks) for(var i = 0; i < textTracks.length; i++)clearCurrentCues(textTracks[i]);
                };
                _proto.onManifestLoaded = function onManifestLoaded(data) {
                    var _this3 = this;
                    this.textTracks = [];
                    this.unparsedVttFrags = this.unparsedVttFrags || [];
                    this.initPTS = [];
                    if (this.cea608Parser1 && this.cea608Parser2) {
                        this.cea608Parser1.reset();
                        this.cea608Parser2.reset();
                    }
                    if (this.config.enableWebVTT) {
                        var tracks = data.subtitles || [];
                        var sameTracks = this.tracks && tracks && this.tracks.length === tracks.length;
                        this.tracks = data.subtitles || [];
                        if (this.config.renderTextTracksNatively) {
                            var inUseTracks = this.media ? this.media.textTracks : [];
                            this.tracks.forEach(function(track, index) {
                                var textTrack;
                                if (index < inUseTracks.length) {
                                    var inUseTrack = null;
                                    for(var i = 0; i < inUseTracks.length; i++)if (canReuseVttTextTrack(inUseTracks[i], track)) {
                                        inUseTrack = inUseTracks[i];
                                        break;
                                    }
                                     // Reuse tracks with the same label, but do not reuse 608/708 tracks
                                    if (inUseTrack) textTrack = inUseTrack;
                                }
                                if (!textTrack) textTrack = _this3.createTextTrack('subtitles', track.name, track.lang);
                                if (track.default) textTrack.mode = _this3.hls.subtitleDisplay ? 'showing' : 'hidden';
                                else textTrack.mode = 'disabled';
                                _this3.textTracks.push(textTrack);
                            });
                        } else if (!sameTracks && this.tracks && this.tracks.length) {
                            // Create a list of tracks for the provider to consume
                            var tracksList = this.tracks.map(function(track) {
                                return {
                                    label: track.name,
                                    kind: track.type.toLowerCase(),
                                    default: track.default,
                                    subtitleTrack: track
                                };
                            });
                            this.hls.trigger(events1["default"].NON_NATIVE_TEXT_TRACKS_FOUND, {
                                tracks: tracksList
                            });
                        }
                    }
                    if (this.config.enableCEA708Captions && data.captions) data.captions.forEach(function(captionsTrack) {
                        var instreamIdMatch = /(?:CC|SERVICE)([1-4])/.exec(captionsTrack.instreamId);
                        if (!instreamIdMatch) return;
                        var trackName = "textTrack" + instreamIdMatch[1];
                        var trackProperties = _this3.captionsProperties[trackName];
                        if (!trackProperties) return;
                        trackProperties.label = captionsTrack.name;
                        if (captionsTrack.lang) // optional attribute
                        trackProperties.languageCode = captionsTrack.lang;
                        trackProperties.media = captionsTrack;
                    });
                };
                _proto.onFragLoaded = function onFragLoaded(data) {
                    var frag = data.frag, payload = data.payload;
                    var cea608Parser1 = this.cea608Parser1, cea608Parser2 = this.cea608Parser2, initPTS = this.initPTS, lastSn = this.lastSn, unparsedVttFrags = this.unparsedVttFrags;
                    if (frag.type === 'main') {
                        var sn = frag.sn; // if this frag isn't contiguous, clear the parser so cues with bad start/end times aren't added to the textTrack
                        if (frag.sn !== lastSn + 1) {
                            if (cea608Parser1 && cea608Parser2) {
                                cea608Parser1.reset();
                                cea608Parser2.reset();
                            }
                        }
                        this.lastSn = sn;
                    } else if (frag.type === 'subtitle') {
                        if (payload.byteLength) {
                            // We need an initial synchronisation PTS. Store fragments as long as none has arrived.
                            if (!Object(number["isFiniteNumber"])(initPTS[frag.cc])) {
                                unparsedVttFrags.push(data);
                                if (initPTS.length) // finish unsuccessfully, otherwise the subtitle-stream-controller could be blocked from loading new frags.
                                this.hls.trigger(events1["default"].SUBTITLE_FRAG_PROCESSED, {
                                    success: false,
                                    frag: frag
                                });
                                return;
                            }
                            var decryptData = frag.decryptdata; // If the subtitles are not encrypted, parse VTTs now. Otherwise, we need to wait.
                            if (decryptData == null || decryptData.key == null || decryptData.method !== 'AES-128') this._parseVTTs(frag, payload);
                        } else // In case there is no payload, finish unsuccessfully.
                        this.hls.trigger(events1["default"].SUBTITLE_FRAG_PROCESSED, {
                            success: false,
                            frag: frag
                        });
                    }
                };
                _proto._parseVTTs = function _parseVTTs(frag, payload) {
                    var _this4 = this;
                    var hls = this.hls, prevCC = this.prevCC, textTracks = this.textTracks, vttCCs = this.vttCCs;
                    if (!vttCCs[frag.cc]) {
                        vttCCs[frag.cc] = {
                            start: frag.start,
                            prevCC: prevCC,
                            new: true
                        };
                        this.prevCC = frag.cc;
                    } // Parse the WebVTT file contents.
                    webvtt_parser.parse(payload, this.initPTS[frag.cc], vttCCs, frag.cc, function(cues) {
                        if (_this4.config.renderTextTracksNatively) {
                            var currentTrack = textTracks[frag.level]; // WebVTTParser.parse is an async method and if the currently selected text track mode is set to "disabled"
                            // before parsing is done then don't try to access currentTrack.cues.getCueById as cues will be null
                            // and trying to access getCueById method of cues will throw an exception
                            // Because we check if the mode is diabled, we can force check `cues` below. They can't be null.
                            if (currentTrack.mode === 'disabled') {
                                hls.trigger(events1["default"].SUBTITLE_FRAG_PROCESSED, {
                                    success: false,
                                    frag: frag
                                });
                                return;
                            } // Add cues and trigger event with success true.
                            cues.forEach(function(cue) {
                                // Sometimes there are cue overlaps on segmented vtts so the same
                                // cue can appear more than once in different vtt files.
                                // This avoid showing duplicated cues with same timecode and text.
                                if (!currentTrack.cues.getCueById(cue.id)) try {
                                    currentTrack.addCue(cue);
                                    if (!currentTrack.cues.getCueById(cue.id)) throw new Error("addCue is failed for: " + cue);
                                } catch (err) {
                                    logger1["logger"].debug("Failed occurred on adding cues: " + err);
                                    var textTrackCue = new window.TextTrackCue(cue.startTime, cue.endTime, cue.text);
                                    textTrackCue.id = cue.id;
                                    currentTrack.addCue(textTrackCue);
                                }
                            });
                        } else {
                            var trackId = _this4.tracks[frag.level].default ? 'default' : 'subtitles' + frag.level;
                            hls.trigger(events1["default"].CUES_PARSED, {
                                type: 'subtitles',
                                cues: cues,
                                track: trackId
                            });
                        }
                        hls.trigger(events1["default"].SUBTITLE_FRAG_PROCESSED, {
                            success: true,
                            frag: frag
                        });
                    }, function(e) {
                        // Something went wrong while parsing. Trigger event with success false.
                        logger1["logger"].log("Failed to parse VTT cue: " + e);
                        hls.trigger(events1["default"].SUBTITLE_FRAG_PROCESSED, {
                            success: false,
                            frag: frag
                        });
                    });
                };
                _proto.onFragDecrypted = function onFragDecrypted(data) {
                    var frag = data.frag, payload = data.payload;
                    if (frag.type === 'subtitle') {
                        if (!Object(number["isFiniteNumber"])(this.initPTS[frag.cc])) {
                            this.unparsedVttFrags.push(data);
                            return;
                        }
                        this._parseVTTs(frag, payload);
                    }
                };
                _proto.onFragParsingUserdata = function onFragParsingUserdata(data) {
                    var cea608Parser1 = this.cea608Parser1, cea608Parser2 = this.cea608Parser2;
                    if (!this.enabled || !(cea608Parser1 && cea608Parser2)) return;
                     // If the event contains captions (found in the bytes property), push all bytes into the parser immediately
                    // It will create the proper timestamps based on the PTS value
                    for(var i = 0; i < data.samples.length; i++){
                        var ccBytes = data.samples[i].bytes;
                        if (ccBytes) {
                            var ccdatas = this.extractCea608Data(ccBytes);
                            cea608Parser1.addData(data.samples[i].pts, ccdatas[0]);
                            cea608Parser2.addData(data.samples[i].pts, ccdatas[1]);
                        }
                    }
                };
                _proto.extractCea608Data = function extractCea608Data(byteArray) {
                    var count = byteArray[0] & 31;
                    var position = 2;
                    var actualCCBytes = [
                        [],
                        []
                    ];
                    for(var j = 0; j < count; j++){
                        var tmpByte = byteArray[position++];
                        var ccbyte1 = 127 & byteArray[position++];
                        var ccbyte2 = 127 & byteArray[position++];
                        var ccValid = (4 & tmpByte) !== 0;
                        var ccType = 3 & tmpByte;
                        if (ccbyte1 === 0 && ccbyte2 === 0) continue;
                        if (ccValid) {
                            if (ccType === 0 || ccType === 1) {
                                actualCCBytes[ccType].push(ccbyte1);
                                actualCCBytes[ccType].push(ccbyte2);
                            }
                        }
                    }
                    return actualCCBytes;
                };
                return TimelineController;
            }(event_handler);
            function canReuseVttTextTrack(inUseTrack, manifestTrack) {
                return inUseTrack && inUseTrack.label === manifestTrack.name && !(inUseTrack.textTrack1 || inUseTrack.textTrack2);
            }
            function intersection(x1, x2, y1, y2) {
                return Math.min(x2, y2) - Math.max(x1, y1);
            }
            function newVTTCCs() {
                return {
                    ccOffset: 0,
                    presentationOffset: 0,
                    0: {
                        start: 0,
                        prevCC: -1,
                        new: false
                    }
                };
            }
            /* harmony default export */ var timeline_controller = timeline_controller_TimelineController;
            // CONCATENATED MODULE: ./src/controller/subtitle-track-controller.js
            function subtitle_track_controller_defineProperties(target, props) {
                for(var i = 0; i < props.length; i++){
                    var descriptor = props[i];
                    descriptor.enumerable = descriptor.enumerable || false;
                    descriptor.configurable = true;
                    if ("value" in descriptor) descriptor.writable = true;
                    Object.defineProperty(target, descriptor.key, descriptor);
                }
            }
            function subtitle_track_controller_createClass(Constructor, protoProps, staticProps) {
                if (protoProps) subtitle_track_controller_defineProperties(Constructor.prototype, protoProps);
                if (staticProps) subtitle_track_controller_defineProperties(Constructor, staticProps);
                return Constructor;
            }
            function subtitle_track_controller_inheritsLoose(subClass, superClass) {
                subClass.prototype = Object.create(superClass.prototype);
                subClass.prototype.constructor = subClass;
                subClass.__proto__ = superClass;
            }
            var subtitle_track_controller_SubtitleTrackController = /*#__PURE__*/ function(_EventHandler) {
                subtitle_track_controller_inheritsLoose(SubtitleTrackController, _EventHandler);
                function SubtitleTrackController(hls) {
                    var _this;
                    _this = _EventHandler.call(this, hls, events1["default"].MEDIA_ATTACHED, events1["default"].MEDIA_DETACHING, events1["default"].MANIFEST_LOADED, events1["default"].SUBTITLE_TRACK_LOADED) || this;
                    _this.tracks = [];
                    _this.trackId = -1;
                    _this.media = null;
                    _this.stopped = true;
                    /**
     * @member {boolean} subtitleDisplay Enable/disable subtitle display rendering
     */ _this.subtitleDisplay = true;
                    /**
     * Keeps reference to a default track id when media has not been attached yet
     * @member {number}
     */ _this.queuedDefaultTrack = null;
                    return _this;
                }
                var _proto = SubtitleTrackController.prototype;
                _proto.destroy = function destroy() {
                    event_handler.prototype.destroy.call(this);
                } // Listen for subtitle track change, then extract the current track ID.
                ;
                _proto.onMediaAttached = function onMediaAttached(data) {
                    var _this2 = this;
                    this.media = data.media;
                    if (!this.media) return;
                    if (Object(number["isFiniteNumber"])(this.queuedDefaultTrack)) {
                        this.subtitleTrack = this.queuedDefaultTrack;
                        this.queuedDefaultTrack = null;
                    }
                    this.trackChangeListener = this._onTextTracksChanged.bind(this);
                    this.useTextTrackPolling = !(this.media.textTracks && 'onchange' in this.media.textTracks);
                    if (this.useTextTrackPolling) this.subtitlePollingInterval = setInterval(function() {
                        _this2.trackChangeListener();
                    }, 500);
                    else this.media.textTracks.addEventListener('change', this.trackChangeListener);
                };
                _proto.onMediaDetaching = function onMediaDetaching() {
                    if (!this.media) return;
                    if (this.useTextTrackPolling) clearInterval(this.subtitlePollingInterval);
                    else this.media.textTracks.removeEventListener('change', this.trackChangeListener);
                    if (Object(number["isFiniteNumber"])(this.subtitleTrack)) this.queuedDefaultTrack = this.subtitleTrack;
                    var textTracks = filterSubtitleTracks(this.media.textTracks); // Clear loaded cues on media detachment from tracks
                    textTracks.forEach(function(track) {
                        clearCurrentCues(track);
                    }); // Disable all subtitle tracks before detachment so when reattached only tracks in that content are enabled.
                    this.subtitleTrack = -1;
                    this.media = null;
                } // Fired whenever a new manifest is loaded.
                ;
                _proto.onManifestLoaded = function onManifestLoaded(data) {
                    var _this3 = this;
                    var tracks = data.subtitles || [];
                    this.tracks = tracks;
                    this.hls.trigger(events1["default"].SUBTITLE_TRACKS_UPDATED, {
                        subtitleTracks: tracks
                    }); // loop through available subtitle tracks and autoselect default if needed
                    // TODO: improve selection logic to handle forced, etc
                    tracks.forEach(function(track) {
                        if (track.default) {
                            // setting this.subtitleTrack will trigger internal logic
                            // if media has not been attached yet, it will fail
                            // we keep a reference to the default track id
                            // and we'll set subtitleTrack when onMediaAttached is triggered
                            if (_this3.media) _this3.subtitleTrack = track.id;
                            else _this3.queuedDefaultTrack = track.id;
                        }
                    });
                };
                _proto.onSubtitleTrackLoaded = function onSubtitleTrackLoaded(data) {
                    var _this4 = this;
                    var id = data.id, details = data.details;
                    var trackId = this.trackId, tracks = this.tracks;
                    var currentTrack = tracks[trackId];
                    if (id >= tracks.length || id !== trackId || !currentTrack || this.stopped) {
                        this._clearReloadTimer();
                        return;
                    }
                    logger1["logger"].log("subtitle track " + id + " loaded");
                    if (details.live) {
                        var reloadInterval = computeReloadInterval(currentTrack.details, details, data.stats.trequest);
                        logger1["logger"].log("Reloading live subtitle playlist in " + reloadInterval + "ms");
                        this.timer = setTimeout(function() {
                            _this4._loadCurrentTrack();
                        }, reloadInterval);
                    } else this._clearReloadTimer();
                };
                _proto.startLoad = function startLoad() {
                    this.stopped = false;
                    this._loadCurrentTrack();
                };
                _proto.stopLoad = function stopLoad() {
                    this.stopped = true;
                    this._clearReloadTimer();
                };
                _proto._clearReloadTimer = function _clearReloadTimer() {
                    if (this.timer) {
                        clearTimeout(this.timer);
                        this.timer = null;
                    }
                };
                _proto._loadCurrentTrack = function _loadCurrentTrack() {
                    var trackId = this.trackId, tracks = this.tracks, hls = this.hls;
                    var currentTrack = tracks[trackId];
                    if (trackId < 0 || !currentTrack || currentTrack.details && !currentTrack.details.live) return;
                    logger1["logger"].log("Loading subtitle track " + trackId);
                    hls.trigger(events1["default"].SUBTITLE_TRACK_LOADING, {
                        url: currentTrack.url,
                        id: trackId
                    });
                };
                _proto._toggleTrackModes = function _toggleTrackModes(newId) {
                    var media = this.media, subtitleDisplay = this.subtitleDisplay, trackId = this.trackId;
                    if (!media) return;
                    var textTracks = filterSubtitleTracks(media.textTracks);
                    if (newId === -1) [].slice.call(textTracks).forEach(function(track) {
                        track.mode = 'disabled';
                    });
                    else {
                        var oldTrack = textTracks[trackId];
                        if (oldTrack) oldTrack.mode = 'disabled';
                    }
                    var nextTrack = textTracks[newId];
                    if (nextTrack) nextTrack.mode = subtitleDisplay ? 'showing' : 'hidden';
                };
                _proto._setSubtitleTrackInternal = function _setSubtitleTrackInternal(newId) {
                    var hls = this.hls, tracks = this.tracks;
                    if (!Object(number["isFiniteNumber"])(newId) || newId < -1 || newId >= tracks.length) return;
                    this.trackId = newId;
                    logger1["logger"].log("Switching to subtitle track " + newId);
                    hls.trigger(events1["default"].SUBTITLE_TRACK_SWITCH, {
                        id: newId
                    });
                    this._loadCurrentTrack();
                };
                _proto._onTextTracksChanged = function _onTextTracksChanged() {
                    // Media is undefined when switching streams via loadSource()
                    if (!this.media || !this.hls.config.renderTextTracksNatively) return;
                    var trackId = -1;
                    var tracks = filterSubtitleTracks(this.media.textTracks);
                    for(var id = 0; id < tracks.length; id++){
                        if (tracks[id].mode === 'hidden') // Do not break in case there is a following track with showing.
                        trackId = id;
                        else if (tracks[id].mode === 'showing') {
                            trackId = id;
                            break;
                        }
                    } // Setting current subtitleTrack will invoke code.
                    this.subtitleTrack = trackId;
                };
                subtitle_track_controller_createClass(SubtitleTrackController, [
                    {
                        key: "subtitleTracks",
                        get: function get() {
                            return this.tracks;
                        }
                    },
                    {
                        key: "subtitleTrack",
                        get: function get() {
                            return this.trackId;
                        },
                        set: function set(subtitleTrackId) {
                            if (this.trackId !== subtitleTrackId) {
                                this._toggleTrackModes(subtitleTrackId);
                                this._setSubtitleTrackInternal(subtitleTrackId);
                            }
                        }
                    }
                ]);
                return SubtitleTrackController;
            }(event_handler);
            function filterSubtitleTracks(textTrackList) {
                var tracks = [];
                for(var i = 0; i < textTrackList.length; i++){
                    var track = textTrackList[i]; // Edge adds a track without a label; we don't want to use it
                    if (track.kind === 'subtitles' && track.label) tracks.push(textTrackList[i]);
                }
                return tracks;
            }
            /* harmony default export */ var subtitle_track_controller = subtitle_track_controller_SubtitleTrackController;
            // EXTERNAL MODULE: ./src/crypt/decrypter.js + 3 modules
            var decrypter = __webpack_require__("./src/crypt/decrypter.js");
            // CONCATENATED MODULE: ./src/controller/subtitle-stream-controller.js
            function subtitle_stream_controller_assertThisInitialized(self) {
                if (self === void 0) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
                return self;
            }
            function subtitle_stream_controller_inheritsLoose(subClass, superClass) {
                subClass.prototype = Object.create(superClass.prototype);
                subClass.prototype.constructor = subClass;
                subClass.__proto__ = superClass;
            }
            /**
 * @class SubtitleStreamController
 */ var subtitle_stream_controller_window = window, subtitle_stream_controller_performance = subtitle_stream_controller_window.performance;
            var subtitle_stream_controller_TICK_INTERVAL = 500; // how often to tick in ms
            var subtitle_stream_controller_SubtitleStreamController = /*#__PURE__*/ function(_BaseStreamController) {
                subtitle_stream_controller_inheritsLoose(SubtitleStreamController, _BaseStreamController);
                function SubtitleStreamController(hls, fragmentTracker) {
                    var _this;
                    _this = _BaseStreamController.call(this, hls, events1["default"].MEDIA_ATTACHED, events1["default"].MEDIA_DETACHING, events1["default"].ERROR, events1["default"].KEY_LOADED, events1["default"].FRAG_LOADED, events1["default"].SUBTITLE_TRACKS_UPDATED, events1["default"].SUBTITLE_TRACK_SWITCH, events1["default"].SUBTITLE_TRACK_LOADED, events1["default"].SUBTITLE_FRAG_PROCESSED, events1["default"].LEVEL_UPDATED) || this;
                    _this.fragmentTracker = fragmentTracker;
                    _this.config = hls.config;
                    _this.state = State.STOPPED;
                    _this.tracks = [];
                    _this.tracksBuffered = [];
                    _this.currentTrackId = -1;
                    _this.decrypter = new decrypter["default"](hls, hls.config); // lastAVStart stores the time in seconds for the start time of a level load
                    _this.lastAVStart = 0;
                    _this._onMediaSeeking = _this.onMediaSeeking.bind(subtitle_stream_controller_assertThisInitialized(_this));
                    return _this;
                }
                var _proto = SubtitleStreamController.prototype;
                _proto.startLoad = function startLoad() {
                    this.stopLoad();
                    this.state = State.IDLE; // Check if we already have a track with necessary details to load fragments
                    var currentTrack = this.tracks[this.currentTrackId];
                    if (currentTrack && currentTrack.details) {
                        this.setInterval(subtitle_stream_controller_TICK_INTERVAL);
                        this.tick();
                    }
                };
                _proto.onSubtitleFragProcessed = function onSubtitleFragProcessed(data) {
                    var frag = data.frag, success = data.success;
                    this.fragPrevious = frag;
                    this.state = State.IDLE;
                    if (!success) return;
                    var buffered = this.tracksBuffered[this.currentTrackId];
                    if (!buffered) return;
                     // Create/update a buffered array matching the interface used by BufferHelper.bufferedInfo
                    // so we can re-use the logic used to detect how much have been buffered
                    var timeRange;
                    var fragStart = frag.start;
                    for(var i = 0; i < buffered.length; i++)if (fragStart >= buffered[i].start && fragStart <= buffered[i].end) {
                        timeRange = buffered[i];
                        break;
                    }
                    var fragEnd = frag.start + frag.duration;
                    if (timeRange) timeRange.end = fragEnd;
                    else {
                        timeRange = {
                            start: fragStart,
                            end: fragEnd
                        };
                        buffered.push(timeRange);
                    }
                };
                _proto.onMediaAttached = function onMediaAttached(_ref) {
                    var media = _ref.media;
                    this.media = media;
                    media.addEventListener('seeking', this._onMediaSeeking);
                    this.state = State.IDLE;
                };
                _proto.onMediaDetaching = function onMediaDetaching() {
                    var _this2 = this;
                    if (!this.media) return;
                    this.media.removeEventListener('seeking', this._onMediaSeeking);
                    this.fragmentTracker.removeAllFragments();
                    this.currentTrackId = -1;
                    this.tracks.forEach(function(track) {
                        _this2.tracksBuffered[track.id] = [];
                    });
                    this.media = null;
                    this.state = State.STOPPED;
                } // If something goes wrong, proceed to next frag, if we were processing one.
                ;
                _proto.onError = function onError(data) {
                    var frag = data.frag; // don't handle error not related to subtitle fragment
                    if (!frag || frag.type !== 'subtitle') return;
                    if (this.fragCurrent && this.fragCurrent.loader) this.fragCurrent.loader.abort();
                    this.state = State.IDLE;
                } // Got all new subtitle tracks.
                ;
                _proto.onSubtitleTracksUpdated = function onSubtitleTracksUpdated(data) {
                    var _this3 = this;
                    logger1["logger"].log('subtitle tracks updated');
                    this.tracksBuffered = [];
                    this.tracks = data.subtitleTracks;
                    this.tracks.forEach(function(track) {
                        _this3.tracksBuffered[track.id] = [];
                    });
                };
                _proto.onSubtitleTrackSwitch = function onSubtitleTrackSwitch(data) {
                    this.currentTrackId = data.id;
                    if (!this.tracks || !this.tracks.length || this.currentTrackId === -1) {
                        this.clearInterval();
                        return;
                    } // Check if track has the necessary details to load fragments
                    var currentTrack = this.tracks[this.currentTrackId];
                    if (currentTrack && currentTrack.details) this.setInterval(subtitle_stream_controller_TICK_INTERVAL);
                } // Got a new set of subtitle fragments.
                ;
                _proto.onSubtitleTrackLoaded = function onSubtitleTrackLoaded(data) {
                    var id = data.id, details = data.details;
                    var currentTrackId = this.currentTrackId, tracks = this.tracks;
                    var currentTrack = tracks[currentTrackId];
                    if (id >= tracks.length || id !== currentTrackId || !currentTrack) return;
                    if (details.live) mergeSubtitlePlaylists(currentTrack.details, details, this.lastAVStart);
                    currentTrack.details = details;
                    this.setInterval(subtitle_stream_controller_TICK_INTERVAL);
                };
                _proto.onKeyLoaded = function onKeyLoaded() {
                    if (this.state === State.KEY_LOADING) this.state = State.IDLE;
                };
                _proto.onFragLoaded = function onFragLoaded(data) {
                    var fragCurrent = this.fragCurrent;
                    var decryptData = data.frag.decryptdata;
                    var fragLoaded = data.frag;
                    var hls = this.hls;
                    if (this.state === State.FRAG_LOADING && fragCurrent && data.frag.type === 'subtitle' && fragCurrent.sn === data.frag.sn) // check to see if the payload needs to be decrypted
                    {
                        if (data.payload.byteLength > 0 && decryptData && decryptData.key && decryptData.method === 'AES-128') {
                            var startTime = subtitle_stream_controller_performance.now(); // decrypt the subtitles
                            this.decrypter.decrypt(data.payload, decryptData.key.buffer, decryptData.iv.buffer, function(decryptedData) {
                                var endTime = subtitle_stream_controller_performance.now();
                                hls.trigger(events1["default"].FRAG_DECRYPTED, {
                                    frag: fragLoaded,
                                    payload: decryptedData,
                                    stats: {
                                        tstart: startTime,
                                        tdecrypt: endTime
                                    }
                                });
                            });
                        }
                    }
                };
                _proto.onLevelUpdated = function onLevelUpdated(_ref2) {
                    var details = _ref2.details;
                    var frags = details.fragments;
                    this.lastAVStart = frags.length ? frags[0].start : 0;
                };
                _proto.doTick = function doTick() {
                    if (!this.media) {
                        this.state = State.IDLE;
                        return;
                    }
                    switch(this.state){
                        case State.IDLE:
                            var config = this.config, currentTrackId = this.currentTrackId, fragmentTracker = this.fragmentTracker, media = this.media, tracks = this.tracks;
                            if (!tracks || !tracks[currentTrackId] || !tracks[currentTrackId].details) break;
                            var maxBufferHole = config.maxBufferHole, maxFragLookUpTolerance = config.maxFragLookUpTolerance;
                            var maxConfigBuffer = Math.min(config.maxBufferLength, config.maxMaxBufferLength);
                            var bufferedInfo = BufferHelper1.bufferedInfo(this._getBuffered(), media.currentTime, maxBufferHole);
                            var bufferEnd = bufferedInfo.end, bufferLen = bufferedInfo.len;
                            var trackDetails = tracks[currentTrackId].details;
                            var fragments = trackDetails.fragments;
                            var fragLen = fragments.length;
                            var end = fragments[fragLen - 1].start + fragments[fragLen - 1].duration;
                            if (bufferLen > maxConfigBuffer) return;
                            var foundFrag;
                            var fragPrevious = this.fragPrevious;
                            if (bufferEnd < end) {
                                if (fragPrevious && trackDetails.hasProgramDateTime) foundFrag = findFragmentByPDT(fragments, fragPrevious.endProgramDateTime, maxFragLookUpTolerance);
                                if (!foundFrag) foundFrag = findFragmentByPTS(fragPrevious, fragments, bufferEnd, maxFragLookUpTolerance);
                            } else foundFrag = fragments[fragLen - 1];
                            if (foundFrag && foundFrag.encrypted) {
                                logger1["logger"].log("Loading key for " + foundFrag.sn);
                                this.state = State.KEY_LOADING;
                                this.hls.trigger(events1["default"].KEY_LOADING, {
                                    frag: foundFrag
                                });
                            } else if (foundFrag && fragmentTracker.getState(foundFrag) === FragmentState.NOT_LOADED) {
                                // only load if fragment is not loaded
                                this.fragCurrent = foundFrag;
                                this.state = State.FRAG_LOADING;
                                this.hls.trigger(events1["default"].FRAG_LOADING, {
                                    frag: foundFrag
                                });
                            }
                    }
                };
                _proto.stopLoad = function stopLoad() {
                    this.lastAVStart = 0;
                    this.fragPrevious = null;
                    _BaseStreamController.prototype.stopLoad.call(this);
                };
                _proto._getBuffered = function _getBuffered() {
                    return this.tracksBuffered[this.currentTrackId] || [];
                };
                _proto.onMediaSeeking = function onMediaSeeking() {
                    if (this.fragCurrent) {
                        var currentTime = this.media ? this.media.currentTime : 0;
                        var tolerance = this.config.maxFragLookUpTolerance;
                        var fragStartOffset = this.fragCurrent.start - tolerance;
                        var fragEndOffset = this.fragCurrent.start + this.fragCurrent.duration + tolerance; // check if position will be out of currently loaded frag range after seeking : if out, cancel frag load, if in, don't do anything
                        if (currentTime < fragStartOffset || currentTime > fragEndOffset) {
                            if (this.fragCurrent.loader) this.fragCurrent.loader.abort();
                            this.fragmentTracker.removeFragment(this.fragCurrent);
                            this.fragCurrent = null;
                            this.fragPrevious = null; // switch to IDLE state to load new fragment
                            this.state = State.IDLE; // speed up things
                            this.tick();
                        }
                    }
                };
                return SubtitleStreamController;
            }(base_stream_controller_BaseStreamController);
            // CONCATENATED MODULE: ./src/utils/mediakeys-helper.ts
            /**
 * @see https://developer.mozilla.org/en-US/docs/Web/API/Navigator/requestMediaKeySystemAccess
 */ var KeySystems1;
            (function(KeySystems) {
                KeySystems["WIDEVINE"] = "com.widevine.alpha";
                KeySystems["PLAYREADY"] = "com.microsoft.playready";
            })(KeySystems1 || (KeySystems1 = {
            }));
            var requestMediaKeySystemAccess = function() {
                if (typeof window !== 'undefined' && window.navigator && window.navigator.requestMediaKeySystemAccess) return window.navigator.requestMediaKeySystemAccess.bind(window.navigator);
                else return null;
            }();
            // CONCATENATED MODULE: ./src/controller/eme-controller.ts
            function eme_controller_defineProperties(target, props) {
                for(var i = 0; i < props.length; i++){
                    var descriptor = props[i];
                    descriptor.enumerable = descriptor.enumerable || false;
                    descriptor.configurable = true;
                    if ("value" in descriptor) descriptor.writable = true;
                    Object.defineProperty(target, descriptor.key, descriptor);
                }
            }
            function eme_controller_createClass(Constructor, protoProps, staticProps) {
                if (protoProps) eme_controller_defineProperties(Constructor.prototype, protoProps);
                if (staticProps) eme_controller_defineProperties(Constructor, staticProps);
                return Constructor;
            }
            function eme_controller_inheritsLoose(subClass, superClass) {
                subClass.prototype = Object.create(superClass.prototype);
                subClass.prototype.constructor = subClass;
                subClass.__proto__ = superClass;
            }
            /**
 * @author Stephan Hesse <disparat@gmail.com> | <tchakabam@gmail.com>
 *
 * DRM support for Hls.js
 */ var MAX_LICENSE_REQUEST_FAILURES = 3;
            /**
 * @see https://developer.mozilla.org/en-US/docs/Web/API/MediaKeySystemConfiguration
 * @param {Array<string>} audioCodecs List of required audio codecs to support
 * @param {Array<string>} videoCodecs List of required video codecs to support
 * @param {object} drmSystemOptions Optional parameters/requirements for the key-system
 * @returns {Array<MediaSystemConfiguration>} An array of supported configurations
 */ var createWidevineMediaKeySystemConfigurations = function createWidevineMediaKeySystemConfigurations(audioCodecs, videoCodecs, drmSystemOptions) {
                /* jshint ignore:line */ var baseConfig = {
                    // initDataTypes: ['keyids', 'mp4'],
                    // label: "",
                    // persistentState: "not-allowed", // or "required" ?
                    // distinctiveIdentifier: "not-allowed", // or "required" ?
                    // sessionTypes: ['temporary'],
                    audioCapabilities: [],
                    // { contentType: 'audio/mp4; codecs="mp4a.40.2"' }
                    videoCapabilities: [] // { contentType: 'video/mp4; codecs="avc1.42E01E"' }
                };
                audioCodecs.forEach(function(codec) {
                    baseConfig.audioCapabilities.push({
                        contentType: "audio/mp4; codecs=\"" + codec + "\"",
                        robustness: drmSystemOptions.audioRobustness || ''
                    });
                });
                videoCodecs.forEach(function(codec) {
                    baseConfig.videoCapabilities.push({
                        contentType: "video/mp4; codecs=\"" + codec + "\"",
                        robustness: drmSystemOptions.videoRobustness || ''
                    });
                });
                return [
                    baseConfig
                ];
            };
            /**
 * The idea here is to handle key-system (and their respective platforms) specific configuration differences
 * in order to work with the local requestMediaKeySystemAccess method.
 *
 * We can also rule-out platform-related key-system support at this point by throwing an error.
 *
 * @param {string} keySystem Identifier for the key-system, see `KeySystems` enum
 * @param {Array<string>} audioCodecs List of required audio codecs to support
 * @param {Array<string>} videoCodecs List of required video codecs to support
 * @throws will throw an error if a unknown key system is passed
 * @returns {Array<MediaSystemConfiguration>} A non-empty Array of MediaKeySystemConfiguration objects
 */ var eme_controller_getSupportedMediaKeySystemConfigurations = function getSupportedMediaKeySystemConfigurations(keySystem, audioCodecs, videoCodecs, drmSystemOptions) {
                switch(keySystem){
                    case KeySystems1.WIDEVINE:
                        return createWidevineMediaKeySystemConfigurations(audioCodecs, videoCodecs, drmSystemOptions);
                    default:
                        throw new Error("Unknown key-system: " + keySystem);
                }
            };
            /**
 * Controller to deal with encrypted media extensions (EME)
 * @see https://developer.mozilla.org/en-US/docs/Web/API/Encrypted_Media_Extensions_API
 *
 * @class
 * @constructor
 */ var eme_controller_EMEController = /*#__PURE__*/ function(_EventHandler) {
                eme_controller_inheritsLoose(EMEController, _EventHandler);
                /**
     * @constructs
     * @param {Hls} hls Our Hls.js instance
     */ function EMEController(hls) {
                    var _this;
                    _this = _EventHandler.call(this, hls, events1["default"].MEDIA_ATTACHED, events1["default"].MEDIA_DETACHED, events1["default"].MANIFEST_PARSED) || this;
                    _this._widevineLicenseUrl = void 0;
                    _this._licenseXhrSetup = void 0;
                    _this._emeEnabled = void 0;
                    _this._requestMediaKeySystemAccess = void 0;
                    _this._drmSystemOptions = void 0;
                    _this._config = void 0;
                    _this._mediaKeysList = [];
                    _this._media = null;
                    _this._hasSetMediaKeys = false;
                    _this._requestLicenseFailureCount = 0;
                    _this.mediaKeysPromise = null;
                    _this._onMediaEncrypted = function(e) {
                        logger1["logger"].log("Media is encrypted using \"" + e.initDataType + "\" init data type");
                        if (!_this.mediaKeysPromise) {
                            logger1["logger"].error('Fatal: Media is encrypted but no CDM access or no keys have been requested');
                            _this.hls.trigger(events1["default"].ERROR, {
                                type: errors["ErrorTypes"].KEY_SYSTEM_ERROR,
                                details: errors["ErrorDetails"].KEY_SYSTEM_NO_KEYS,
                                fatal: true
                            });
                            return;
                        }
                        var finallySetKeyAndStartSession = function finallySetKeyAndStartSession(mediaKeys) {
                            if (!_this._media) return;
                            _this._attemptSetMediaKeys(mediaKeys);
                            _this._generateRequestWithPreferredKeySession(e.initDataType, e.initData);
                        }; // Could use `Promise.finally` but some Promise polyfills are missing it
                        _this.mediaKeysPromise.then(finallySetKeyAndStartSession).catch(finallySetKeyAndStartSession);
                    };
                    _this._config = hls.config;
                    _this._widevineLicenseUrl = _this._config.widevineLicenseUrl;
                    _this._licenseXhrSetup = _this._config.licenseXhrSetup;
                    _this._emeEnabled = _this._config.emeEnabled;
                    _this._requestMediaKeySystemAccess = _this._config.requestMediaKeySystemAccessFunc;
                    _this._drmSystemOptions = hls.config.drmSystemOptions;
                    return _this;
                }
                /**
   * @param {string} keySystem Identifier for the key-system, see `KeySystems` enum
   * @returns {string} License server URL for key-system (if any configured, otherwise causes error)
   * @throws if a unsupported keysystem is passed
   */ var _proto = EMEController.prototype;
                _proto.getLicenseServerUrl = function getLicenseServerUrl(keySystem) {
                    switch(keySystem){
                        case KeySystems1.WIDEVINE:
                            if (!this._widevineLicenseUrl) break;
                            return this._widevineLicenseUrl;
                    }
                    throw new Error("no license server URL configured for key-system \"" + keySystem + "\"");
                };
                _proto._attemptKeySystemAccess = function _attemptKeySystemAccess(keySystem, audioCodecs, videoCodecs) {
                    var _this2 = this;
                    // This can throw, but is caught in event handler callpath
                    var mediaKeySystemConfigs = eme_controller_getSupportedMediaKeySystemConfigurations(keySystem, audioCodecs, videoCodecs, this._drmSystemOptions);
                    logger1["logger"].log('Requesting encrypted media key-system access'); // expecting interface like window.navigator.requestMediaKeySystemAccess
                    var keySystemAccessPromise = this.requestMediaKeySystemAccess(keySystem, mediaKeySystemConfigs);
                    this.mediaKeysPromise = keySystemAccessPromise.then(function(mediaKeySystemAccess) {
                        return _this2._onMediaKeySystemAccessObtained(keySystem, mediaKeySystemAccess);
                    });
                    keySystemAccessPromise.catch(function(err) {
                        logger1["logger"].error("Failed to obtain key-system \"" + keySystem + "\" access:", err);
                    });
                };
                /**
     * Handles obtaining access to a key-system
     * @private
     * @param {string} keySystem
     * @param {MediaKeySystemAccess} mediaKeySystemAccess https://developer.mozilla.org/en-US/docs/Web/API/MediaKeySystemAccess
     */ _proto._onMediaKeySystemAccessObtained = function _onMediaKeySystemAccessObtained(keySystem, mediaKeySystemAccess) {
                    var _this3 = this;
                    logger1["logger"].log("Access for key-system \"" + keySystem + "\" obtained");
                    var mediaKeysListItem = {
                        mediaKeysSessionInitialized: false,
                        mediaKeySystemAccess: mediaKeySystemAccess,
                        mediaKeySystemDomain: keySystem
                    };
                    this._mediaKeysList.push(mediaKeysListItem);
                    var mediaKeysPromise = Promise.resolve().then(function() {
                        return mediaKeySystemAccess.createMediaKeys();
                    }).then(function(mediaKeys) {
                        mediaKeysListItem.mediaKeys = mediaKeys;
                        logger1["logger"].log("Media-keys created for key-system \"" + keySystem + "\"");
                        _this3._onMediaKeysCreated();
                        return mediaKeys;
                    });
                    mediaKeysPromise.catch(function(err) {
                        logger1["logger"].error('Failed to create media-keys:', err);
                    });
                    return mediaKeysPromise;
                };
                _proto._onMediaKeysCreated = function _onMediaKeysCreated() {
                    var _this4 = this;
                    // check for all key-list items if a session exists, otherwise, create one
                    this._mediaKeysList.forEach(function(mediaKeysListItem) {
                        if (!mediaKeysListItem.mediaKeysSession) {
                            // mediaKeys is definitely initialized here
                            mediaKeysListItem.mediaKeysSession = mediaKeysListItem.mediaKeys.createSession();
                            _this4._onNewMediaKeySession(mediaKeysListItem.mediaKeysSession);
                        }
                    });
                };
                _proto._onNewMediaKeySession = function _onNewMediaKeySession(keySession) {
                    var _this5 = this;
                    logger1["logger"].log("New key-system session " + keySession.sessionId);
                    keySession.addEventListener('message', function(event) {
                        _this5._onKeySessionMessage(keySession, event.message);
                    }, false);
                };
                _proto._onKeySessionMessage = function _onKeySessionMessage(keySession, message) {
                    logger1["logger"].log('Got EME message event, creating license request');
                    this._requestLicense(message, function(data) {
                        logger1["logger"].log("Received license data (length: " + (data ? data.byteLength : data) + "), updating key-session");
                        keySession.update(data);
                    });
                };
                /**
   * @private
   */ _proto._attemptSetMediaKeys = function _attemptSetMediaKeys(mediaKeys) {
                    if (!this._media) throw new Error('Attempted to set mediaKeys without first attaching a media element');
                    if (!this._hasSetMediaKeys) {
                        // FIXME: see if we can/want/need-to really to deal with several potential key-sessions?
                        var keysListItem = this._mediaKeysList[0];
                        if (!keysListItem || !keysListItem.mediaKeys) {
                            logger1["logger"].error('Fatal: Media is encrypted but no CDM access or no keys have been obtained yet');
                            this.hls.trigger(events1["default"].ERROR, {
                                type: errors["ErrorTypes"].KEY_SYSTEM_ERROR,
                                details: errors["ErrorDetails"].KEY_SYSTEM_NO_KEYS,
                                fatal: true
                            });
                            return;
                        }
                        logger1["logger"].log('Setting keys for encrypted media');
                        this._media.setMediaKeys(keysListItem.mediaKeys);
                        this._hasSetMediaKeys = true;
                    }
                };
                _proto._generateRequestWithPreferredKeySession = function _generateRequestWithPreferredKeySession(initDataType, initData) {
                    var _this6 = this;
                    // FIXME: see if we can/want/need-to really to deal with several potential key-sessions?
                    var keysListItem = this._mediaKeysList[0];
                    if (!keysListItem) {
                        logger1["logger"].error('Fatal: Media is encrypted but not any key-system access has been obtained yet');
                        this.hls.trigger(events1["default"].ERROR, {
                            type: errors["ErrorTypes"].KEY_SYSTEM_ERROR,
                            details: errors["ErrorDetails"].KEY_SYSTEM_NO_ACCESS,
                            fatal: true
                        });
                        return;
                    }
                    if (keysListItem.mediaKeysSessionInitialized) {
                        logger1["logger"].warn('Key-Session already initialized but requested again');
                        return;
                    }
                    var keySession = keysListItem.mediaKeysSession;
                    if (!keySession) {
                        logger1["logger"].error('Fatal: Media is encrypted but no key-session existing');
                        this.hls.trigger(events1["default"].ERROR, {
                            type: errors["ErrorTypes"].KEY_SYSTEM_ERROR,
                            details: errors["ErrorDetails"].KEY_SYSTEM_NO_SESSION,
                            fatal: true
                        });
                        return;
                    } // initData is null if the media is not CORS-same-origin
                    if (!initData) {
                        logger1["logger"].warn('Fatal: initData required for generating a key session is null');
                        this.hls.trigger(events1["default"].ERROR, {
                            type: errors["ErrorTypes"].KEY_SYSTEM_ERROR,
                            details: errors["ErrorDetails"].KEY_SYSTEM_NO_INIT_DATA,
                            fatal: true
                        });
                        return;
                    }
                    logger1["logger"].log("Generating key-session request for \"" + initDataType + "\" init data type");
                    keysListItem.mediaKeysSessionInitialized = true;
                    keySession.generateRequest(initDataType, initData).then(function() {
                        logger1["logger"].debug('Key-session generation succeeded');
                    }).catch(function(err) {
                        logger1["logger"].error('Error generating key-session request:', err);
                        _this6.hls.trigger(events1["default"].ERROR, {
                            type: errors["ErrorTypes"].KEY_SYSTEM_ERROR,
                            details: errors["ErrorDetails"].KEY_SYSTEM_NO_SESSION,
                            fatal: false
                        });
                    });
                };
                _proto._createLicenseXhr = function _createLicenseXhr(url, keyMessage, callback) {
                    var xhr = new XMLHttpRequest();
                    var licenseXhrSetup = this._licenseXhrSetup;
                    try {
                        if (licenseXhrSetup) try {
                            licenseXhrSetup(xhr, url);
                        } catch (e) {
                            // let's try to open before running setup
                            xhr.open('POST', url, true);
                            licenseXhrSetup(xhr, url);
                        }
                         // if licenseXhrSetup did not yet call open, let's do it now
                        if (!xhr.readyState) xhr.open('POST', url, true);
                    } catch (e) {
                        // IE11 throws an exception on xhr.open if attempting to access an HTTP resource over HTTPS
                        throw new Error("issue setting up KeySystem license XHR " + e);
                    } // Because we set responseType to ArrayBuffer here, callback is typed as handling only array buffers
                    xhr.responseType = 'arraybuffer';
                    xhr.onreadystatechange = this._onLicenseRequestReadyStageChange.bind(this, xhr, url, keyMessage, callback);
                    return xhr;
                };
                _proto._onLicenseRequestReadyStageChange = function _onLicenseRequestReadyStageChange(xhr, url, keyMessage, callback) {
                    switch(xhr.readyState){
                        case 4:
                            if (xhr.status === 200) {
                                this._requestLicenseFailureCount = 0;
                                logger1["logger"].log('License request succeeded');
                                if (xhr.responseType !== 'arraybuffer') logger1["logger"].warn('xhr response type was not set to the expected arraybuffer for license request');
                                callback(xhr.response);
                            } else {
                                logger1["logger"].error("License Request XHR failed (" + url + "). Status: " + xhr.status + " (" + xhr.statusText + ")");
                                this._requestLicenseFailureCount++;
                                if (this._requestLicenseFailureCount > MAX_LICENSE_REQUEST_FAILURES) {
                                    this.hls.trigger(events1["default"].ERROR, {
                                        type: errors["ErrorTypes"].KEY_SYSTEM_ERROR,
                                        details: errors["ErrorDetails"].KEY_SYSTEM_LICENSE_REQUEST_FAILED,
                                        fatal: true
                                    });
                                    return;
                                }
                                var attemptsLeft = MAX_LICENSE_REQUEST_FAILURES - this._requestLicenseFailureCount + 1;
                                logger1["logger"].warn("Retrying license request, " + attemptsLeft + " attempts left");
                                this._requestLicense(keyMessage, callback);
                            }
                            break;
                    }
                };
                _proto._generateLicenseRequestChallenge = function _generateLicenseRequestChallenge(keysListItem, keyMessage) {
                    switch(keysListItem.mediaKeySystemDomain){
                        // case KeySystems.PLAYREADY:
                        // from https://github.com/MicrosoftEdge/Demos/blob/master/eme/scripts/demo.js
                        /*
        if (this.licenseType !== this.LICENSE_TYPE_WIDEVINE) {
          // For PlayReady CDMs, we need to dig the Challenge out of the XML.
          var keyMessageXml = new DOMParser().parseFromString(String.fromCharCode.apply(null, new Uint16Array(keyMessage)), 'application/xml');
          if (keyMessageXml.getElementsByTagName('Challenge')[0]) {
              challenge = atob(keyMessageXml.getElementsByTagName('Challenge')[0].childNodes[0].nodeValue);
          } else {
              throw 'Cannot find <Challenge> in key message';
          }
          var headerNames = keyMessageXml.getElementsByTagName('name');
          var headerValues = keyMessageXml.getElementsByTagName('value');
          if (headerNames.length !== headerValues.length) {
              throw 'Mismatched header <name>/<value> pair in key message';
          }
          for (var i = 0; i < headerNames.length; i++) {
              xhr.setRequestHeader(headerNames[i].childNodes[0].nodeValue, headerValues[i].childNodes[0].nodeValue);
          }
        }
        break;
      */ case KeySystems1.WIDEVINE:
                            // For Widevine CDMs, the challenge is the keyMessage.
                            return keyMessage;
                    }
                    throw new Error("unsupported key-system: " + keysListItem.mediaKeySystemDomain);
                };
                _proto._requestLicense = function _requestLicense(keyMessage, callback) {
                    logger1["logger"].log('Requesting content license for key-system');
                    var keysListItem = this._mediaKeysList[0];
                    if (!keysListItem) {
                        logger1["logger"].error('Fatal error: Media is encrypted but no key-system access has been obtained yet');
                        this.hls.trigger(events1["default"].ERROR, {
                            type: errors["ErrorTypes"].KEY_SYSTEM_ERROR,
                            details: errors["ErrorDetails"].KEY_SYSTEM_NO_ACCESS,
                            fatal: true
                        });
                        return;
                    }
                    try {
                        var _url = this.getLicenseServerUrl(keysListItem.mediaKeySystemDomain);
                        var _xhr = this._createLicenseXhr(_url, keyMessage, callback);
                        logger1["logger"].log("Sending license request to URL: " + _url);
                        var challenge = this._generateLicenseRequestChallenge(keysListItem, keyMessage);
                        _xhr.send(challenge);
                    } catch (e) {
                        logger1["logger"].error("Failure requesting DRM license: " + e);
                        this.hls.trigger(events1["default"].ERROR, {
                            type: errors["ErrorTypes"].KEY_SYSTEM_ERROR,
                            details: errors["ErrorDetails"].KEY_SYSTEM_LICENSE_REQUEST_FAILED,
                            fatal: true
                        });
                    }
                };
                _proto.onMediaAttached = function onMediaAttached(data) {
                    if (!this._emeEnabled) return;
                    var media = data.media; // keep reference of media
                    this._media = media;
                    media.addEventListener('encrypted', this._onMediaEncrypted);
                };
                _proto.onMediaDetached = function onMediaDetached() {
                    var media = this._media;
                    var mediaKeysList = this._mediaKeysList;
                    if (!media) return;
                    media.removeEventListener('encrypted', this._onMediaEncrypted);
                    this._media = null;
                    this._mediaKeysList = []; // Close all sessions and remove media keys from the video element.
                    Promise.all(mediaKeysList.map(function(mediaKeysListItem) {
                        if (mediaKeysListItem.mediaKeysSession) return mediaKeysListItem.mediaKeysSession.close().catch(function() {
                        // generated no key requests will throw an error.
                        });
                    })).then(function() {
                        return media.setMediaKeys(null);
                    }).catch(function() {
                    });
                } // TODO: Use manifest types here when they are defined
                ;
                _proto.onManifestParsed = function onManifestParsed(data) {
                    if (!this._emeEnabled) return;
                    var audioCodecs = data.levels.map(function(level) {
                        return level.audioCodec;
                    });
                    var videoCodecs = data.levels.map(function(level) {
                        return level.videoCodec;
                    });
                    this._attemptKeySystemAccess(KeySystems1.WIDEVINE, audioCodecs, videoCodecs);
                };
                eme_controller_createClass(EMEController, [
                    {
                        key: "requestMediaKeySystemAccess",
                        get: function get() {
                            if (!this._requestMediaKeySystemAccess) throw new Error('No requestMediaKeySystemAccess function configured');
                            return this._requestMediaKeySystemAccess;
                        }
                    }
                ]);
                return EMEController;
            }(event_handler);
            /* harmony default export */ var eme_controller = eme_controller_EMEController;
            // CONCATENATED MODULE: ./src/config.ts
            function ownKeys(object, enumerableOnly) {
                var keys = Object.keys(object);
                if (Object.getOwnPropertySymbols) {
                    var symbols = Object.getOwnPropertySymbols(object);
                    if (enumerableOnly) symbols = symbols.filter(function(sym) {
                        return Object.getOwnPropertyDescriptor(object, sym).enumerable;
                    });
                    keys.push.apply(keys, symbols);
                }
                return keys;
            }
            function _objectSpread(target) {
                for(var i = 1; i < arguments.length; i++){
                    var source = arguments[i] != null ? arguments[i] : {
                    };
                    if (i % 2) ownKeys(Object(source), true).forEach(function(key) {
                        _defineProperty(target, key, source[key]);
                    });
                    else if (Object.getOwnPropertyDescriptors) Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
                    else ownKeys(Object(source)).forEach(function(key) {
                        Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
                    });
                }
                return target;
            }
            function _defineProperty(obj, key, value) {
                if (key in obj) Object.defineProperty(obj, key, {
                    value: value,
                    enumerable: true,
                    configurable: true,
                    writable: true
                });
                else obj[key] = value;
                return obj;
            }
            /**
 * HLS config
 */ // import FetchLoader from './utils/fetch-loader';
            // If possible, keep hlsDefaultConfig shallow
            // It is cloned whenever a new Hls instance is created, by keeping the config
            // shallow the properties are cloned, and we don't end up manipulating the default
            var hlsDefaultConfig = _objectSpread(_objectSpread({
                autoStartLoad: true,
                // used by stream-controller
                startPosition: -1,
                // used by stream-controller
                defaultAudioCodec: void 0,
                // used by stream-controller
                debug: false,
                // used by logger
                capLevelOnFPSDrop: false,
                // used by fps-controller
                capLevelToPlayerSize: false,
                // used by cap-level-controller
                initialLiveManifestSize: 1,
                // used by stream-controller
                maxBufferLength: 30,
                // used by stream-controller
                maxBufferSize: 60000000,
                // used by stream-controller
                maxBufferHole: 0.5,
                // used by stream-controller
                lowBufferWatchdogPeriod: 0.5,
                // used by stream-controller
                highBufferWatchdogPeriod: 3,
                // used by stream-controller
                nudgeOffset: 0.1,
                // used by stream-controller
                nudgeMaxRetry: 3,
                // used by stream-controller
                maxFragLookUpTolerance: 0.25,
                // used by stream-controller
                liveSyncDurationCount: 3,
                // used by stream-controller
                liveMaxLatencyDurationCount: Infinity,
                // used by stream-controller
                liveSyncDuration: void 0,
                // used by stream-controller
                liveMaxLatencyDuration: void 0,
                // used by stream-controller
                liveDurationInfinity: false,
                // used by buffer-controller
                liveBackBufferLength: Infinity,
                // used by buffer-controller
                maxMaxBufferLength: 600,
                // used by stream-controller
                enableWorker: true,
                // used by demuxer
                enableSoftwareAES: true,
                // used by decrypter
                manifestLoadingTimeOut: 10000,
                // used by playlist-loader
                manifestLoadingMaxRetry: 1,
                // used by playlist-loader
                manifestLoadingRetryDelay: 1000,
                // used by playlist-loader
                manifestLoadingMaxRetryTimeout: 64000,
                // used by playlist-loader
                startLevel: void 0,
                // used by level-controller
                levelLoadingTimeOut: 10000,
                // used by playlist-loader
                levelLoadingMaxRetry: 4,
                // used by playlist-loader
                levelLoadingRetryDelay: 1000,
                // used by playlist-loader
                levelLoadingMaxRetryTimeout: 64000,
                // used by playlist-loader
                fragLoadingTimeOut: 20000,
                // used by fragment-loader
                fragLoadingMaxRetry: 6,
                // used by fragment-loader
                fragLoadingRetryDelay: 1000,
                // used by fragment-loader
                fragLoadingMaxRetryTimeout: 64000,
                // used by fragment-loader
                startFragPrefetch: false,
                // used by stream-controller
                fpsDroppedMonitoringPeriod: 5000,
                // used by fps-controller
                fpsDroppedMonitoringThreshold: 0.2,
                // used by fps-controller
                appendErrorMaxRetry: 3,
                // used by buffer-controller
                loader: xhr_loader,
                // loader: FetchLoader,
                fLoader: void 0,
                // used by fragment-loader
                pLoader: void 0,
                // used by playlist-loader
                xhrSetup: void 0,
                // used by xhr-loader
                licenseXhrSetup: void 0,
                // used by eme-controller
                // fetchSetup: void 0,
                abrController: abr_controller,
                bufferController: buffer_controller,
                capLevelController: cap_level_controller,
                fpsController: fps_controller,
                stretchShortVideoTrack: false,
                // used by mp4-remuxer
                maxAudioFramesDrift: 1,
                // used by mp4-remuxer
                forceKeyFrameOnDiscontinuity: true,
                // used by ts-demuxer
                abrEwmaFastLive: 3,
                // used by abr-controller
                abrEwmaSlowLive: 9,
                // used by abr-controller
                abrEwmaFastVoD: 3,
                // used by abr-controller
                abrEwmaSlowVoD: 9,
                // used by abr-controller
                abrEwmaDefaultEstimate: 500000,
                // 500 kbps  // used by abr-controller
                abrBandWidthFactor: 0.95,
                // used by abr-controller
                abrBandWidthUpFactor: 0.7,
                // used by abr-controller
                abrMaxWithRealBitrate: false,
                // used by abr-controller
                maxStarvationDelay: 4,
                // used by abr-controller
                maxLoadingDelay: 4,
                // used by abr-controller
                minAutoBitrate: 0,
                // used by hls
                emeEnabled: false,
                // used by eme-controller
                widevineLicenseUrl: void 0,
                // used by eme-controller
                drmSystemOptions: {
                },
                // used by eme-controller
                requestMediaKeySystemAccessFunc: requestMediaKeySystemAccess,
                // used by eme-controller
                testBandwidth: true
            }, timelineConfig()), {
            }, {
                subtitleStreamController: subtitle_stream_controller_SubtitleStreamController,
                subtitleTrackController: subtitle_track_controller,
                timelineController: timeline_controller,
                audioStreamController: audio_stream_controller,
                audioTrackController: audio_track_controller,
                emeController: eme_controller
            });
            function timelineConfig() {
                return {
                    cueHandler: cues_namespaceObject,
                    // used by timeline-controller
                    enableCEA708Captions: true,
                    // used by timeline-controller
                    enableWebVTT: true,
                    // used by timeline-controller
                    captionsTextTrack1Label: 'English',
                    // used by timeline-controller
                    captionsTextTrack1LanguageCode: 'en',
                    // used by timeline-controller
                    captionsTextTrack2Label: 'Spanish',
                    // used by timeline-controller
                    captionsTextTrack2LanguageCode: 'es',
                    // used by timeline-controller
                    captionsTextTrack3Label: 'Unknown CC',
                    // used by timeline-controller
                    captionsTextTrack3LanguageCode: '',
                    // used by timeline-controller
                    captionsTextTrack4Label: 'Unknown CC',
                    // used by timeline-controller
                    captionsTextTrack4LanguageCode: '',
                    // used by timeline-controller
                    renderTextTracksNatively: true
                };
            }
            // CONCATENATED MODULE: ./src/hls.ts
            function hls_ownKeys(object, enumerableOnly) {
                var keys = Object.keys(object);
                if (Object.getOwnPropertySymbols) {
                    var symbols = Object.getOwnPropertySymbols(object);
                    if (enumerableOnly) symbols = symbols.filter(function(sym) {
                        return Object.getOwnPropertyDescriptor(object, sym).enumerable;
                    });
                    keys.push.apply(keys, symbols);
                }
                return keys;
            }
            function hls_objectSpread(target) {
                for(var i = 1; i < arguments.length; i++){
                    var source = arguments[i] != null ? arguments[i] : {
                    };
                    if (i % 2) hls_ownKeys(Object(source), true).forEach(function(key) {
                        hls_defineProperty(target, key, source[key]);
                    });
                    else if (Object.getOwnPropertyDescriptors) Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
                    else hls_ownKeys(Object(source)).forEach(function(key) {
                        Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
                    });
                }
                return target;
            }
            function hls_defineProperty(obj, key, value) {
                if (key in obj) Object.defineProperty(obj, key, {
                    value: value,
                    enumerable: true,
                    configurable: true,
                    writable: true
                });
                else obj[key] = value;
                return obj;
            }
            function hls_assertThisInitialized(self) {
                if (self === void 0) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
                return self;
            }
            function hls_defineProperties(target, props) {
                for(var i = 0; i < props.length; i++){
                    var descriptor = props[i];
                    descriptor.enumerable = descriptor.enumerable || false;
                    descriptor.configurable = true;
                    if ("value" in descriptor) descriptor.writable = true;
                    Object.defineProperty(target, descriptor.key, descriptor);
                }
            }
            function hls_createClass(Constructor, protoProps, staticProps) {
                if (protoProps) hls_defineProperties(Constructor.prototype, protoProps);
                if (staticProps) hls_defineProperties(Constructor, staticProps);
                return Constructor;
            }
            function hls_inheritsLoose(subClass, superClass) {
                subClass.prototype = Object.create(superClass.prototype);
                subClass.prototype.constructor = subClass;
                subClass.__proto__ = superClass;
            }
            /**
 * @module Hls
 * @class
 * @constructor
 */ var hls_Hls = /*#__PURE__*/ function(_Observer) {
                hls_inheritsLoose(Hls, _Observer);
                /**
   * @type {boolean}
   */ Hls.isSupported = function isSupported() {
                    return is_supported_isSupported();
                };
                hls_createClass(Hls, null, [
                    {
                        key: "version",
                        /**
     * @type {string}
     */ get: function get() {
                            return "0.14.17";
                        }
                    },
                    {
                        key: "Events",
                        get: function get() {
                            return events1["default"];
                        }
                    },
                    {
                        key: "ErrorTypes",
                        get: function get() {
                            return errors["ErrorTypes"];
                        }
                    },
                    {
                        key: "ErrorDetails",
                        get: function get() {
                            return errors["ErrorDetails"];
                        }
                    },
                    {
                        key: "DefaultConfig",
                        get: function get() {
                            if (!Hls.defaultConfig) return hlsDefaultConfig;
                            return Hls.defaultConfig;
                        },
                        set: function set(defaultConfig) {
                            Hls.defaultConfig = defaultConfig;
                        }
                    }
                ]);
                function Hls(userConfig) {
                    var _this;
                    if (userConfig === void 0) userConfig = {
                    };
                    _this = _Observer.call(this) || this;
                    _this.config = void 0;
                    _this._autoLevelCapping = void 0;
                    _this.abrController = void 0;
                    _this.capLevelController = void 0;
                    _this.levelController = void 0;
                    _this.streamController = void 0;
                    _this.networkControllers = void 0;
                    _this.audioTrackController = void 0;
                    _this.subtitleTrackController = void 0;
                    _this.emeController = void 0;
                    _this.coreComponents = void 0;
                    _this.media = null;
                    _this.url = null;
                    var defaultConfig = Hls.DefaultConfig;
                    if ((userConfig.liveSyncDurationCount || userConfig.liveMaxLatencyDurationCount) && (userConfig.liveSyncDuration || userConfig.liveMaxLatencyDuration)) throw new Error('Illegal hls.js config: don\'t mix up liveSyncDurationCount/liveMaxLatencyDurationCount and liveSyncDuration/liveMaxLatencyDuration');
                     // Shallow clone
                    _this.config = hls_objectSpread(hls_objectSpread({
                    }, defaultConfig), userConfig);
                    var _assertThisInitialize = hls_assertThisInitialized(_this), config = _assertThisInitialize.config;
                    if (config.liveMaxLatencyDurationCount !== void 0 && config.liveMaxLatencyDurationCount <= config.liveSyncDurationCount) throw new Error('Illegal hls.js config: "liveMaxLatencyDurationCount" must be gt "liveSyncDurationCount"');
                    if (config.liveMaxLatencyDuration !== void 0 && (config.liveSyncDuration === void 0 || config.liveMaxLatencyDuration <= config.liveSyncDuration)) throw new Error('Illegal hls.js config: "liveMaxLatencyDuration" must be gt "liveSyncDuration"');
                    Object(logger1["enableLogs"])(config.debug);
                    _this._autoLevelCapping = -1; // core controllers and network loaders
                    /**
     * @member {AbrController} abrController
     */ var abrController = _this.abrController = new config.abrController(hls_assertThisInitialized(_this)); // eslint-disable-line new-cap
                    var bufferController = new config.bufferController(hls_assertThisInitialized(_this)); // eslint-disable-line new-cap
                    var capLevelController = _this.capLevelController = new config.capLevelController(hls_assertThisInitialized(_this)); // eslint-disable-line new-cap
                    var fpsController = new config.fpsController(hls_assertThisInitialized(_this)); // eslint-disable-line new-cap
                    var playListLoader = new playlist_loader(hls_assertThisInitialized(_this));
                    var fragmentLoader = new fragment_loader(hls_assertThisInitialized(_this));
                    var keyLoader = new key_loader(hls_assertThisInitialized(_this));
                    var id3TrackController = new id3_track_controller(hls_assertThisInitialized(_this)); // network controllers
                    /**
     * @member {LevelController} levelController
     */ var levelController = _this.levelController = new level_controller_LevelController(hls_assertThisInitialized(_this)); // FIXME: FragmentTracker must be defined before StreamController because the order of event handling is important
                    var fragmentTracker = new fragment_tracker_FragmentTracker(hls_assertThisInitialized(_this));
                    /**
     * @member {StreamController} streamController
     */ var streamController = _this.streamController = new stream_controller(hls_assertThisInitialized(_this), fragmentTracker);
                    var networkControllers = [
                        levelController,
                        streamController
                    ]; // optional audio stream controller
                    /**
     * @var {ICoreComponent | Controller}
     */ var Controller = config.audioStreamController;
                    if (Controller) networkControllers.push(new Controller(hls_assertThisInitialized(_this), fragmentTracker));
                    /**
     * @member {INetworkController[]} networkControllers
     */ _this.networkControllers = networkControllers;
                    /**
     * @var {ICoreComponent[]}
     */ var coreComponents = [
                        playListLoader,
                        fragmentLoader,
                        keyLoader,
                        abrController,
                        bufferController,
                        capLevelController,
                        fpsController,
                        id3TrackController,
                        fragmentTracker
                    ]; // optional audio track and subtitle controller
                    Controller = config.audioTrackController;
                    if (Controller) {
                        var audioTrackController = new Controller(hls_assertThisInitialized(_this));
                        /**
       * @member {AudioTrackController} audioTrackController
       */ _this.audioTrackController = audioTrackController;
                        coreComponents.push(audioTrackController);
                    }
                    Controller = config.subtitleTrackController;
                    if (Controller) {
                        var subtitleTrackController = new Controller(hls_assertThisInitialized(_this));
                        /**
       * @member {SubtitleTrackController} subtitleTrackController
       */ _this.subtitleTrackController = subtitleTrackController;
                        networkControllers.push(subtitleTrackController);
                    }
                    Controller = config.emeController;
                    if (Controller) {
                        var emeController = new Controller(hls_assertThisInitialized(_this));
                        /**
       * @member {EMEController} emeController
       */ _this.emeController = emeController;
                        coreComponents.push(emeController);
                    } // optional subtitle controllers
                    Controller = config.subtitleStreamController;
                    if (Controller) networkControllers.push(new Controller(hls_assertThisInitialized(_this), fragmentTracker));
                    Controller = config.timelineController;
                    if (Controller) coreComponents.push(new Controller(hls_assertThisInitialized(_this)));
                    /**
     * @member {ICoreComponent[]}
     */ _this.coreComponents = coreComponents;
                    return _this;
                }
                /**
   * Dispose of the instance
   */ var _proto = Hls.prototype;
                _proto.destroy = function destroy() {
                    logger1["logger"].log('destroy');
                    this.trigger(events1["default"].DESTROYING);
                    this.detachMedia();
                    this.coreComponents.concat(this.networkControllers).forEach(function(component) {
                        component.destroy();
                    });
                    this.url = null;
                    this.removeAllListeners();
                    this._autoLevelCapping = -1;
                };
                _proto.attachMedia = function attachMedia(media) {
                    logger1["logger"].log('attachMedia');
                    this.media = media;
                    this.trigger(events1["default"].MEDIA_ATTACHING, {
                        media: media
                    });
                };
                _proto.detachMedia = function detachMedia() {
                    logger1["logger"].log('detachMedia');
                    this.trigger(events1["default"].MEDIA_DETACHING);
                    this.media = null;
                };
                _proto.loadSource = function loadSource(url) {
                    url = url_toolkit["buildAbsoluteURL"](window.location.href, url, {
                        alwaysNormalize: true
                    });
                    logger1["logger"].log("loadSource:" + url);
                    this.url = url; // when attaching to a source URL, trigger a playlist load
                    this.trigger(events1["default"].MANIFEST_LOADING, {
                        url: url
                    });
                };
                _proto.startLoad = function startLoad(startPosition) {
                    if (startPosition === void 0) startPosition = -1;
                    logger1["logger"].log("startLoad(" + startPosition + ")");
                    this.networkControllers.forEach(function(controller) {
                        controller.startLoad(startPosition);
                    });
                };
                _proto.stopLoad = function stopLoad() {
                    logger1["logger"].log('stopLoad');
                    this.networkControllers.forEach(function(controller) {
                        controller.stopLoad();
                    });
                };
                _proto.swapAudioCodec = function swapAudioCodec() {
                    logger1["logger"].log('swapAudioCodec');
                    this.streamController.swapAudioCodec();
                };
                _proto.recoverMediaError = function recoverMediaError() {
                    logger1["logger"].log('recoverMediaError');
                    var media = this.media;
                    this.detachMedia();
                    if (media) this.attachMedia(media);
                };
                _proto.removeLevel = function removeLevel(levelIndex, urlId) {
                    if (urlId === void 0) urlId = 0;
                    this.levelController.removeLevel(levelIndex, urlId);
                };
                hls_createClass(Hls, [
                    {
                        key: "levels",
                        get: function get() {
                            return this.levelController.levels;
                        }
                    },
                    {
                        key: "currentLevel",
                        get: function get() {
                            return this.streamController.currentLevel;
                        },
                        set: function set(newLevel) {
                            logger1["logger"].log("set currentLevel:" + newLevel);
                            this.loadLevel = newLevel;
                            this.streamController.immediateLevelSwitch();
                        }
                    },
                    {
                        key: "nextLevel",
                        get: function get() {
                            return this.streamController.nextLevel;
                        },
                        set: function set(newLevel) {
                            logger1["logger"].log("set nextLevel:" + newLevel);
                            this.levelController.manualLevel = newLevel;
                            this.streamController.nextLevelSwitch();
                        }
                    },
                    {
                        key: "loadLevel",
                        get: function get() {
                            return this.levelController.level;
                        },
                        set: function set(newLevel) {
                            logger1["logger"].log("set loadLevel:" + newLevel);
                            this.levelController.manualLevel = newLevel;
                        }
                    },
                    {
                        key: "nextLoadLevel",
                        get: function get() {
                            return this.levelController.nextLoadLevel;
                        },
                        set: function set(level) {
                            this.levelController.nextLoadLevel = level;
                        }
                    },
                    {
                        key: "firstLevel",
                        get: function get() {
                            return Math.max(this.levelController.firstLevel, this.minAutoLevel);
                        },
                        set: function set(newLevel) {
                            logger1["logger"].log("set firstLevel:" + newLevel);
                            this.levelController.firstLevel = newLevel;
                        }
                    },
                    {
                        key: "startLevel",
                        get: function get() {
                            return this.levelController.startLevel;
                        },
                        set: function set(newLevel) {
                            logger1["logger"].log("set startLevel:" + newLevel); // if not in automatic start level detection, ensure startLevel is greater than minAutoLevel
                            if (newLevel !== -1) newLevel = Math.max(newLevel, this.minAutoLevel);
                            this.levelController.startLevel = newLevel;
                        }
                    },
                    {
                        key: "capLevelToPlayerSize",
                        set: function set(shouldStartCapping) {
                            var newCapLevelToPlayerSize = !!shouldStartCapping;
                            if (newCapLevelToPlayerSize !== this.config.capLevelToPlayerSize) {
                                if (newCapLevelToPlayerSize) this.capLevelController.startCapping(); // If capping occurs, nextLevelSwitch will happen based on size.
                                else {
                                    this.capLevelController.stopCapping();
                                    this.autoLevelCapping = -1;
                                    this.streamController.nextLevelSwitch(); // Now we're uncapped, get the next level asap.
                                }
                                this.config.capLevelToPlayerSize = newCapLevelToPlayerSize;
                            }
                        }
                    },
                    {
                        key: "autoLevelCapping",
                        get: function get() {
                            return this._autoLevelCapping;
                        },
                        /**
     * Capping/max level value that should be used by automatic level selection algorithm (`ABRController`)
     * @type {number}
     */ set: function set(newLevel) {
                            logger1["logger"].log("set autoLevelCapping:" + newLevel);
                            this._autoLevelCapping = newLevel;
                        }
                    },
                    {
                        key: "bandwidthEstimate",
                        get: function get() {
                            var bwEstimator = this.abrController._bwEstimator;
                            return bwEstimator ? bwEstimator.getEstimate() : NaN;
                        }
                    },
                    {
                        key: "autoLevelEnabled",
                        get: function get() {
                            return this.levelController.manualLevel === -1;
                        }
                    },
                    {
                        key: "manualLevel",
                        get: function get() {
                            return this.levelController.manualLevel;
                        }
                    },
                    {
                        key: "minAutoLevel",
                        get: function get() {
                            var levels = this.levels, minAutoBitrate = this.config.minAutoBitrate;
                            var len = levels ? levels.length : 0;
                            for(var i = 0; i < len; i++){
                                var levelNextBitrate = levels[i].realBitrate ? Math.max(levels[i].realBitrate, levels[i].bitrate) : levels[i].bitrate;
                                if (levelNextBitrate > minAutoBitrate) return i;
                            }
                            return 0;
                        }
                    },
                    {
                        key: "maxAutoLevel",
                        get: function get() {
                            var levels = this.levels, autoLevelCapping = this.autoLevelCapping;
                            var maxAutoLevel;
                            if (autoLevelCapping === -1 && levels && levels.length) maxAutoLevel = levels.length - 1;
                            else maxAutoLevel = autoLevelCapping;
                            return maxAutoLevel;
                        }
                    },
                    {
                        key: "nextAutoLevel",
                        get: function get() {
                            // ensure next auto level is between  min and max auto level
                            return Math.min(Math.max(this.abrController.nextAutoLevel, this.minAutoLevel), this.maxAutoLevel);
                        },
                        set: function set(nextLevel) {
                            this.abrController.nextAutoLevel = Math.max(this.minAutoLevel, nextLevel);
                        }
                    },
                    {
                        key: "audioTracks",
                        get: function get() {
                            var audioTrackController = this.audioTrackController;
                            return audioTrackController ? audioTrackController.audioTracks : [];
                        }
                    },
                    {
                        key: "audioTrack",
                        get: function get() {
                            var audioTrackController = this.audioTrackController;
                            return audioTrackController ? audioTrackController.audioTrack : -1;
                        },
                        set: function set(audioTrackId) {
                            var audioTrackController = this.audioTrackController;
                            if (audioTrackController) audioTrackController.audioTrack = audioTrackId;
                        }
                    },
                    {
                        key: "liveSyncPosition",
                        get: function get() {
                            return this.streamController.liveSyncPosition;
                        }
                    },
                    {
                        key: "subtitleTracks",
                        get: function get() {
                            var subtitleTrackController = this.subtitleTrackController;
                            return subtitleTrackController ? subtitleTrackController.subtitleTracks : [];
                        }
                    },
                    {
                        key: "subtitleTrack",
                        get: function get() {
                            var subtitleTrackController = this.subtitleTrackController;
                            return subtitleTrackController ? subtitleTrackController.subtitleTrack : -1;
                        },
                        set: function set(subtitleTrackId) {
                            var subtitleTrackController = this.subtitleTrackController;
                            if (subtitleTrackController) subtitleTrackController.subtitleTrack = subtitleTrackId;
                        }
                    },
                    {
                        key: "subtitleDisplay",
                        get: function get() {
                            var subtitleTrackController = this.subtitleTrackController;
                            return subtitleTrackController ? subtitleTrackController.subtitleDisplay : false;
                        },
                        set: function set(value) {
                            var subtitleTrackController = this.subtitleTrackController;
                            if (subtitleTrackController) subtitleTrackController.subtitleDisplay = value;
                        }
                    }
                ]);
                return Hls;
            }(Observer1);
            hls_Hls.defaultConfig = void 0;
        /***/ },
        /***/ "./src/polyfills/number.js": function(module, __webpack_exports__, __webpack_require__) {
            "use strict";
            __webpack_require__.r(__webpack_exports__);
            /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isFiniteNumber", function() {
                return isFiniteNumber;
            });
            /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MAX_SAFE_INTEGER", function() {
                return MAX_SAFE_INTEGER;
            });
            var isFiniteNumber = Number.isFinite || function(value) {
                return typeof value === 'number' && isFinite(value);
            };
            var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991;
        /***/ },
        /***/ "./src/utils/get-self-scope.js": function(module, __webpack_exports__, __webpack_require__) {
            "use strict";
            __webpack_require__.r(__webpack_exports__);
            /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getSelfScope", function() {
                return getSelfScope;
            });
            function getSelfScope() {
                // see https://stackoverflow.com/a/11237259/589493
                if (typeof window === 'undefined') /* eslint-disable-next-line no-undef */ return self;
                else return window;
            }
        /***/ },
        /***/ "./src/utils/logger.js": function(module, __webpack_exports__, __webpack_require__) {
            "use strict";
            __webpack_require__.r(__webpack_exports__);
            /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enableLogs", function() {
                return enableLogs;
            });
            /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "logger", function() {
                return logger;
            });
            /* harmony import */ var _get_self_scope__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./get-self-scope */ "./src/utils/get-self-scope.js");
            function noop() {
            }
            var fakeLogger = {
                trace: noop,
                debug: noop,
                log: noop,
                warn: noop,
                info: noop,
                error: noop
            };
            var exportedLogger = fakeLogger; // let lastCallTime;
            // function formatMsgWithTimeInfo(type, msg) {
            //   const now = Date.now();
            //   const diff = lastCallTime ? '+' + (now - lastCallTime) : '0';
            //   lastCallTime = now;
            //   msg = (new Date(now)).toISOString() + ' | [' +  type + '] > ' + msg + ' ( ' + diff + ' ms )';
            //   return msg;
            // }
            function formatMsg(type, msg) {
                msg = '[' + type + '] > ' + msg;
                return msg;
            }
            var global = Object(_get_self_scope__WEBPACK_IMPORTED_MODULE_0__["getSelfScope"])();
            function consolePrintFn(type) {
                var func = global.console[type];
                if (func) return function() {
                    for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++)args[_key] = arguments[_key];
                    if (args[0]) args[0] = formatMsg(type, args[0]);
                    func.apply(global.console, args);
                };
                return noop;
            }
            function exportLoggerFunctions(debugConfig) {
                for(var _len2 = arguments.length, functions = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++)functions[_key2 - 1] = arguments[_key2];
                functions.forEach(function(type) {
                    exportedLogger[type] = debugConfig[type] ? debugConfig[type].bind(debugConfig) : consolePrintFn(type);
                });
            }
            var enableLogs = function enableLogs(debugConfig) {
                // check that console is available
                if (global.console && debugConfig === true || typeof debugConfig === 'object') {
                    exportLoggerFunctions(debugConfig, // 'trace',
                    'debug', 'log', 'info', 'warn', 'error'); // Some browsers don't allow to use bind on console object anyway
                    // fallback to default if needed
                    try {
                        exportedLogger.log();
                    } catch (e) {
                        exportedLogger = fakeLogger;
                    }
                } else exportedLogger = fakeLogger;
            };
            var logger = exportedLogger;
        /***/ }
    })["default"]);
});

},{}],"7UXcy":[function(require,module,exports) {
var Buffer = require("buffer").Buffer;
'use strict';
class HlsjsIPFSLoader {
    constructor(config){
        this._abortFlag = [
            false
        ];
        this.ipfs = config.ipfs;
        this.hash = config.ipfsHash;
        if (config.debug === false) this.debug = function() {
        };
        else if (config.debug === true) this.debug = console.log;
        else this.debug = config.debug;
        if (config.m3u8provider) this.m3u8provider = config.m3u8provider;
        else this.m3u8provider = null;
        if (config.tsListProvider) this.tsListProvider = config.tsListProvider;
        else this.tsListProvider = null;
    }
    destroy() {
    }
    abort() {
        this._abortFlag[0] = true;
    }
    load(context, config1, callbacks) {
        this.context = context;
        this.config = config1;
        this.callbacks = callbacks;
        this.stats = {
            trequest: performance.now(),
            retry: 0
        };
        this.retryDelay = config1.retryDelay;
        this.loadInternal();
    }
    /**
   * Call this by getting the HLSIPFSLoader instance from hls.js hls.coreComponents[0].loaders.manifest.setM3U8Provider()
   * @param {function} provider
   */ setM3U8Provider(provider) {
        this.m3u8provider = provider;
    }
    /**
   *
   * @param {function} provider
   */ setTsListProvider(provider1) {
        this.tsListProvider = provider1;
    }
    loadInternal() {
        const { stats , context , callbacks  } = this;
        stats.tfirst = Math.max(performance.now(), stats.trequest);
        stats.loaded = 0;
        //When using absolute path (https://example.com/index.html) vs https://example.com/
        const urlParts = window.location.href.split("/");
        if (urlParts[urlParts.length - 1] !== "") urlParts[urlParts.length - 1] = "";
        const filename = context.url.replace(urlParts.join("/"), "");
        const options = {
        };
        if (Number.isFinite(context.rangeStart)) {
            options.offset = context.rangeStart;
            if (Number.isFinite(context.rangeEnd)) options.length = context.rangeEnd - context.rangeStart;
        }
        if (filename.split(".")[1] === "m3u8" && this.m3u8provider !== null) {
            const res = this.m3u8provider();
            let data;
            if (Buffer.isBuffer(res)) data = buf2str(res);
            else data = res;
            const response = {
                url: context.url,
                data: data
            };
            callbacks.onSuccess(response, stats, context);
            return;
        }
        if (filename.split(".")[1] === "m3u8" && this.tsListProvider !== null) {
            var tslist = this.tsListProvider();
            var hash = tslist[filename];
            if (hash) this.cat(hash).then((res)=>{
                let data;
                if (Buffer.isBuffer(res)) data = buf2str(res);
                else data = res;
                stats.loaded = stats.total = data.length;
                stats.tload = Math.max(stats.tfirst, performance.now());
                const response = {
                    url: context.url,
                    data: data
                };
                callbacks.onSuccess(response, stats, context);
            });
            return;
        }
        this._abortFlag[0] = false;
        getFile(this.ipfs, this.hash, filename, options, this.debug, this._abortFlag).then((res)=>{
            const data = context.responseType === 'arraybuffer' ? res : buf2str(res);
            stats.loaded = stats.total = data.length;
            stats.tload = Math.max(stats.tfirst, performance.now());
            const response = {
                url: context.url,
                data: data
            };
            callbacks.onSuccess(response, stats, context);
        }, console.error);
    }
}
async function getFile(ipfs, rootHash, filename, options, debug, abortFlag) {
    debug(`Fetching hash for '${rootHash}/${filename}'`);
    const path = `${rootHash}/${filename}`;
    try {
        return await cat(path, options, ipfs, debug, abortFlag);
    } catch (ex) {
        throw new Error(`File not found: ${rootHash}/${filename}`);
    }
}
function buf2str(buf) {
    return new TextDecoder().decode(buf);
}
async function cat(cid, options, ipfs, debug, abortFlag) {
    const parts = [];
    let length = 0, offset = 0;
    for await (const buf of ipfs.cat(cid, options)){
        parts.push(buf);
        length += buf.length;
        if (abortFlag[0]) {
            debug('Cancel reading from ipfs');
            break;
        }
    }
    const value = new Uint8Array(length);
    for (const buf1 of parts){
        value.set(buf1, offset);
        offset += buf1.length;
    }
    debug(`Received data for file '${cid}' size: ${value.length} in ${parts.length} blocks`);
    return value;
}
exports = module.exports = HlsjsIPFSLoader;

},{"buffer":"eKea5"}]},["lBB98","hD4hw"], "hD4hw", "parcelRequire6d65")

//# sourceMappingURL=index.379dd93c.js.map
