/* eslint-disable no-undefined,no-param-reassign,no-shadow */ /** * Throttle execution of a function. Especially useful for rate limiting * execution of handlers on events like resize and scroll. * * @param {number} delay - A zero-or-greater delay in milliseconds. For event callbacks, values around 100 or 250 (or even higher) * are most useful. * @param {Function} callback - A function to be executed after delay milliseconds. The `this` context and all arguments are passed through, * as-is, to `callback` when the throttled-function is executed. * @param {object} [options] - An object to configure options. * @param {boolean} [options.noTrailing] - Optional, defaults to false. If noTrailing is true, callback will only execute every `delay` milliseconds * while the throttled-function is being called. If noTrailing is false or unspecified, callback will be executed * one final time after the last throttled-function call. (After the throttled-function has not been called for * `delay` milliseconds, the internal counter is reset). * @param {boolean} [options.noLeading] - Optional, defaults to false. If noLeading is false, the first throttled-function call will execute callback * immediately. If noLeading is true, the first the callback execution will be skipped. It should be noted that * callback will never executed if both noLeading = true and noTrailing = true. * @param {boolean} [options.debounceMode] - If `debounceMode` is true (at begin), schedule `clear` to execute after `delay` ms. If `debounceMode` is * false (at end), schedule `callback` to execute after `delay` ms. * * @returns {Function} A new, throttled, function. */ function throttle (delay, callback, options) { var _ref = options || {}, _ref$noTrailing = _ref.noTrailing, noTrailing = _ref$noTrailing === void 0 ? false : _ref$noTrailing, _ref$noLeading = _ref.noLeading, noLeading = _ref$noLeading === void 0 ? false : _ref$noLeading, _ref$debounceMode = _ref.debounceMode, debounceMode = _ref$debounceMode === void 0 ? undefined : _ref$debounceMode; /* * After wrapper has stopped being called, this timeout ensures that * `callback` is executed at the proper times in `throttle` and `end` * debounce modes. */ var timeoutID; var cancelled = false; // Keep track of the last time `callback` was executed. var lastExec = 0; // Function to clear existing timeout function clearExistingTimeout() { if (timeoutID) { clearTimeout(timeoutID); } } // Function to cancel next exec function cancel(options) { var _ref2 = options || {}, _ref2$upcomingOnly = _ref2.upcomingOnly, upcomingOnly = _ref2$upcomingOnly === void 0 ? false : _ref2$upcomingOnly; clearExistingTimeout(); cancelled = !upcomingOnly; } /* * The `wrapper` function encapsulates all of the throttling / debouncing * functionality and when executed will limit the rate at which `callback` * is executed. */ function wrapper() { for (var _len = arguments.length, arguments_ = new Array(_len), _key = 0; _key < _len; _key++) { arguments_[_key] = arguments[_key]; } var self = this; var elapsed = Date.now() - lastExec; if (cancelled) { return; } // Execute `callback` and update the `lastExec` timestamp. function exec() { lastExec = Date.now(); callback.apply(self, arguments_); } /* * If `debounceMode` is true (at begin) this is used to clear the flag * to allow future `callback` executions. */ function clear() { timeoutID = undefined; } if (!noLeading && debounceMode && !timeoutID) { /* * Since `wrapper` is being called for the first time and * `debounceMode` is true (at begin), execute `callback` * and noLeading != true. */ exec(); } clearExistingTimeout(); if (debounceMode === undefined && elapsed > delay) { if (noLeading) { /* * In throttle mode with noLeading, if `delay` time has * been exceeded, update `lastExec` and schedule `callback` * to execute after `delay` ms. */ lastExec = Date.now(); if (!noTrailing) { timeoutID = setTimeout(debounceMode ? clear : exec, delay); } } else { /* * In throttle mode without noLeading, if `delay` time has been exceeded, execute * `callback`. */ exec(); } } else if (noTrailing !== true) { /* * In trailing throttle mode, since `delay` time has not been * exceeded, schedule `callback` to execute `delay` ms after most * recent execution. * * If `debounceMode` is true (at begin), schedule `clear` to execute * after `delay` ms. * * If `debounceMode` is false (at end), schedule `callback` to * execute after `delay` ms. */ timeoutID = setTimeout(debounceMode ? clear : exec, debounceMode === undefined ? delay - elapsed : delay); } } wrapper.cancel = cancel; // Return the wrapper function. return wrapper; } /* eslint-disable no-undefined */ /** * Debounce execution of a function. Debouncing, unlike throttling, * guarantees that a function is only executed a single time, either at the * very beginning of a series of calls, or at the very end. * * @param {number} delay - A zero-or-greater delay in milliseconds. For event callbacks, values around 100 or 250 (or even higher) are most useful. * @param {Function} callback - A function to be executed after delay milliseconds. The `this` context and all arguments are passed through, as-is, * to `callback` when the debounced-function is executed. * @param {object} [options] - An object to configure options. * @param {boolean} [options.atBegin] - Optional, defaults to false. If atBegin is false or unspecified, callback will only be executed `delay` milliseconds * after the last debounced-function call. If atBegin is true, callback will be executed only at the first debounced-function call. * (After the throttled-function has not been called for `delay` milliseconds, the internal counter is reset). * * @returns {Function} A new, debounced function. */ function debounce (delay, callback, options) { var _ref = options || {}, _ref$atBegin = _ref.atBegin, atBegin = _ref$atBegin === void 0 ? false : _ref$atBegin; return throttle(delay, callback, { debounceMode: atBegin !== false }); } export { debounce, throttle }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VzIjpbIi4uL3Rocm90dGxlLmpzIiwiLi4vZGVib3VuY2UuanMiXSwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgbm8tdW5kZWZpbmVkLG5vLXBhcmFtLXJlYXNzaWduLG5vLXNoYWRvdyAqL1xuXG4vKipcbiAqIFRocm90dGxlIGV4ZWN1dGlvbiBvZiBhIGZ1bmN0aW9uLiBFc3BlY2lhbGx5IHVzZWZ1bCBmb3IgcmF0ZSBsaW1pdGluZ1xuICogZXhlY3V0aW9uIG9mIGhhbmRsZXJzIG9uIGV2ZW50cyBsaWtlIHJlc2l6ZSBhbmQgc2Nyb2xsLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBkZWxheSAtICAgICAgICAgICAgICAgICAgQSB6ZXJvLW9yLWdyZWF0ZXIgZGVsYXkgaW4gbWlsbGlzZWNvbmRzLiBGb3IgZXZlbnQgY2FsbGJhY2tzLCB2YWx1ZXMgYXJvdW5kIDEwMCBvciAyNTAgKG9yIGV2ZW4gaGlnaGVyKVxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZSBtb3N0IHVzZWZ1bC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIC0gICAgICAgICAgICAgICBBIGZ1bmN0aW9uIHRvIGJlIGV4ZWN1dGVkIGFmdGVyIGRlbGF5IG1pbGxpc2Vjb25kcy4gVGhlIGB0aGlzYCBjb250ZXh0IGFuZCBhbGwgYXJndW1lbnRzIGFyZSBwYXNzZWQgdGhyb3VnaCxcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcy1pcywgdG8gYGNhbGxiYWNrYCB3aGVuIHRoZSB0aHJvdHRsZWQtZnVuY3Rpb24gaXMgZXhlY3V0ZWQuXG4gKiBAcGFyYW0ge29iamVjdH0gW29wdGlvbnNdIC0gICAgICAgICAgICAgIEFuIG9iamVjdCB0byBjb25maWd1cmUgb3B0aW9ucy5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMubm9UcmFpbGluZ10gLSAgIE9wdGlvbmFsLCBkZWZhdWx0cyB0byBmYWxzZS4gSWYgbm9UcmFpbGluZyBpcyB0cnVlLCBjYWxsYmFjayB3aWxsIG9ubHkgZXhlY3V0ZSBldmVyeSBgZGVsYXlgIG1pbGxpc2Vjb25kc1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIHRoZSB0aHJvdHRsZWQtZnVuY3Rpb24gaXMgYmVpbmcgY2FsbGVkLiBJZiBub1RyYWlsaW5nIGlzIGZhbHNlIG9yIHVuc3BlY2lmaWVkLCBjYWxsYmFjayB3aWxsIGJlIGV4ZWN1dGVkXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25lIGZpbmFsIHRpbWUgYWZ0ZXIgdGhlIGxhc3QgdGhyb3R0bGVkLWZ1bmN0aW9uIGNhbGwuIChBZnRlciB0aGUgdGhyb3R0bGVkLWZ1bmN0aW9uIGhhcyBub3QgYmVlbiBjYWxsZWQgZm9yXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYGRlbGF5YCBtaWxsaXNlY29uZHMsIHRoZSBpbnRlcm5hbCBjb3VudGVyIGlzIHJlc2V0KS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMubm9MZWFkaW5nXSAtICAgT3B0aW9uYWwsIGRlZmF1bHRzIHRvIGZhbHNlLiBJZiBub0xlYWRpbmcgaXMgZmFsc2UsIHRoZSBmaXJzdCB0aHJvdHRsZWQtZnVuY3Rpb24gY2FsbCB3aWxsIGV4ZWN1dGUgY2FsbGJhY2tcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbW1lZGlhdGVseS4gSWYgbm9MZWFkaW5nIGlzIHRydWUsIHRoZSBmaXJzdCB0aGUgY2FsbGJhY2sgZXhlY3V0aW9uIHdpbGwgYmUgc2tpcHBlZC4gSXQgc2hvdWxkIGJlIG5vdGVkIHRoYXRcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayB3aWxsIG5ldmVyIGV4ZWN1dGVkIGlmIGJvdGggbm9MZWFkaW5nID0gdHJ1ZSBhbmQgbm9UcmFpbGluZyA9IHRydWUuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLmRlYm91bmNlTW9kZV0gLSBJZiBgZGVib3VuY2VNb2RlYCBpcyB0cnVlIChhdCBiZWdpbiksIHNjaGVkdWxlIGBjbGVhcmAgdG8gZXhlY3V0ZSBhZnRlciBgZGVsYXlgIG1zLiBJZiBgZGVib3VuY2VNb2RlYCBpc1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlIChhdCBlbmQpLCBzY2hlZHVsZSBgY2FsbGJhY2tgIHRvIGV4ZWN1dGUgYWZ0ZXIgYGRlbGF5YCBtcy5cbiAqXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IEEgbmV3LCB0aHJvdHRsZWQsIGZ1bmN0aW9uLlxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAoZGVsYXksIGNhbGxiYWNrLCBvcHRpb25zKSB7XG5cdGNvbnN0IHtcblx0XHRub1RyYWlsaW5nID0gZmFsc2UsXG5cdFx0bm9MZWFkaW5nID0gZmFsc2UsXG5cdFx0ZGVib3VuY2VNb2RlID0gdW5kZWZpbmVkXG5cdH0gPSBvcHRpb25zIHx8IHt9O1xuXHQvKlxuXHQgKiBBZnRlciB3cmFwcGVyIGhhcyBzdG9wcGVkIGJlaW5nIGNhbGxlZCwgdGhpcyB0aW1lb3V0IGVuc3VyZXMgdGhhdFxuXHQgKiBgY2FsbGJhY2tgIGlzIGV4ZWN1dGVkIGF0IHRoZSBwcm9wZXIgdGltZXMgaW4gYHRocm90dGxlYCBhbmQgYGVuZGBcblx0ICogZGVib3VuY2UgbW9kZXMuXG5cdCAqL1xuXHRsZXQgdGltZW91dElEO1xuXHRsZXQgY2FuY2VsbGVkID0gZmFsc2U7XG5cblx0Ly8gS2VlcCB0cmFjayBvZiB0aGUgbGFzdCB0aW1lIGBjYWxsYmFja2Agd2FzIGV4ZWN1dGVkLlxuXHRsZXQgbGFzdEV4ZWMgPSAwO1xuXG5cdC8vIEZ1bmN0aW9uIHRvIGNsZWFyIGV4aXN0aW5nIHRpbWVvdXRcblx0ZnVuY3Rpb24gY2xlYXJFeGlzdGluZ1RpbWVvdXQoKSB7XG5cdFx0aWYgKHRpbWVvdXRJRCkge1xuXHRcdFx0Y2xlYXJUaW1lb3V0KHRpbWVvdXRJRCk7XG5cdFx0fVxuXHR9XG5cblx0Ly8gRnVuY3Rpb24gdG8gY2FuY2VsIG5leHQgZXhlY1xuXHRmdW5jdGlvbiBjYW5jZWwob3B0aW9ucykge1xuXHRcdGNvbnN0IHsgdXBjb21pbmdPbmx5ID0gZmFsc2UgfSA9IG9wdGlvbnMgfHwge307XG5cdFx0Y2xlYXJFeGlzdGluZ1RpbWVvdXQoKTtcblx0XHRjYW5jZWxsZWQgPSAhdXBjb21pbmdPbmx5O1xuXHR9XG5cblx0Lypcblx0ICogVGhlIGB3cmFwcGVyYCBmdW5jdGlvbiBlbmNhcHN1bGF0ZXMgYWxsIG9mIHRoZSB0aHJvdHRsaW5nIC8gZGVib3VuY2luZ1xuXHQgKiBmdW5jdGlvbmFsaXR5IGFuZCB3aGVuIGV4ZWN1dGVkIHdpbGwgbGltaXQgdGhlIHJhdGUgYXQgd2hpY2ggYGNhbGxiYWNrYFxuXHQgKiBpcyBleGVjdXRlZC5cblx0ICovXG5cdGZ1bmN0aW9uIHdyYXBwZXIoLi4uYXJndW1lbnRzXykge1xuXHRcdGxldCBzZWxmID0gdGhpcztcblx0XHRsZXQgZWxhcHNlZCA9IERhdGUubm93KCkgLSBsYXN0RXhlYztcblxuXHRcdGlmIChjYW5jZWxsZWQpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBFeGVjdXRlIGBjYWxsYmFja2AgYW5kIHVwZGF0ZSB0aGUgYGxhc3RFeGVjYCB0aW1lc3RhbXAuXG5cdFx0ZnVuY3Rpb24gZXhlYygpIHtcblx0XHRcdGxhc3RFeGVjID0gRGF0ZS5ub3coKTtcblx0XHRcdGNhbGxiYWNrLmFwcGx5KHNlbGYsIGFyZ3VtZW50c18pO1xuXHRcdH1cblxuXHRcdC8qXG5cdFx0ICogSWYgYGRlYm91bmNlTW9kZWAgaXMgdHJ1ZSAoYXQgYmVnaW4pIHRoaXMgaXMgdXNlZCB0byBjbGVhciB0aGUgZmxhZ1xuXHRcdCAqIHRvIGFsbG93IGZ1dHVyZSBgY2FsbGJhY2tgIGV4ZWN1dGlvbnMuXG5cdFx0ICovXG5cdFx0ZnVuY3Rpb24gY2xlYXIoKSB7XG5cdFx0XHR0aW1lb3V0SUQgPSB1bmRlZmluZWQ7XG5cdFx0fVxuXG5cdFx0aWYgKCFub0xlYWRpbmcgJiYgZGVib3VuY2VNb2RlICYmICF0aW1lb3V0SUQpIHtcblx0XHRcdC8qXG5cdFx0XHQgKiBTaW5jZSBgd3JhcHBlcmAgaXMgYmVpbmcgY2FsbGVkIGZvciB0aGUgZmlyc3QgdGltZSBhbmRcblx0XHRcdCAqIGBkZWJvdW5jZU1vZGVgIGlzIHRydWUgKGF0IGJlZ2luKSwgZXhlY3V0ZSBgY2FsbGJhY2tgXG5cdFx0XHQgKiBhbmQgbm9MZWFkaW5nICE9IHRydWUuXG5cdFx0XHQgKi9cblx0XHRcdGV4ZWMoKTtcblx0XHR9XG5cblx0XHRjbGVhckV4aXN0aW5nVGltZW91dCgpO1xuXG5cdFx0aWYgKGRlYm91bmNlTW9kZSA9PT0gdW5kZWZpbmVkICYmIGVsYXBzZWQgPiBkZWxheSkge1xuXHRcdFx0aWYgKG5vTGVhZGluZykge1xuXHRcdFx0XHQvKlxuXHRcdFx0XHQgKiBJbiB0aHJvdHRsZSBtb2RlIHdpdGggbm9MZWFkaW5nLCBpZiBgZGVsYXlgIHRpbWUgaGFzXG5cdFx0XHRcdCAqIGJlZW4gZXhjZWVkZWQsIHVwZGF0ZSBgbGFzdEV4ZWNgIGFuZCBzY2hlZHVsZSBgY2FsbGJhY2tgXG5cdFx0XHRcdCAqIHRvIGV4ZWN1dGUgYWZ0ZXIgYGRlbGF5YCBtcy5cblx0XHRcdFx0ICovXG5cdFx0XHRcdGxhc3RFeGVjID0gRGF0ZS5ub3coKTtcblx0XHRcdFx0aWYgKCFub1RyYWlsaW5nKSB7XG5cdFx0XHRcdFx0dGltZW91dElEID0gc2V0VGltZW91dChkZWJvdW5jZU1vZGUgPyBjbGVhciA6IGV4ZWMsIGRlbGF5KTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Lypcblx0XHRcdFx0ICogSW4gdGhyb3R0bGUgbW9kZSB3aXRob3V0IG5vTGVhZGluZywgaWYgYGRlbGF5YCB0aW1lIGhhcyBiZWVuIGV4Y2VlZGVkLCBleGVjdXRlXG5cdFx0XHRcdCAqIGBjYWxsYmFja2AuXG5cdFx0XHRcdCAqL1xuXHRcdFx0XHRleGVjKCk7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIGlmIChub1RyYWlsaW5nICE9PSB0cnVlKSB7XG5cdFx0XHQvKlxuXHRcdFx0ICogSW4gdHJhaWxpbmcgdGhyb3R0bGUgbW9kZSwgc2luY2UgYGRlbGF5YCB0aW1lIGhhcyBub3QgYmVlblxuXHRcdFx0ICogZXhjZWVkZWQsIHNjaGVkdWxlIGBjYWxsYmFja2AgdG8gZXhlY3V0ZSBgZGVsYXlgIG1zIGFmdGVyIG1vc3Rcblx0XHRcdCAqIHJlY2VudCBleGVjdXRpb24uXG5cdFx0XHQgKlxuXHRcdFx0ICogSWYgYGRlYm91bmNlTW9kZWAgaXMgdHJ1ZSAoYXQgYmVnaW4pLCBzY2hlZHVsZSBgY2xlYXJgIHRvIGV4ZWN1dGVcblx0XHRcdCAqIGFmdGVyIGBkZWxheWAgbXMuXG5cdFx0XHQgKlxuXHRcdFx0ICogSWYgYGRlYm91bmNlTW9kZWAgaXMgZmFsc2UgKGF0IGVuZCksIHNjaGVkdWxlIGBjYWxsYmFja2AgdG9cblx0XHRcdCAqIGV4ZWN1dGUgYWZ0ZXIgYGRlbGF5YCBtcy5cblx0XHRcdCAqL1xuXHRcdFx0dGltZW91dElEID0gc2V0VGltZW91dChcblx0XHRcdFx0ZGVib3VuY2VNb2RlID8gY2xlYXIgOiBleGVjLFxuXHRcdFx0XHRkZWJvdW5jZU1vZGUgPT09IHVuZGVmaW5lZCA/IGRlbGF5IC0gZWxhcHNlZCA6IGRlbGF5XG5cdFx0XHQpO1xuXHRcdH1cblx0fVxuXG5cdHdyYXBwZXIuY2FuY2VsID0gY2FuY2VsO1xuXG5cdC8vIFJldHVybiB0aGUgd3JhcHBlciBmdW5jdGlvbi5cblx0cmV0dXJuIHdyYXBwZXI7XG59XG4iLCIvKiBlc2xpbnQtZGlzYWJsZSBuby11bmRlZmluZWQgKi9cblxuaW1wb3J0IHRocm90dGxlIGZyb20gJy4vdGhyb3R0bGUuanMnO1xuXG4vKipcbiAqIERlYm91bmNlIGV4ZWN1dGlvbiBvZiBhIGZ1bmN0aW9uLiBEZWJvdW5jaW5nLCB1bmxpa2UgdGhyb3R0bGluZyxcbiAqIGd1YXJhbnRlZXMgdGhhdCBhIGZ1bmN0aW9uIGlzIG9ubHkgZXhlY3V0ZWQgYSBzaW5nbGUgdGltZSwgZWl0aGVyIGF0IHRoZVxuICogdmVyeSBiZWdpbm5pbmcgb2YgYSBzZXJpZXMgb2YgY2FsbHMsIG9yIGF0IHRoZSB2ZXJ5IGVuZC5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gZGVsYXkgLSAgICAgICAgICAgICAgIEEgemVyby1vci1ncmVhdGVyIGRlbGF5IGluIG1pbGxpc2Vjb25kcy4gRm9yIGV2ZW50IGNhbGxiYWNrcywgdmFsdWVzIGFyb3VuZCAxMDAgb3IgMjUwIChvciBldmVuIGhpZ2hlcikgYXJlIG1vc3QgdXNlZnVsLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgLSAgICAgICAgICBBIGZ1bmN0aW9uIHRvIGJlIGV4ZWN1dGVkIGFmdGVyIGRlbGF5IG1pbGxpc2Vjb25kcy4gVGhlIGB0aGlzYCBjb250ZXh0IGFuZCBhbGwgYXJndW1lbnRzIGFyZSBwYXNzZWQgdGhyb3VnaCwgYXMtaXMsXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0byBgY2FsbGJhY2tgIHdoZW4gdGhlIGRlYm91bmNlZC1mdW5jdGlvbiBpcyBleGVjdXRlZC5cbiAqIEBwYXJhbSB7b2JqZWN0fSBbb3B0aW9uc10gLSAgICAgICAgICAgQW4gb2JqZWN0IHRvIGNvbmZpZ3VyZSBvcHRpb25zLlxuICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy5hdEJlZ2luXSAtICBPcHRpb25hbCwgZGVmYXVsdHMgdG8gZmFsc2UuIElmIGF0QmVnaW4gaXMgZmFsc2Ugb3IgdW5zcGVjaWZpZWQsIGNhbGxiYWNrIHdpbGwgb25seSBiZSBleGVjdXRlZCBgZGVsYXlgIG1pbGxpc2Vjb25kc1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWZ0ZXIgdGhlIGxhc3QgZGVib3VuY2VkLWZ1bmN0aW9uIGNhbGwuIElmIGF0QmVnaW4gaXMgdHJ1ZSwgY2FsbGJhY2sgd2lsbCBiZSBleGVjdXRlZCBvbmx5IGF0IHRoZSBmaXJzdCBkZWJvdW5jZWQtZnVuY3Rpb24gY2FsbC5cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChBZnRlciB0aGUgdGhyb3R0bGVkLWZ1bmN0aW9uIGhhcyBub3QgYmVlbiBjYWxsZWQgZm9yIGBkZWxheWAgbWlsbGlzZWNvbmRzLCB0aGUgaW50ZXJuYWwgY291bnRlciBpcyByZXNldCkuXG4gKlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBBIG5ldywgZGVib3VuY2VkIGZ1bmN0aW9uLlxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAoZGVsYXksIGNhbGxiYWNrLCBvcHRpb25zKSB7XG5cdGNvbnN0IHsgYXRCZWdpbiA9IGZhbHNlIH0gPSBvcHRpb25zIHx8IHt9O1xuXHRyZXR1cm4gdGhyb3R0bGUoZGVsYXksIGNhbGxiYWNrLCB7IGRlYm91bmNlTW9kZTogYXRCZWdpbiAhPT0gZmFsc2UgfSk7XG59XG4iXSwibmFtZXMiOlsiZGVsYXkiLCJjYWxsYmFjayIsIm9wdGlvbnMiLCJub1RyYWlsaW5nIiwibm9MZWFkaW5nIiwiZGVib3VuY2VNb2RlIiwidW5kZWZpbmVkIiwidGltZW91dElEIiwiY2FuY2VsbGVkIiwibGFzdEV4ZWMiLCJjbGVhckV4aXN0aW5nVGltZW91dCIsImNsZWFyVGltZW91dCIsImNhbmNlbCIsInVwY29taW5nT25seSIsIndyYXBwZXIiLCJhcmd1bWVudHNfIiwic2VsZiIsImVsYXBzZWQiLCJEYXRlIiwibm93IiwiZXhlYyIsImFwcGx5IiwiY2xlYXIiLCJzZXRUaW1lb3V0IiwiYXRCZWdpbiIsInRocm90dGxlIl0sIm1hcHBpbmdzIjoiQUFBQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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