{"version":3,"file":"trackProgress.mjs","sources":["../node_modules/lodash.throttle/index.js","../src/trackProgress.ts"],"sourcesContent":["/**\n * lodash (Custom Build) <https://lodash.com/>\n * Build: `lodash modularize exports=\"npm\" -o ./`\n * Copyright jQuery Foundation and other contributors <https://jquery.org/>\n * Released under MIT license <https://lodash.com/license>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\n\n/** Used as the `TypeError` message for \"Functions\" methods. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/** Used as references for various `Number` constants. */\nvar NAN = 0 / 0;\n\n/** `Object#toString` result references. */\nvar symbolTag = '[object Symbol]';\n\n/** Used to match leading and trailing whitespace. */\nvar reTrim = /^\\s+|\\s+$/g;\n\n/** Used to detect bad signed hexadecimal string values. */\nvar reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\n/** Used to detect binary string values. */\nvar reIsBinary = /^0b[01]+$/i;\n\n/** Used to detect octal string values. */\nvar reIsOctal = /^0o[0-7]+$/i;\n\n/** Built-in method references without a dependency on `root`. */\nvar freeParseInt = parseInt;\n\n/** Detect free variable `global` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max,\n    nativeMin = Math.min;\n\n/**\n * Gets the timestamp of the number of milliseconds that have elapsed since\n * the Unix epoch (1 January 1970 00:00:00 UTC).\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Date\n * @returns {number} Returns the timestamp.\n * @example\n *\n * _.defer(function(stamp) {\n *   console.log(_.now() - stamp);\n * }, _.now());\n * // => Logs the number of milliseconds it took for the deferred invocation.\n */\nvar now = function() {\n  return root.Date.now();\n};\n\n/**\n * Creates a debounced function that delays invoking `func` until after `wait`\n * milliseconds have elapsed since the last time the debounced function was\n * invoked. The debounced function comes with a `cancel` method to cancel\n * delayed `func` invocations and a `flush` method to immediately invoke them.\n * Provide `options` to indicate whether `func` should be invoked on the\n * leading and/or trailing edge of the `wait` timeout. The `func` is invoked\n * with the last arguments provided to the debounced function. Subsequent\n * calls to the debounced function return the result of the last `func`\n * invocation.\n *\n * **Note:** If `leading` and `trailing` options are `true`, `func` is\n * invoked on the trailing edge of the timeout only if the debounced function\n * is invoked more than once during the `wait` timeout.\n *\n * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred\n * until to the next tick, similar to `setTimeout` with a timeout of `0`.\n *\n * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n * for details over the differences between `_.debounce` and `_.throttle`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to debounce.\n * @param {number} [wait=0] The number of milliseconds to delay.\n * @param {Object} [options={}] The options object.\n * @param {boolean} [options.leading=false]\n *  Specify invoking on the leading edge of the timeout.\n * @param {number} [options.maxWait]\n *  The maximum time `func` is allowed to be delayed before it's invoked.\n * @param {boolean} [options.trailing=true]\n *  Specify invoking on the trailing edge of the timeout.\n * @returns {Function} Returns the new debounced function.\n * @example\n *\n * // Avoid costly calculations while the window size is in flux.\n * jQuery(window).on('resize', _.debounce(calculateLayout, 150));\n *\n * // Invoke `sendMail` when clicked, debouncing subsequent calls.\n * jQuery(element).on('click', _.debounce(sendMail, 300, {\n *   'leading': true,\n *   'trailing': false\n * }));\n *\n * // Ensure `batchLog` is invoked once after 1 second of debounced calls.\n * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });\n * var source = new EventSource('/stream');\n * jQuery(source).on('message', debounced);\n *\n * // Cancel the trailing debounced invocation.\n * jQuery(window).on('popstate', debounced.cancel);\n */\nfunction debounce(func, wait, options) {\n  var lastArgs,\n      lastThis,\n      maxWait,\n      result,\n      timerId,\n      lastCallTime,\n      lastInvokeTime = 0,\n      leading = false,\n      maxing = false,\n      trailing = true;\n\n  if (typeof func != 'function') {\n    throw new TypeError(FUNC_ERROR_TEXT);\n  }\n  wait = toNumber(wait) || 0;\n  if (isObject(options)) {\n    leading = !!options.leading;\n    maxing = 'maxWait' in options;\n    maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;\n    trailing = 'trailing' in options ? !!options.trailing : trailing;\n  }\n\n  function invokeFunc(time) {\n    var args = lastArgs,\n        thisArg = lastThis;\n\n    lastArgs = lastThis = undefined;\n    lastInvokeTime = time;\n    result = func.apply(thisArg, args);\n    return result;\n  }\n\n  function leadingEdge(time) {\n    // Reset any `maxWait` timer.\n    lastInvokeTime = time;\n    // Start the timer for the trailing edge.\n    timerId = setTimeout(timerExpired, wait);\n    // Invoke the leading edge.\n    return leading ? invokeFunc(time) : result;\n  }\n\n  function remainingWait(time) {\n    var timeSinceLastCall = time - lastCallTime,\n        timeSinceLastInvoke = time - lastInvokeTime,\n        result = wait - timeSinceLastCall;\n\n    return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;\n  }\n\n  function shouldInvoke(time) {\n    var timeSinceLastCall = time - lastCallTime,\n        timeSinceLastInvoke = time - lastInvokeTime;\n\n    // Either this is the first call, activity has stopped and we're at the\n    // trailing edge, the system time has gone backwards and we're treating\n    // it as the trailing edge, or we've hit the `maxWait` limit.\n    return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||\n      (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));\n  }\n\n  function timerExpired() {\n    var time = now();\n    if (shouldInvoke(time)) {\n      return trailingEdge(time);\n    }\n    // Restart the timer.\n    timerId = setTimeout(timerExpired, remainingWait(time));\n  }\n\n  function trailingEdge(time) {\n    timerId = undefined;\n\n    // Only invoke if we have `lastArgs` which means `func` has been\n    // debounced at least once.\n    if (trailing && lastArgs) {\n      return invokeFunc(time);\n    }\n    lastArgs = lastThis = undefined;\n    return result;\n  }\n\n  function cancel() {\n    if (timerId !== undefined) {\n      clearTimeout(timerId);\n    }\n    lastInvokeTime = 0;\n    lastArgs = lastCallTime = lastThis = timerId = undefined;\n  }\n\n  function flush() {\n    return timerId === undefined ? result : trailingEdge(now());\n  }\n\n  function debounced() {\n    var time = now(),\n        isInvoking = shouldInvoke(time);\n\n    lastArgs = arguments;\n    lastThis = this;\n    lastCallTime = time;\n\n    if (isInvoking) {\n      if (timerId === undefined) {\n        return leadingEdge(lastCallTime);\n      }\n      if (maxing) {\n        // Handle invocations in a tight loop.\n        timerId = setTimeout(timerExpired, wait);\n        return invokeFunc(lastCallTime);\n      }\n    }\n    if (timerId === undefined) {\n      timerId = setTimeout(timerExpired, wait);\n    }\n    return result;\n  }\n  debounced.cancel = cancel;\n  debounced.flush = flush;\n  return debounced;\n}\n\n/**\n * Creates a throttled function that only invokes `func` at most once per\n * every `wait` milliseconds. The throttled function comes with a `cancel`\n * method to cancel delayed `func` invocations and a `flush` method to\n * immediately invoke them. Provide `options` to indicate whether `func`\n * should be invoked on the leading and/or trailing edge of the `wait`\n * timeout. The `func` is invoked with the last arguments provided to the\n * throttled function. Subsequent calls to the throttled function return the\n * result of the last `func` invocation.\n *\n * **Note:** If `leading` and `trailing` options are `true`, `func` is\n * invoked on the trailing edge of the timeout only if the throttled function\n * is invoked more than once during the `wait` timeout.\n *\n * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred\n * until to the next tick, similar to `setTimeout` with a timeout of `0`.\n *\n * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n * for details over the differences between `_.throttle` and `_.debounce`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to throttle.\n * @param {number} [wait=0] The number of milliseconds to throttle invocations to.\n * @param {Object} [options={}] The options object.\n * @param {boolean} [options.leading=true]\n *  Specify invoking on the leading edge of the timeout.\n * @param {boolean} [options.trailing=true]\n *  Specify invoking on the trailing edge of the timeout.\n * @returns {Function} Returns the new throttled function.\n * @example\n *\n * // Avoid excessively updating the position while scrolling.\n * jQuery(window).on('scroll', _.throttle(updatePosition, 100));\n *\n * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.\n * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });\n * jQuery(element).on('click', throttled);\n *\n * // Cancel the trailing throttled invocation.\n * jQuery(window).on('popstate', throttled.cancel);\n */\nfunction throttle(func, wait, options) {\n  var leading = true,\n      trailing = true;\n\n  if (typeof func != 'function') {\n    throw new TypeError(FUNC_ERROR_TEXT);\n  }\n  if (isObject(options)) {\n    leading = 'leading' in options ? !!options.leading : leading;\n    trailing = 'trailing' in options ? !!options.trailing : trailing;\n  }\n  return debounce(func, wait, {\n    'leading': leading,\n    'maxWait': wait,\n    'trailing': trailing\n  });\n}\n\n/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n  return !!value && typeof value == 'object';\n}\n\n/**\n * Checks if `value` is classified as a `Symbol` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n  return typeof value == 'symbol' ||\n    (isObjectLike(value) && objectToString.call(value) == symbolTag);\n}\n\n/**\n * Converts `value` to a number.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to process.\n * @returns {number} Returns the number.\n * @example\n *\n * _.toNumber(3.2);\n * // => 3.2\n *\n * _.toNumber(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toNumber(Infinity);\n * // => Infinity\n *\n * _.toNumber('3.2');\n * // => 3.2\n */\nfunction toNumber(value) {\n  if (typeof value == 'number') {\n    return value;\n  }\n  if (isSymbol(value)) {\n    return NAN;\n  }\n  if (isObject(value)) {\n    var other = typeof value.valueOf == 'function' ? value.valueOf() : value;\n    value = isObject(other) ? (other + '') : other;\n  }\n  if (typeof value != 'string') {\n    return value === 0 ? value : +value;\n  }\n  value = value.replace(reTrim, '');\n  var isBinary = reIsBinary.test(value);\n  return (isBinary || reIsOctal.test(value))\n    ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n    : (reIsBadHex.test(value) ? NAN : +value);\n}\n\nmodule.exports = throttle;\n","import throttle from 'lodash.throttle';\n\ninterface ProgressTrackerConfig {\n  throttleWait: number;\n  [key: string]: any;\n}\n\ninterface CurrentProgress {\n  // total bytes to be transferred\n  total?: number;\n  // total bytes finished transfering\n  finished?: number;\n  // Overall percent; 0-100\n  percent?: number;\n  // Overall progress; 0-1\n  progress?: number;\n  // Total time elapsed in seconds\n  elapsed: number;\n  // Remaining time to completion in seconds\n  remaining?: number;\n  // Trnasfer speed in bytes/sec\n  speed?: number;\n  // Trnasfer speed in bits/sec\n  bitrate?: number;\n}\n\ninterface TransferEvent {\n    // total bytes to be transferred\n    total: number;\n    // total bytes finished transfering\n    finished: number;\n    computable: boolean;\n}\n\ntype MaybeProgressValue<T> = T | undefined;\n\nexport const fromXHREvent = (xhrEvent: ProgressEvent): TransferEvent => ({\n  computable: xhrEvent.lengthComputable,\n  finished: xhrEvent.loaded,\n  total: xhrEvent.total,\n});\n\nexport const createProgressTracker = ({\n  throttleWait,\n}: ProgressTrackerConfig = { throttleWait: 250 }) => {\n  const started = Date.now();\n\n  return throttle(({\n    total,\n    finished,\n    computable = total > 0 && finished >= 0,\n  }: TransferEvent): CurrentProgress => {\n    let elapsed: number;\n\n    let percent: MaybeProgressValue<number>;\n    let speed: MaybeProgressValue<number>;\n    let progress: MaybeProgressValue<number>;\n    let remaining: MaybeProgressValue<number>;\n    let bitrate: MaybeProgressValue<number>;\n\n    elapsed = (Date.now() - started) / 1000;\n\n    if (computable) {\n      percent = Math.round((finished * 100) / total);\n\n      // wait till values warm up\n      if (elapsed >= 1) {\n        speed = finished / elapsed;\n      }\n\n      if (total) {\n        progress = Math.min(finished, total) / total;\n\n        if (speed) {\n          bitrate = speed / 8;\n          remaining = 0;\n\n          if (percent < 100) {\n            remaining = (total / speed) - elapsed;\n            remaining = Number(remaining.toFixed(4));\n          }\n        }\n      }\n    }\n\n    return {\n      total,\n      finished,\n      percent,\n      progress,\n      elapsed,\n      remaining,\n      speed,\n      bitrate,\n    };\n  }, throttleWait);\n};\n"],"names":["NAN","symbolTag","reTrim","reIsBadHex","reIsBinary","reIsOctal","freeParseInt","parseInt","freeGlobal","global","Object","freeSelf","self","root","Function","objectToString","prototype","toString","nativeMax","Math","max","nativeMin","min","now","Date","isObject","value","type","toNumber","isObjectLike","call","isSymbol","other","valueOf","replace","isBinary","test","slice","fromXHREvent","xhrEvent","computable","lengthComputable","finished","loaded","total","createProgressTracker","ref","throttleWait","func","wait","leading","trailing","started","elapsed","percent","speed","progress","remaining","bitrate","round","Number","toFixed","throttle","options","lastArgs","lastThis","maxWait","result","timerId","lastCallTime","lastInvokeTime","maxing","TypeError","invokeFunc","time","args","thisArg","undefined","apply","shouldInvoke","timeSinceLastCall","timerExpired","trailingEdge","setTimeout","remainingWait","debounced","isInvoking","arguments","this","leadingEdge","cancel","clearTimeout","flush","debounce"],"mappings":"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"}