UNPKG

@orbit/core

Version:

Core library for Orbit - a flexible data access and synchronization layer.

164 lines 16.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.fulfillAll = exports.fulfillInSeries = exports.settleInSeries = exports.evented = exports.isEvented = void 0; const notifier_1 = require("./notifier"); const EVENTED = '__evented__'; /** * Has a class been decorated as `@evented`? */ function isEvented(obj) { return !!obj[EVENTED]; } exports.isEvented = isEvented; /** * Marks a class as evented. * * An evented class should also implement the `Evented` interface. * * ```ts * import { evented, Evented } from '@orbit/core'; * * @evented * class Source implements Evented { * ... * } * ``` * * Listeners can then register themselves for particular events with `on`: * * ```ts * let source = new Source(); * * function listener1(message: string) { * console.log('listener1 heard ' + message); * }; * function listener2(message: string) { * console.log('listener2 heard ' + message); * }; * * source.on('greeting', listener1); * source.on('greeting', listener2); * * evented.emit('greeting', 'hello'); // logs "listener1 heard hello" and * // "listener2 heard hello" * ``` * * Listeners can be unregistered from events at any time with `off`: * * ```ts * source.off('greeting', listener2); * ``` */ function evented(Klass) { let proto = Klass.prototype; if (isEvented(proto)) { return; } proto[EVENTED] = true; proto.on = function (eventName, listener) { return notifierForEvent(this, eventName, true).addListener(listener); }; proto.off = function (eventName, listener) { const notifier = notifierForEvent(this, eventName); if (notifier) { if (listener) { notifier.removeListener(listener); } else { removeNotifierForEvent(this, eventName); } } }; proto.one = function (eventName, listener) { const notifier = notifierForEvent(this, eventName, true); const callOnce = function () { listener(...arguments); notifier.removeListener(callOnce); }; return notifier.addListener(callOnce); }; proto.emit = function (eventName, ...args) { let notifier = notifierForEvent(this, eventName); if (notifier) { notifier.emit.apply(notifier, args); } }; proto.listeners = function (eventName) { let notifier = notifierForEvent(this, eventName); return notifier ? notifier.listeners : []; }; } exports.evented = evented; /** * Settle any promises returned by event listeners in series. * * Returns an array of results (or `undefined`) returned by listeners. * * If any errors are encountered during processing, they will be caught and * returned with other results. Errors will not interrupt further processing. */ async function settleInSeries(obj, eventName, ...args) { const listeners = obj.listeners(eventName); const results = []; for (let listener of listeners) { try { results.push(await listener(...args)); } catch (e) { results.push(e); } } return results; } exports.settleInSeries = settleInSeries; /** * Fulfills any promises returned by event listeners in series. * * Returns an array of results (or `undefined`) returned by listeners. * * On error, processing will stop and the returned promise will be rejected with * the error that was encountered. */ async function fulfillInSeries(obj, eventName, ...args) { const listeners = obj.listeners(eventName); const results = []; for (let listener of listeners) { results.push(await listener(...args)); } return results; } exports.fulfillInSeries = fulfillInSeries; /** * Fulfills any promises returned by event listeners in parallel, using * `Promise.all`. * * Returns an array of results (or `undefined`) returned by listeners. * * On error, processing will stop and the returned promise will be rejected with * the error that was encountered. */ async function fulfillAll(obj, eventName, ...args) { const listeners = obj.listeners(eventName); const promises = []; for (let listener of listeners) { promises.push(listener(...args)); } return Promise.all(promises); } exports.fulfillAll = fulfillAll; function notifierForEvent(object, eventName, createIfUndefined = false) { if (object._eventedNotifiers === undefined) { object._eventedNotifiers = {}; } let notifier = object._eventedNotifiers[eventName]; if (!notifier && createIfUndefined) { notifier = object._eventedNotifiers[eventName] = new notifier_1.Notifier(); } return notifier; } function removeNotifierForEvent(object, eventName) { if (object._eventedNotifiers && object._eventedNotifiers[eventName]) { delete object._eventedNotifiers[eventName]; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXZlbnRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ldmVudGVkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHlDQUFnRDtBQUVoRCxNQUFNLE9BQU8sR0FBRyxhQUFhLENBQUM7QUFFOUI7O0dBRUc7QUFDSCxTQUFnQixTQUFTLENBQUMsR0FBWTtJQUNwQyxPQUFPLENBQUMsQ0FBRSxHQUErQixDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ3JELENBQUM7QUFGRCw4QkFFQztBQXVCRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FzQ0c7QUFDSCxTQUFnQixPQUFPLENBQUMsS0FBeUI7SUFDL0MsSUFBSSxLQUFLLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQztJQUU1QixJQUFJLFNBQVMsQ0FBQyxLQUFLLENBQUMsRUFBRTtRQUNwQixPQUFPO0tBQ1I7SUFFRCxLQUFLLENBQUMsT0FBTyxDQUFDLEdBQUcsSUFBSSxDQUFDO0lBRXRCLEtBQUssQ0FBQyxFQUFFLEdBQUcsVUFBVSxTQUFpQixFQUFFLFFBQWtCO1FBQ3hELE9BQU8sZ0JBQWdCLENBQUMsSUFBSSxFQUFFLFNBQVMsRUFBRSxJQUFJLENBQUMsQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDdkUsQ0FBQyxDQUFDO0lBRUYsS0FBSyxDQUFDLEdBQUcsR0FBRyxVQUFVLFNBQWlCLEVBQUUsUUFBa0I7UUFDekQsTUFBTSxRQUFRLEdBQUcsZ0JBQWdCLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBRW5ELElBQUksUUFBUSxFQUFFO1lBQ1osSUFBSSxRQUFRLEVBQUU7Z0JBQ1osUUFBUSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsQ0FBQzthQUNuQztpQkFBTTtnQkFDTCxzQkFBc0IsQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLENBQUM7YUFDekM7U0FDRjtJQUNILENBQUMsQ0FBQztJQUVGLEtBQUssQ0FBQyxH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QUFNLENBQUMsaUJBQWlCLEtBQUssU0FBUyxFQUFFO1FBQzFDLE1BQU0sQ0FBQyxpQkFBaUIsR0FBRyxFQUFFLENBQUM7S0FDL0I7SUFDRCxJQUFJLFFBQVEsR0FBRyxNQUFNLENBQUMsaUJBQWlCLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDbkQsSUFBSSxDQUFDLFFBQVEsSUFBSSxpQkFBaUIsRUFBRTtRQUNsQyxRQUFRLEdBQUcsTUFBTSxDQUFDLGlCQUFpQixDQUFDLFNBQVMsQ0FBQyxHQUFHLElBQUksbUJBQVEsRUFBRSxDQUFDO0tBQ2pFO0lBQ0QsT0FBTyxRQUFRLENBQUM7QUFDbEIsQ0FBQztBQUVELFNBQVMsc0JBQXNCLENBQUMsTUFBVyxFQUFFLFNBQWlCO0lBQzVELElBQUksTUFBTSxDQUFDLGlCQUFpQixJQUFJLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsRUFBRTtRQUNuRSxPQUFPLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsQ0FBQztLQUM1QztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBOb3RpZmllciwgTGlzdGVuZXIgfSBmcm9tICcuL25vdGlmaWVyJztcblxuY29uc3QgRVZFTlRFRCA9ICdfX2V2ZW50ZWRfXyc7XG5cbi8qKlxuICogSGFzIGEgY2xhc3MgYmVlbiBkZWNvcmF0ZWQgYXMgYEBldmVudGVkYD9cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRXZlbnRlZChvYmo6IHVua25vd24pOiBib29sZWFuIHtcbiAgcmV0dXJuICEhKG9iaiBhcyB7IFtFVkVOVEVEXT86IGJvb2xlYW4gfSlbRVZFTlRFRF07XG59XG5cbi8qKlxuICogQSBjbGFzcyBkZWNvcmF0ZWQgYXMgYEBldmVudGVkYCBzaG91bGQgYWxzbyBpbXBsZW1lbnQgdGhlIGBFdmVudGVkYFxuICogaW50ZXJmYWNlLlxuICpcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyBldmVudGVkLCBFdmVudGVkIH0gZnJvbSAnQG9yYml0L2NvcmUnO1xuICpcbiAqIEBldmVudGVkXG4gKiBjbGFzcyBTb3VyY2UgaW1wbGVtZW50cyBFdmVudGVkIHtcbiAqICAgLy8gLi4uIEV2ZW50ZWQgaW1wbGVtZW50YXRpb25cbiAqIH1cbiAqIGBgYFxuICovXG5leHBvcnQgaW50ZXJmYWNlIEV2ZW50ZWQ8RXZlbnQgZXh0ZW5kcyBzdHJpbmcgPSBzdHJpbmc+IHtcbiAgb246IChldmVudDogRXZlbnQsIGxpc3RlbmVyOiBMaXN0ZW5lcikgPT4gKCkgPT4gdm9pZDtcbiAgb2ZmOiAoZXZlbnQ6IEV2ZW50LCBsaXN0ZW5lcj86IExpc3RlbmVyKSA9PiB2b2lkO1xuICBvbmU6IChldmVudDogRXZlbnQsIGxpc3RlbmVyOiBMaXN0ZW5lcikgPT4gKCkgPT4gdm9pZDtcbiAgZW1pdDogKGV2ZW50OiBFdmVudCwgLi4uYXJnczogdW5rbm93bltdKSA9PiB2b2lkO1xuICBsaXN0ZW5lcnM6IChldmVudDogRXZlbnQpID0+IExpc3RlbmVyW107XG59XG5cbi8qKlxuICogTWFya3MgYSBjbGFzcyBhcyBldmVudGVkLlxuICpcbiAqIEFuIGV2ZW50ZWQgY2xhc3Mgc2hvdWxkIGFsc28gaW1wbGVtZW50IHRoZSBgRXZlbnRlZGAgaW50ZXJmYWNlLlxuICpcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyBldmVudGVkLCBFdmVudGVkIH0gZnJvbSAnQG9yYml0L2NvcmUnO1xuICpcbiAqIEBldmVudGVkXG4gKiBjbGFzcyBTb3VyY2UgaW1wbGVtZW50cyBFdmVudGVkIHtcbiAqICAgLi4uXG4gKiB9XG4gKiBgYGBcbiAqXG4gKiBMaXN0ZW5lcnMgY2FuIHRoZW4gcmVnaXN0ZXIgdGhlbXNlbHZlcyBmb3IgcGFydGljdWxhciBldmVudHMgd2l0aCBgb25gOlxuICpcbiAqIGBgYHRzXG4gKiBsZXQgc291cmNlID0gbmV3IFNvdXJjZSgpO1xuICpcbiAqIGZ1bmN0aW9uIGxpc3RlbmVyMShtZXNzYWdlOiBzdHJpbmcpIHtcbiAqICAgY29uc29sZS5sb2coJ2xpc3RlbmVyMSBoZWFyZCAnICsgbWVzc2FnZSk7XG4gKiB9O1xuICogZnVuY3Rpb24gbGlzdGVuZXIyKG1lc3NhZ2U6IHN0cmluZykge1xuICogICBjb25zb2xlLmxvZygnbGlzdGVuZXIyIGhlYXJkICcgKyBtZXNzYWdlKTtcbiAqIH07XG4gKlxuICogc291cmNlLm9uKCdncmVldGluZycsIGxpc3RlbmVyMSk7XG4gKiBzb3VyY2Uub24oJ2dyZWV0aW5nJywgbGlzdGVuZXIyKTtcbiAqXG4gKiBldmVudGVkLmVtaXQoJ2dyZWV0aW5nJywgJ2hlbGxvJyk7IC8vIGxvZ3MgXCJsaXN0ZW5lcjEgaGVhcmQgaGVsbG9cIiBhbmRcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgICBcImxpc3RlbmVyMiBoZWFyZCBoZWxsb1wiXG4gKiBgYGBcbiAqXG4gKiBMaXN0ZW5lcnMgY2FuIGJlIHVucmVnaXN0ZXJlZCBmcm9tIGV2ZW50cyBhdCBhbnkgdGltZSB3aXRoIGBvZmZgOlxuICpcbiAqIGBgYHRzXG4gKiBzb3VyY2Uub2ZmKCdncmVldGluZycsIGxpc3RlbmVyMik7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGV2ZW50ZWQoS2xhc3M6IHsgcHJvdG90eXBlOiBhbnkgfSk6IHZvaWQge1xuICBsZXQgcHJvdG8gPSBLbGFzcy5wcm90b3R5cGU7XG5cbiAgaWYgKGlzRXZlbnRlZChwcm90bykpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBwcm90b1tFVkVOVEVEXSA9IHRydWU7XG5cbiAgcHJvdG8ub24gPSBmdW5jdGlvbiAoZXZlbnROYW1lOiBzdHJpbmcsIGxpc3RlbmVyOiBMaXN0ZW5lcik6ICgpID0+IHZvaWQge1xuICAgIHJldHVybiBub3RpZmllckZvckV2ZW50KHRoaXMsIGV2ZW50TmFtZSwgdHJ1ZSkuYWRkTGlzdGVuZXIobGlzdGVuZXIpO1xuICB9O1xuXG4gIHByb3RvLm9mZiA9IGZ1bmN0aW9uIChldmVudE5hbWU6IHN0cmluZywgbGlzdGVuZXI6IExpc3RlbmVyKSB7XG4gICAgY29uc3Qgbm90aWZpZXIgPSBub3RpZmllckZvckV2ZW50KHRoaXMsIGV2ZW50TmFtZSk7XG5cbiAgICBpZiAobm90aWZpZXIpIHtcbiAgICAgIGlmIChsaXN0ZW5lcikge1xuICAgICAgICBub3RpZmllci5yZW1vdmVMaXN0ZW5lcihsaXN0ZW5lcik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZW1vdmVOb3RpZmllckZvckV2ZW50KHRoaXMsIGV2ZW50TmFtZSk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHByb3RvLm9uZSA9IGZ1bmN0aW9uIChldmVudE5hbWU6IHN0cmluZywgbGlzdGVuZXI6IExpc3RlbmVyKTogKCkgPT4gdm9pZCB7XG4gICAgY29uc3Qgbm90aWZpZXIgPSBub3RpZmllckZvckV2ZW50KHRoaXMsIGV2ZW50TmFtZSwgdHJ1ZSk7XG5cbiAgICBjb25zdCBjYWxsT25jZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIGxpc3RlbmVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICBub3RpZmllci5yZW1vdmVMaXN0ZW5lcihjYWxsT25jZSk7XG4gICAgfTtcblxuICAgIHJldHVybiBub3RpZmllci5hZGRMaXN0ZW5lcihjYWxsT25jZSk7XG4gIH07XG5cbiAgcHJvdG8uZW1pdCA9IGZ1bmN0aW9uIChldmVudE5hbWU6IHN0cmluZywgLi4uYXJnczogdW5rbm93bltdKSB7XG4gICAgbGV0IG5vdGlmaWVyID0gbm90aWZpZXJGb3JFdmVudCh0aGlzLCBldmVudE5hbWUpO1xuXG4gICAgaWYgKG5vdGlmaWVyKSB7XG4gICAgICBub3RpZmllci5lbWl0LmFwcGx5KG5vdGlmaWVyLCBhcmdzKTtcbiAgICB9XG4gIH07XG5cbiAgcHJvdG8ubGlzdGVuZXJzID0gZnVuY3Rpb24gKGV2ZW50TmFtZTogc3RyaW5nKSB7XG4gICAgbGV0IG5vdGlmaWVyID0gbm90aWZpZXJGb3JFdmVudCh0aGlzLCBldmVudE5hbWUpO1xuICAgIHJldHVybiBub3RpZmllciA/IG5vdGlmaWVyLmxpc3RlbmVycyA6IFtdO1xuICB9O1xufVxuXG4vKipcbiAqIFNldHRsZSBhbnkgcHJvbWlzZXMgcmV0dXJuZWQgYnkgZXZlbnQgbGlzdGVuZXJzIGluIHNlcmllcy5cbiAqXG4gKiBSZXR1cm5zIGFuIGFycmF5IG9mIHJlc3VsdHMgKG9yIGB1bmRlZmluZWRgKSByZXR1cm5lZCBieSBsaXN0ZW5lcnMuXG4gKlxuICogSWYgYW55IGVycm9ycyBhcmUgZW5jb3VudGVyZWQgZHVyaW5nIHByb2Nlc3NpbmcsIHRoZXkgd2lsbCBiZSBjYXVnaHQgYW5kXG4gKiByZXR1cm5lZCB3aXRoIG90aGVyIHJlc3VsdHMuIEVycm9ycyB3aWxsIG5vdCBpbnRlcnJ1cHQgZnVydGhlciBwcm9jZXNzaW5nLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc2V0dGxlSW5TZXJpZXMoXG4gIG9iajogRXZlbnRlZCxcbiAgZXZlbnROYW1lOiBzdHJpbmcsXG4gIC4uLmFyZ3M6IHVua25vd25bXVxuKTogUHJvbWlzZTx1bmtub3duW10+IHtcbiAgY29uc3QgbGlzdGVuZXJzID0gb2JqLmxpc3RlbmVycyhldmVudE5hbWUpO1xuICBjb25zdCByZXN1bHRzOiB1bmtub3duW10gPSBbXTtcblxuICBmb3IgKGxldCBsaXN0ZW5lciBvZiBsaXN0ZW5lcnMpIHtcbiAgICB0cnkge1xuICAgICAgcmVzdWx0cy5wdXNoKGF3YWl0IGxpc3RlbmVyKC4uLmFyZ3MpKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXN1bHRzLnB1c2goZSk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHRzO1xufVxuXG4vKipcbiAqIEZ1bGZpbGxzIGFueSBwcm9taXNlcyByZXR1cm5lZCBieSBldmVudCBsaXN0ZW5lcnMgaW4gc2VyaWVzLlxuICpcbiAqIFJldHVybnMgYW4gYXJyYXkgb2YgcmVzdWx0cyAob3IgYHVuZGVmaW5lZGApIHJldHVybmVkIGJ5IGxpc3RlbmVycy5cbiAqXG4gKiBPbiBlcnJvciwgcHJvY2Vzc2luZyB3aWxsIHN0b3AgYW5kIHRoZSByZXR1cm5lZCBwcm9taXNlIHdpbGwgYmUgcmVqZWN0ZWQgd2l0aFxuICogdGhlIGVycm9yIHRoYXQgd2FzIGVuY291bnRlcmVkLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZnVsZmlsbEluU2VyaWVzKFxuICBvYmo6IEV2ZW50ZWQsXG4gIGV2ZW50TmFtZTogc3RyaW5nLFxuICAuLi5hcmdzOiB1bmtub3duW11cbik6IFByb21pc2U8dW5rbm93bltdPiB7XG4gIGNvbnN0IGxpc3RlbmVycyA9IG9iai5saXN0ZW5lcnMoZXZlbnROYW1lKTtcbiAgY29uc3QgcmVzdWx0czogdW5rbm93bltdID0gW107XG5cbiAgZm9yIChsZXQgbGlzdGVuZXIgb2YgbGlzdGVuZXJzKSB7XG4gICAgcmVzdWx0cy5wdXNoKGF3YWl0IGxpc3RlbmVyKC4uLmFyZ3MpKTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHRzO1xufVxuXG4vKipcbiAqIEZ1bGZpbGxzIGFueSBwcm9taXNlcyByZXR1cm5lZCBieSBldmVudCBsaXN0ZW5lcnMgaW4gcGFyYWxsZWwsIHVzaW5nXG4gKiBgUHJvbWlzZS5hbGxgLlxuICpcbiAqIFJldHVybnMgYW4gYXJyYXkgb2YgcmVzdWx0cyAob3IgYHVuZGVmaW5lZGApIHJldHVybmVkIGJ5IGxpc3RlbmVycy5cbiAqXG4gKiBPbiBlcnJvciwgcHJvY2Vzc2luZyB3aWxsIHN0b3AgYW5kIHRoZSByZXR1cm5lZCBwcm9taXNlIHdpbGwgYmUgcmVqZWN0ZWQgd2l0aFxuICogdGhlIGVycm9yIHRoYXQgd2FzIGVuY291bnRlcmVkLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZnVsZmlsbEFsbChcbiAgb2JqOiBFdmVudGVkLFxuICBldmVudE5hbWU6IHN0cmluZyxcbiAgLi4uYXJnczogdW5rbm93bltdXG4pOiBQcm9taXNlPHVua25vd25bXT4ge1xuICBjb25zdCBsaXN0ZW5lcnMgPSBvYmoubGlzdGVuZXJzKGV2ZW50TmFtZSk7XG4gIGNvbnN0IHByb21pc2VzOiBQcm9taXNlPHVua25vd24+W10gPSBbXTtcblxuICBmb3IgKGxldCBsaXN0ZW5lciBvZiBsaXN0ZW5lcnMpIHtcbiAgICBwcm9taXNlcy5wdXNoKGxpc3RlbmVyKC4uLmFyZ3MpKTtcbiAgfVxuXG4gIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcyk7XG59XG5cbmZ1bmN0aW9uIG5vdGlmaWVyRm9yRXZlbnQoXG4gIG9iamVjdDogYW55LFxuICBldmVudE5hbWU6IHN0cmluZyxcbiAgY3JlYXRlSWZVbmRlZmluZWQgPSBmYWxzZVxuKSB7XG4gIGlmIChvYmplY3QuX2V2ZW50ZWROb3RpZmllcnMgPT09IHVuZGVmaW5lZCkge1xuICAgIG9iamVjdC5fZXZlbnRlZE5vdGlmaWVycyA9IHt9O1xuICB9XG4gIGxldCBub3RpZmllciA9IG9iamVjdC5fZXZlbnRlZE5vdGlmaWVyc1tldmVudE5hbWVdO1xuICBpZiAoIW5vdGlmaWVyICYmIGNyZWF0ZUlmVW5kZWZpbmVkKSB7XG4gICAgbm90aWZpZXIgPSBvYmplY3QuX2V2ZW50ZWROb3RpZmllcnNbZXZlbnROYW1lXSA9IG5ldyBOb3RpZmllcigpO1xuICB9XG4gIHJldHVybiBub3RpZmllcjtcbn1cblxuZnVuY3Rpb24gcmVtb3ZlTm90aWZpZXJGb3JFdmVudChvYmplY3Q6IGFueSwgZXZlbnROYW1lOiBzdHJpbmcpIHtcbiAgaWYgKG9iamVjdC5fZXZlbnRlZE5vdGlmaWVycyAmJiBvYmplY3QuX2V2ZW50ZWROb3RpZmllcnNbZXZlbnROYW1lXSkge1xuICAgIGRlbGV0ZSBvYmplY3QuX2V2ZW50ZWROb3RpZmllcnNbZXZlbnROYW1lXTtcbiAgfVxufVxuIl19