'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.findEntryByContentBlock = undefined;let findEntryByContentBlock = exports.findEntryByContentBlock = (() => {var _ref = _asyncToGenerator(






































































































  function* (archive, block) {
    if (archive.metadata.length <= 0) {
      return;
    }

    // do a binary search
    let lo = 1;
    let hi = archive.metadata.length;
    const nextCursor = function () {return (hi + lo) / 2 | 0;};
    let cursor = nextCursor();
    while (lo <= hi) {
      // find a file entry in the current [lo, hi] range
      let entry;
      let st;
      let origCursor = cursor;
      while (true) {
        // fetch the entry
        entry = yield new _bluebird2.default(function (resolve) {return (
            archive.tree._getAndDecode(cursor, {}, function (err, e) {
              if (err) console.warn('Failed to fetch block', block, err);
              resolve(e);
            }));});
        if (!entry) {
          return; // read error, abort
        }
        if (entry.value) {
          st = archive.tree._codec.decode(entry.value);
          if (st.blocks !== 0) {
            break; // found a file
          }
        }
        cursor++;
        if (cursor > hi) cursor = lo; // overflow back to lo
        if (cursor === origCursor) {
          return; // no files in the current [lo, hi] range, not found
        }
      }

      // check the range
      const range = {
        name: entry.name,
        start: st.offset,
        end: st.offset + st.blocks - 1 };

      if (block >= range.start && block <= range.end) {
        // found
        return range;
      }

      // adjust range and try again
      if (block > range.end) {
        lo = cursor + 1;
      } else {
        hi = cursor - 1;
      }
      cursor = nextCursor();
    }
  });return function findEntryByContentBlock(_x, _x2) {return _ref.apply(this, arguments);};})();exports.stat = stat;exports.readdir = readdir;exports.download = download;var _bluebird = require('bluebird');var _bluebird2 = _interopRequireDefault(_bluebird);var _callMeMaybe = require('call-me-maybe');var _callMeMaybe2 = _interopRequireDefault(_callMeMaybe);var _co = require('co');var _co2 = _interopRequireDefault(_co);var _path = require('path');var _path2 = _interopRequireDefault(_path);function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function _asyncToGenerator(fn) {return function () {var gen = fn.apply(this, arguments);return new _bluebird2.default(function (resolve, reject) {function step(key, arg) {try {var info = gen[key](arg);var value = info.value;} catch (error) {reject(error);return;}if (info.done) {resolve(value);} else {return _bluebird2.default.resolve(value).then(function (value) {step("next", value);}, function (err) {step("throw", err);});}}return step("next");});};} // Helping with hyperdrive/ hypercore, trying to pull code out of DatWrapper
function normalize(rootPath, parentPath, subname) {const str = _path2.default.join(parentPath, subname).slice(rootPath.length);if (str.charAt(0) === '/') return str.slice(1);return str;} // From pauls-dat-api: lookup information about a file
function stat(archive, name, cb) {return (0, _callMeMaybe2.default)(cb, new _bluebird2.default((resolve, reject) => {// run stat operation
    archive.stat(name, (err, st) => {if (err) reject(err);else {// read download status
        st.downloaded = 0;if (archive.isStaging) {st.downloaded = st.blocks;} else if (archive.content && archive.content.length) {st.downloaded = archive.content.downloaded(st.offset, st.offset + st.blocks);}resolve(st);}});}));} // helper to list the files in a directory
function readdir(archive, name, fOpts, fCb) {const cb = typeof fOpts === 'function' ? fOpts : fCb;let opts = typeof fOpts === 'function' ? {} : fOpts;opts = opts || {};return (0, _callMeMaybe2.default)(cb, (0, _co2.default)(function* () {// options
    const recursive = opts && !!opts.recursive; // run first readdir
    const promise = new _bluebird2.default((resolve, reject) => {archive.readdir(name, (err, names) => {if (err) reject(err);else resolve(names);});});let results = yield promise; // recurse if requested
    if (recursive) {const rootPath = name;const readdirSafe = n => new _bluebird2.default(resolve => {archive.readdir(n, (_, names) => resolve(names || []));});const recurse = _co2.default.wrap(function* (names, parentPath) {yield _bluebird2.default.all(names.map(_co2.default.wrap(function* (n) {const thisPath = _path2.default.join(parentPath, n);const subnames = yield readdirSafe(thisPath);yield recurse(subnames, thisPath);results = results.concat(subnames.map(subname => normalize(rootPath, thisPath, subname)));})));});yield recurse(results, name);}return results;}));} // download the given file(s)
function download(archive, name, cb) {return (0, _callMeMaybe2.default)(cb, (0, _co2.default)(function* () {// lookup the entry
    const entry = yield stat(archive, name);if (!entry) {throw new Error(`The entry ${name} was not found in the archive.`);} // recurse on a directory
    if (entry.isDirectory()) {const listing = yield readdir(archive, name);const promises = listing.map(subname => download(archive, _path2.default.join(name, subname)));return _bluebird2.default.all(promises);} // prioritize a file
    if (entry.isFile()) {return new _bluebird2.default((resolve, reject) => {archive.content.download({ start: entry.offset, end: entry.offset + entry.blocks }, err => {if (err) reject(err);else resolve();});});}}));}