UNPKG

@jokio/ts-events

Version:

Various EventEmitter event replacements with synchronous, a-synchronous, and queued events. Made in TypeScript so usable with JavaScript and TypeScript.

342 lines 39.9 kB
// Copyright © 2015 Rogier Schouten<github@workingcode.ninja> // License: ISC 'use strict'; var __extends = (this && this.__extends) || (function () { var extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t; return { next: verb(0), "throw": verb(1), "return": verb(2) }; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [0, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; Object.defineProperty(exports, "__esModule", { value: true }); var objects_1 = require("./objects"); var sync_event_1 = require("./sync-event"); var async_event_1 = require("./async-event"); var queued_event_1 = require("./queued-event"); var EventType; (function (EventType) { EventType[EventType["Sync"] = 0] = "Sync"; EventType[EventType["Async"] = 1] = "Async"; EventType[EventType["Queued"] = 2] = "Queued"; })(EventType = exports.EventType || (exports.EventType = {})); /** * An event that behaves like a Sync/Async/Queued event depending on how * you subscribe. */ var AnyEvent = (function () { function AnyEvent(opts) { /** * Underlying event implementations; one for every attach type + opts combination */ this._events = []; if (opts && opts.monitorAttach) { this.evtFirstAttached = new VoidAnyEvent(); this.evtLastDetached = new VoidAnyEvent(); } } AnyEvent.prototype.attach = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var mode = EventType.Sync; if (args.length > 0 && typeof args[0] === 'number') { mode = args.shift(); } var boundTo = this; // add ourselves as default 'boundTo' argument var handler; var opts; var postable; if (typeof args[0] === 'function' || (args[0] && typeof args[0] === 'object' && typeof args[0].post === 'function')) { if (typeof args[0] === 'function') { handler = args[0]; } else { postable = args[0]; } opts = args[1]; } else { boundTo = args[0]; handler = args[1]; opts = args[2]; } this._attach(mode, boundTo, handler, postable, opts, false); }; AnyEvent.prototype.once = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var mode = EventType.Sync; if (args.length > 0 && typeof args[0] === 'number') { mode = args.shift(); } var boundTo = this; // add ourselves as default 'boundTo' argument var handler; var opts; var postable; if (typeof args[0] === 'function' || (args[0] && typeof args[0] === 'object' && typeof args[0].post === 'function')) { if (typeof args[0] === 'function') { handler = args[0]; } else { postable = args[0]; } opts = args[1]; } else { boundTo = args[0]; handler = args[1]; opts = args[2]; } this._attach(mode, boundTo, handler, postable, opts, true); }; AnyEvent.prototype._attach = function (mode, boundTo, handler, postable, opts, once) { var prevCount = (!!this.evtFirstAttached ? this.listenerCount() : 0); var event; switch (mode) { case EventType.Sync: { for (var _i = 0, _a = this._events; _i < _a.length; _i++) { var evt = _a[_i]; if (evt instanceof sync_event_1.SyncEvent) { event = evt; } } if (!event) { event = new sync_event_1.SyncEvent(); this._events.push(event); } } break; case EventType.Async: { for (var _b = 0, _c = this._events; _b < _c.length; _b++) { var evt = _c[_b]; if (evt instanceof async_event_1.AsyncEvent && objects_1.shallowEquals(evt.options, opts)) { event = evt; } } if (!event) { event = new async_event_1.AsyncEvent(opts); this._events.push(event); } } break; case EventType.Queued: { for (var _d = 0, _e = this._events; _d < _e.length; _d++) { var evt = _e[_d]; if (evt instanceof queued_event_1.QueuedEvent && objects_1.shallowEquals(evt.options, opts)) { event = evt; } } if (!event) { event = new queued_event_1.QueuedEvent(opts); this._events.push(event); } } break; default: throw new Error('unknown EventType'); } if (once) { if (postable) { event.once(postable); } else { event.once(boundTo, handler); } } else { if (postable) { event.attach(postable); } else { event.attach(boundTo, handler); } } if (this.evtFirstAttached && prevCount === 0) { this.evtFirstAttached.post(); } }; AnyEvent.prototype.attachSync = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } args.unshift(EventType.Sync); this.attach.apply(this, args); }; AnyEvent.prototype.onceSync = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } args.unshift(EventType.Sync); this.once.apply(this, args); }; AnyEvent.prototype.attachAsync = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } args.unshift(EventType.Async); this.attach.apply(this, args); }; AnyEvent.prototype.onceAsync = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } args.unshift(EventType.Async); this.once.apply(this, args); }; AnyEvent.prototype.attachQueued = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } args.unshift(EventType.Queued); this.attach.apply(this, args); }; AnyEvent.prototype.onceQueued = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } args.unshift(EventType.Queued); this.once.apply(this, args); }; /** * Detach event handlers regardless of type */ AnyEvent.prototype.detach = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var prevCount = (!!this.evtLastDetached ? this.listenerCount() : 0); for (var i = 0; i < this._events.length; ++i) { this._events[i].detach.apply(this._events[i], args); } if (!!this.evtLastDetached && prevCount > 0 && this.listenerCount() === 0) { this.evtLastDetached.post(); } }; /** * Post an event to all current listeners */ AnyEvent.prototype.post = function (data) { return __awaiter(this, void 0, void 0, function () { var events, i, i; return __generator(this, function (_a) { switch (_a.label) { case 0: events = []; for (i = 0; i < this._events.length; ++i) { events.push(this._events[i]); } i = 0; _a.label = 1; case 1: if (!(i < events.length)) return [3 /*break*/, 4]; return [4 /*yield*/, events[i].post(data)]; case 2: _a.sent(); _a.label = 3; case 3: ++i; return [3 /*break*/, 1]; case 4: return [2 /*return*/]; } }); }); }; /** * The number of attached listeners */ AnyEvent.prototype.listenerCount = function () { var result = 0; for (var i = 0; i < this._events.length; ++i) { result += this._events[i].listenerCount(); } return result; }; return AnyEvent; }()); exports.AnyEvent = AnyEvent; /** * Convenience class for AnyEvents without data */ var VoidAnyEvent = (function (_super) { __extends(VoidAnyEvent, _super); function VoidAnyEvent() { return _super !== null && _super.apply(this, arguments) || this; } /** * Send the AsyncEvent. */ VoidAnyEvent.prototype.post = function () { return _super.prototype.post.call(this, undefined); }; return VoidAnyEvent; }(AnyEvent)); exports.VoidAnyEvent = VoidAnyEvent; /** * Similar to 'error' event on EventEmitter: throws when a post() occurs while no handlers set. */ var ErrorAnyEvent = (function (_super) { __extends(ErrorAnyEvent, _super); function ErrorAnyEvent() { return _super !== null && _super.apply(this, arguments) || this; } ErrorAnyEvent.prototype.post = function (data) { if (this.listenerCount() === 0) { throw new Error("error event posted while no listeners attached. Error: " + data.message); } return _super.prototype.post.call(this, data); }; return ErrorAnyEvent; }(AnyEvent)); exports.ErrorAnyEvent = ErrorAnyEvent; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW55LWV2ZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2xpYi9hbnktZXZlbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsNkRBQTZEO0FBQzdELGVBQWU7QUFFZixZQUFZLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBRWIscUNBQTBDO0FBRzFDLDJDQUF5QztBQUN6Qyw2Q0FBMkQ7QUFDM0QsK0NBQThEO0FBRTlELElBQVksU0FJWDtBQUpELFdBQVksU0FBUztJQUNqQix5Q0FBSSxDQUFBO0lBQ0osMkNBQUssQ0FBQTtJQUNMLDZDQUFNLENBQUE7QUFDVixDQUFDLEVBSlcsU0FBUyxHQUFULGlCQUFTLEtBQVQsaUJBQVMsUUFJcEI7QUFTRDs7O0dBR0c7QUFDSDtJQWtCSSxrQkFBWSxJQUFtQjtRQUwvQjs7V0FFRztRQUNLLFlBQU8sR0FBbUIsRUFBRSxDQUFDO1FBR2pDLEVBQUUsQ0FBQyxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQztZQUM3QixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztZQUMzQyxJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUFDOUMsQ0FBQztJQUNMLENBQUM7SUFhTSx5QkFBTSxHQUFiO1FBQWMsY0FBYzthQUFkLFVBQWMsRUFBZCxxQkFBYyxFQUFkLElBQWM7WUFBZCx5QkFBYzs7UUFDeEIsSUFBSSxJQUFJLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQztRQUMxQixFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSSxPQUFPLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDO1lBQ2pELElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFlLENBQUM7UUFDckMsQ0FBQztRQUNELElBQUksT0FB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QUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDO1lBQzNDLE1BQU0sSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQzlDLENBQUM7UUFDRCxNQUFNLENBQUMsTUFBTSxDQUFDO0lBQ2xCLENBQUM7SUFDTCxlQUFDO0FBQUQsQ0FBQyxBQTNQRCxJQTJQQztBQTNQWSw0QkFBUTtBQTZQckI7O0dBRUc7QUFDSDtJQUFrQyxnQ0FBYztJQUFoRDs7SUFRQSxDQUFDO0lBTkc7O09BRUc7SUFDSSwyQkFBSSxHQUFYO1FBQ0ksTUFBTSxDQUFDLGlCQUFNLElBQUksWUFBQyxTQUFTLENBQUMsQ0FBQztJQUNqQyxDQUFDO0lBQ0wsbUJBQUM7QUFBRCxDQUFDLEFBUkQsQ0FBa0MsUUFBUSxHQVF6QztBQVJZLG9DQUFZO0FBVXpCOztHQUVHO0FBQ0g7SUFBbUMsaUNBQWU7SUFBbEQ7O0lBUUEsQ0FBQztJQU5VLDRCQUFJLEdBQVgsVUFBWSxJQUFXO1FBQ25CLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzdCLE1BQU0sSUFBSSxLQUFLLENBQUMsNERBQTBELElBQUksQ0FBQyxPQUFTLENBQUMsQ0FBQztRQUM5RixDQUFDO1FBQ0QsTUFBTSxDQUFDLGlCQUFNLElBQUksWUFBQyxJQUFJLENBQUMsQ0FBQztJQUM1QixDQUFDO0lBQ0wsb0JBQUM7QUFBRCxDQUFDLEFBUkQsQ0FBbUMsUUFBUSxHQVExQztBQVJZLHNDQUFhIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IMKpIDIwMTUgUm9naWVyIFNjaG91dGVuPGdpdGh1YkB3b3JraW5nY29kZS5uaW5qYT5cbi8vIExpY2Vuc2U6IElTQ1xuXG4ndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7IHNoYWxsb3dFcXVhbHMgfSBmcm9tICcuL29iamVjdHMnO1xuXG5pbXBvcnQgeyBCYXNlRXZlbnQsIFBvc3RhYmxlLCBMaXN0ZW5lciB9IGZyb20gJy4vYmFzZS1ldmVudCc7XG5pbXBvcnQgeyBTeW5jRXZlbnQgfSBmcm9tICcuL3N5bmMtZXZlbnQnO1xuaW1wb3J0IHsgQXN5bmNFdmVudCwgQXN5bmNFdmVudE9wdHMgfSBmcm9tICcuL2FzeW5jLWV2ZW50JztcbmltcG9ydCB7IFF1ZXVlZEV2ZW50LCBRdWV1ZWRFdmVudE9wdHMgfSBmcm9tICcuL3F1ZXVlZC1ldmVudCc7XG5cbmV4cG9ydCBlbnVtIEV2ZW50VHlwZSB7XG4gICAgU3luYyxcbiAgICBBc3luYyxcbiAgICBRdWV1ZWRcbn1cblxuZXhwb3J0IGludGVyZmFjZSBBbnlFdmVudE9wdHMge1xuICAgIC8qKlxuICAgICAqIENyZWF0ZSBldnRGaXJzdEF0dGFjaGVkIGFuZCBldnRMYXN0RGV0YWNoZWQgc28geW91IGNhbiBtb25pdG9yIHdoZW4gc29tZW9uZSBpcyBzdWJzY3JpYmVkXG4gICAgICovXG4gICAgbW9uaXRvckF0dGFjaD86IGJvb2xlYW47XG59XG5cbi8qKlxuICogQW4gZXZlbnQgdGhhdCBiZWhhdmVzIGxpa2UgYSBTeW5jL0FzeW5jL1F1ZXVlZCBldmVudCBkZXBlbmRpbmcgb24gaG93XG4gKiB5b3Ugc3Vic2NyaWJlLlxuICovXG5leHBvcnQgY2xhc3MgQW55RXZlbnQ8VD4gaW1wbGVtZW50cyBQb3N0YWJsZTxUPiB7XG5cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyZWQgd2hlbmV2ZXIgc29tZW9uZSBhdHRhY2hlcyBhbmQgbm9ib2R5IHdhcyBhdHRhY2hlZC5cbiAgICAgKiBOb3RlOiB5b3UgbXVzdCBjYWxsIHRoZSBjb25zdHJ1Y3RvciB3aXRoIG1vbml0b3JBdHRhY2ggc2V0IHRvIHRydWUgdG8gY3JlYXRlIHRoaXMgZXZlbnQhXG4gICAgICovXG4gICAgcHVibGljIGV2dEZpcnN0QXR0YWNoZWQ6IFZvaWRBbnlFdmVudDtcbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyZWQgd2hlbmV2ZXIgc29tZW9uZSBkZXRhY2hlcyBhbmQgbm9ib2R5IGlzIGF0dGFjaGVkIGFueW1vcmVcbiAgICAgKiBOb3RlOiB5b3UgbXVzdCBjYWxsIHRoZSBjb25zdHJ1Y3RvciB3aXRoIG1vbml0b3JBdHRhY2ggc2V0IHRvIHRydWUgdG8gY3JlYXRlIHRoaXMgZXZlbnQhXG4gICAgICovXG4gICAgcHVibGljIGV2dExhc3REZXRhY2hlZDogVm9pZEFueUV2ZW50O1xuXG4gICAgLyoqXG4gICAgICogVW5kZXJseWluZyBldmVudCBpbXBsZW1lbnRhdGlvbnM7IG9uZSBmb3IgZXZlcnkgYXR0YWNoIHR5cGUgKyBvcHRzIGNvbWJpbmF0aW9uXG4gICAgICovXG4gICAgcHJpdmF0ZSBfZXZlbnRzOiBCYXNlRXZlbnQ8VD5bXSA9IFtdO1xuXG4gICAgY29uc3RydWN0b3Iob3B0cz86IEFueUV2ZW50T3B0cykge1xuICAgICAgICBpZiAob3B0cyAmJiBvcHRzLm1vbml0b3JBdHRhY2gpIHtcbiAgICAgICAgICAgIHRoaXMuZXZ0Rmlyc3RBdHRhY2hlZCA9IG5ldyBWb2lkQW55RXZlbnQoKTtcbiAgICAgICAgICAgIHRoaXMuZXZ0TGFzdERldGFjaGVkID0gbmV3IFZvaWRBbnlFdmVudCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTGVnYWN5IG1ldGhvZFxuICAgICAqIHNhbWUgYXMgYXR0YWNoU3luYy9hdHRhY2hBc3luYy9hdHRhY2hRdWV1ZWQ7IGJhc2VkIG9uIHRoZSBnaXZlbiBlbnVtXG4gICAgICogQHBhcmFtIG1vZGUgZGV0ZXJtaW5lcyB3aGV0aGVyIHRvIGF0dGFjaCBzeW5jL2FzeW5jL3F1ZXVlZFxuICAgICAqL1xuICAgIHB1YmxpYyBhdHRhY2goaGFuZGxlcjogKGRhdGE6IFQpID0+IFByb21pc2U8dm9pZD4sIG9wdHM/OiBBc3luY0V2ZW50T3B0cyB8IFF1ZXVlZEV2ZW50T3B0cyk6IHZvaWQ7XG4gICAgcHVibGljIGF0dGFjaChib3VuZFRvOiBPYmplY3QsIGhhbmRsZXI6IChkYXRhOiBUKSA9PiBQcm9taXNlPHZvaWQ+LCBvcHRzPzogQXN5bmNFdmVudE9wdHMgfCBRdWV1ZWRFdmVudE9wdHMpOiB2b2lkO1xuICAgIHB1YmxpYyBhdHRhY2goZXZlbnQ6IFBvc3RhYmxlPFQ+LCBvcHRzPzogQXN5bmNFdmVudE9wdHMgfCBRdWV1ZWRFdmVudE9wdHMpOiB2b2lkO1xuICAgIHB1YmxpYyBhdHRhY2gobW9kZTogRXZlbnRUeXBlLCBoYW5kbGVyOiAoZGF0YTogVCkgPT4gUHJvbWlzZTx2b2lkPiwgb3B0cz86IEFzeW5jRXZlbnRPcHRzIHwgUXVldWVkRXZlbnRPcHRzKTogdm9pZDtcbiAgICBwdWJsaWMgYXR0YWNoKG1vZGU6IEV2ZW50VHlwZSwgYm91bmRUbzogT2JqZWN0LCBoYW5kbGVyOiAoZGF0YTogVCkgPT4gUHJvbWlzZTx2b2lkPiwgb3B0cz86IEFzeW5jRXZlbnRPcHRzIHwgUXVldWVkRXZlbnRPcHRzKTogdm9pZDtcbiAgICBwdWJsaWMgYXR0YWNoKG1vZGU6IEV2ZW50VHlwZSwgZXZlbnQ6IFBvc3RhYmxlPFQ+LCBvcHRzPzogQXN5bmNFdmVudE9wdHMgfCBRdWV1ZWRFdmVudE9wdHMpOiB2b2lkO1xuICAgIHB1YmxpYyBhdHRhY2goLi4uYXJnczogYW55W10pOiB2b2lkIHtcbiAgICAgICAgbGV0IG1vZGUgPSBFdmVudFR5cGUuU3luYztcbiAgICAgICAgaWYgKGFyZ3MubGVuZ3RoID4gMCAmJiB0eXBlb2YgYXJnc1swXSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgIG1vZGUgPSBhcmdzLnNoaWZ0KCkgYXMgRXZlbnRUeXBlO1xuICAgICAgICB9XG4gICAgICAgIGxldCBib3VuZFRvOiBPYmplY3QgPSB0aGlzOyAvLyBhZGQgb3Vyc2VsdmVzIGFzIGRlZmF1bHQgJ2JvdW5kVG8nIGFyZ3VtZW50XG4gICAgICAgIGxldCBoYW5kbGVyOiAoZGF0YTogVCkgPT4gUHJvbWlzZTx2b2lkPjtcbiAgICAgICAgbGV0IG9wdHM6IEFzeW5jRXZlbnRPcHRzIHwgUXVldWVkRXZlbnRPcHRzO1xuICAgICAgICBsZXQgcG9zdGFibGU6IFBvc3RhYmxlPFQ+O1xuICAgICAgICBpZiAodHlwZW9mIGFyZ3NbMF0gPT09ICdmdW5jdGlvbicgfHwgKGFyZ3NbMF0gJiYgdHlwZW9mIGFyZ3NbMF0gPT09ICdvYmplY3QnICYmIHR5cGVvZiBhcmdzWzBdLnBvc3QgPT09ICdmdW5jdGlvbicpKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGFyZ3NbMF0gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICBoYW5kbGVyID0gYXJnc1swXTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcG9zdGFibGUgPSBhcmdzWzBdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgb3B0cyA9IGFyZ3NbMV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBib3VuZFRvID0gYXJnc1swXTtcbiAgICAgICAgICAgIGhhbmRsZXIgPSBhcmdzWzFdO1xuICAgICAgICAgICAgb3B0cyA9IGFyZ3NbMl07XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fYXR0YWNoKG1vZGUsIGJvdW5kVG8sIGhhbmRsZXIsIHBvc3RhYmxlLCBvcHRzLCBmYWxzZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTGVnYWN5IG1ldGhvZFxuICAgICAqIHNhbWUgYXMgb25jZVN5bmMvb25jZUFzeW5jL29uY2VRdWV1ZWQ7IGJhc2VkIG9uIHRoZSBnaXZlbiBlbnVtXG4gICAgICogQHBhcmFtIG1vZGUgZGV0ZXJtaW5lcyB3aGV0aGVyIHRvIG9uY2Ugc3luYy9hc3luYy9xdWV1ZWRcbiAgICAgKi9cbiAgICBwdWJsaWMgb25jZShoYW5kbGVyOiAoZGF0YTogVCkgPT4gUHJvbWlzZTx2b2lkPiwgb3B0cz86IEFzeW5jRXZlbnRPcHRzIHwgUXVldWVkRXZlbnRPcHRzKTogdm9pZDtcbiAgICBwdWJsaWMgb25jZShib3VuZFRvOiBPYmplY3QsIGhhbmRsZXI6IChkYXRhOiBUKSA9PiBQcm9taXNlPHZvaWQ+LCBvcHRzPzogQXN5bmNFdmVudE9wdHMgfCBRdWV1ZWRFdmVudE9wdHMpOiB2b2lkO1xuICAgIHB1YmxpYyBvbmNlKGV2ZW50OiBQb3N0YWJsZTxUPiwgb3B0cz86IEFzeW5jRXZlbnRPcHRzIHwgUXVldWVkRXZlbnRPcHRzKTogdm9pZDtcbiAgICBwdWJsaWMgb25jZShtb2RlOiBFdmVudFR5cGUsIGhhbmRsZXI6IChkYXRhOiBUKSA9PiBQcm9taXNlPHZvaWQ+LCBvcHRzPzogQXN5bmNFdmVudE9wdHMgfCBRdWV1ZWRFdmVudE9wdHMpOiB2b2lkO1xuICAgIHB1YmxpYyBvbmNlKG1vZGU6IEV2ZW50VHlwZSwgYm91bmRUbzogT2JqZWN0LCBoYW5kbGVyOiAoZGF0YTogVCkgPT4gUHJvbWlzZTx2b2lkPiwgb3B0cz86IEFzeW5jRXZlbnRPcHRzIHwgUXVldWVkRXZlbnRPcHRzKTogdm9pZDtcbiAgICBwdWJsaWMgb25jZShtb2RlOiBFdmVudFR5cGUsIGV2ZW50OiBQb3N0YWJsZTxUPiwgb3B0cz86IEFzeW5jRXZlbnRPcHRzIHwgUXVldWVkRXZlbnRPcHRzKTogdm9pZDtcbiAgICBwdWJsaWMgb25jZSguLi5hcmdzOiBhbnlbXSk6IHZvaWQge1xuICAgICAgICBsZXQgbW9kZSA9IEV2ZW50VHlwZS5TeW5jO1xuICAgICAgICBpZiAoYXJncy5sZW5ndGggPiAwICYmIHR5cGVvZiBhcmdzWzBdID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgbW9kZSA9IGFyZ3Muc2hpZnQoKSBhcyBFdmVudFR5cGU7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGJvdW5kVG86IE9iamVjdCA9IHRoaXM7IC8vIGFkZCBvdXJzZWx2ZXMgYXMgZGVmYXVsdCAnYm91bmRUbycgYXJndW1lbnRcbiAgICAgICAgbGV0IGhhbmRsZXI6IChkYXRhOiBUKSA9PiBQcm9taXNlPHZvaWQ+O1xuICAgICAgICBsZXQgb3B0czogQXN5bmNFdmVudE9wdHMgfCBRdWV1ZWRFdmVudE9wdHM7XG4gICAgICAgIGxldCBwb3N0YWJsZTogUG9zdGFibGU8VD47XG4gICAgICAgIGlmICh0eXBlb2YgYXJnc1swXSA9PT0gJ2Z1bmN0aW9uJyB8fCAoYXJnc1swXSAmJiB0eXBlb2YgYXJnc1swXSA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIGFyZ3NbMF0ucG9zdCA9PT0gJ2Z1bmN0aW9uJykpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgYXJnc1swXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgIGhhbmRsZXIgPSBhcmdzWzBdO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBwb3N0YWJsZSA9IGFyZ3NbMF07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBvcHRzID0gYXJnc1sxXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGJvdW5kVG8gPSBhcmdzWzBdO1xuICAgICAgICAgICAgaGFuZGxlciA9IGFyZ3NbMV07XG4gICAgICAgICAgICBvcHRzID0gYXJnc1syXTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9hdHRhY2gobW9kZSwgYm91bmRUbywgaGFuZGxlciwgcG9zdGFibGUsIG9wdHMsIHRydWUpO1xuICAgIH1cblxuICAgIHByaXZhdGUgX2F0dGFjaChcbiAgICAgICAgbW9kZTogRXZlbnRUeXBlLFxuICAgICAgICBib3VuZFRvOiBPYmplY3QgfCB1bmRlZmluZWQsXG4gICAgICAgIGhhbmRsZXI6IChkYXRhOiBUKSA9PiBQcm9taXNlPHZvaWQ+IHwgdW5kZWZpbmVkLFxuICAgICAgICBwb3N0YWJsZTogUG9zdGFibGU8VD4gfCB1bmRlZmluZWQsXG4gICAgICAgIG9wdHM6IEFzeW5jRXZlbnRPcHRzIHwgUXVldWVkRXZlbnRPcHRzIHwgdW5kZWZpbmVkLFxuICAgICAgICBvbmNlOiBib29sZWFuXG4gICAgKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHByZXZDb3VudCA9ICghIXRoaXMuZXZ0Rmlyc3RBdHRhY2hlZCA/IHRoaXMubGlzdGVuZXJDb3VudCgpIDogMCk7XG4gICAgICAgIGxldCBldmVudDogQmFzZUV2ZW50PFQ+O1xuICAgICAgICBzd2l0Y2ggKG1vZGUpIHtcbiAgICAgICAgICAgIGNhc2UgRXZlbnRUeXBlLlN5bmM6IHtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGV2dCBvZiB0aGlzLl9ldmVudHMpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGV2dCBpbnN0YW5jZW9mIFN5bmNFdmVudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQgPSBldnQ7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCFldmVudCkge1xuICAgICAgICAgICAgICAgICAgICBldmVudCA9IG5ldyBTeW5jRXZlbnQ8VD4oKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZXZlbnRzLnB1c2goZXZlbnQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEV2ZW50VHlwZS5Bc3luYzoge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgZXZ0IG9mIHRoaXMuX2V2ZW50cykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXZ0IGluc3RhbmNlb2YgQXN5bmNFdmVudCAmJiBzaGFsbG93RXF1YWxzKCg8QXN5bmNFdmVudDxUPj5ldnQpLm9wdGlvbnMsIG9wdHMpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudCA9IGV2dDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIWV2ZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50ID0gbmV3IEFzeW5jRXZlbnQ8VD4ob3B0cyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50cy5wdXNoKGV2ZW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBFdmVudFR5cGUuUXVldWVkOiB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBldnQgb2YgdGhpcy5fZXZlbnRzKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChldnQgaW5zdGFuY2VvZiBRdWV1ZWRFdmVudCAmJiBzaGFsbG93RXF1YWxzKCg8UXVldWVkRXZlbnQ8VD4+ZXZ0KS5vcHRpb25zLCBvcHRzKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQgPSBldnQ7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCFldmVudCkge1xuICAgICAgICAgICAgICAgICAgICBldmVudCA9IG5ldyBRdWV1ZWRFdmVudDxUPihvcHRzKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZXZlbnRzLnB1c2goZXZlbnQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigndW5rbm93biBFdmVudFR5cGUnKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAob25jZSkge1xuICAgICAgICAgICAgaWYgKHBvc3RhYmxlKSB7XG4gICAgICAgICAgICAgICAgZXZlbnQub25jZShwb3N0YWJsZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGV2ZW50Lm9uY2UoYm91bmRUbywgaGFuZGxlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAocG9zdGFibGUpIHtcbiAgICAgICAgICAgICAgICBldmVudC5hdHRhY2gocG9zdGFibGUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBldmVudC5hdHRhY2goYm91bmRUbywgaGFuZGxlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuZXZ0Rmlyc3RBdHRhY2hlZCAmJiBwcmV2Q291bnQgPT09IDApIHtcbiAgICAgICAgICAgIHRoaXMuZXZ0Rmlyc3RBdHRhY2hlZC5wb3N0KCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgYXR0YWNoU3luYyhoYW5kbGVyOiAoZGF0YTogVCkgPT4gUHJvbWlzZTx2b2lkPik6IHZvaWQ7XG4gICAgcHVibGljIGF0dGFjaFN5bmMoYm91bmRUbzogT2JqZWN0LCBoYW5kbGVyOiAoZGF0YTogVCkgPT4gUHJvbWlzZTx2b2lkPik6IHZvaWQ7XG4gICAgcHVibGljIGF0dGFjaFN5bmMoZXZlbnQ6IFBvc3RhYmxlPFQ+KTogdm9pZDtcbiAgICBwdWJsaWMgYXR0YWNoU3luYyguLi5hcmdzOiBhbnlbXSk6IHZvaWQge1xuICAgICAgICBhcmdzLnVuc2hpZnQoRXZlbnRUeXBlLlN5bmMpO1xuICAgICAgICB0aGlzLmF0dGFjaC5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25jZVN5bmMoaGFuZGxlcjogKGRhdGE6IFQpID0+IFByb21pc2U8dm9pZD4pOiB2b2lkO1xuICAgIHB1YmxpYyBvbmNlU3luYyhib3VuZFRvOiBPYmplY3QsIGhhbmRsZXI6IChkYXRhOiBUKSA9PiBQcm9taXNlPHZvaWQ+KTogdm9pZDtcbiAgICBwdWJsaWMgb25jZVN5bmMoZXZlbnQ6IFBvc3RhYmxlPFQ+KTogdm9pZDtcbiAgICBwdWJsaWMgb25jZVN5bmMoLi4uYXJnczogYW55W10pOiB2b2lkIHtcbiAgICAgICAgYXJncy51bnNoaWZ0KEV2ZW50VHlwZS5TeW5jKTtcbiAgICAgICAgdGhpcy5vbmNlLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhdHRhY2hBc3luYyhoYW5kbGVyOiAoZGF0YTogVCkgPT4gUHJvbWlzZTx2b2lkPiwgb3B0cz86IEFzeW5jRXZlbnRPcHRzKTogdm9pZDtcbiAgICBwdWJsaWMgYXR0YWNoQXN5bmMoYm91bmRUbzogT2JqZWN0LCBoYW5kbGVyOiAoZGF0YTogVCkgPT4gUHJvbWlzZTx2b2lkPiwgb3B0cz86IEFzeW5jRXZlbnRPcHRzKTogdm9pZDtcbiAgICBwdWJsaWMgYXR0YWNoQXN5bmMoZXZlbnQ6IFBvc3RhYmxlPFQ+LCBvcHRzPzogQXN5bmNFdmVudE9wdHMpOiB2b2lkO1xuICAgIHB1YmxpYyBhdHRhY2hBc3luYyguLi5hcmdzOiBhbnlbXSk6IHZvaWQge1xuICAgICAgICBhcmdzLnVuc2hpZnQoRXZlbnRUeXBlLkFzeW5jKTtcbiAgICAgICAgdGhpcy5hdHRhY2guYXBwbHkodGhpcywgYXJncyk7XG4gICAgfVxuXG4gICAgcHVibGljIG9uY2VBc3luYyhoYW5kbGVyOiAoZGF0YTogVCkgPT4gUHJvbWlzZTx2b2lkPiwgb3B0cz86IEFzeW5jRXZlbnRPcHRzKTogdm9pZDtcbiAgICBwdWJsaWMgb25jZUFzeW5jKGJvdW5kVG86IE9iamVjdCwgaGFuZGxlcjogKGRhdGE6IFQpID0+IFByb21pc2U8dm9pZD4sIG9wdHM/OiBBc3luY0V2ZW50T3B0cyk6IHZvaWQ7XG4gICAgcHVibGljIG9uY2VBc3luYyhldmVudDogUG9zdGFibGU8VD4sIG9wdHM/OiBBc3luY0V2ZW50T3B0cyk6IHZvaWQ7XG4gICAgcHVibGljIG9uY2VBc3luYyguLi5hcmdzOiBhbnlbXSk6IHZvaWQge1xuICAgICAgICBhcmdzLnVuc2hpZnQoRXZlbnRUeXBlLkFzeW5jKTtcbiAgICAgICAgdGhpcy5vbmNlLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhdHRhY2hRdWV1ZWQoaGFuZGxlcjogKGRhdGE6IFQpID0+IFByb21pc2U8dm9pZD4sIG9wdHM/OiBRdWV1ZWRFdmVudE9wdHMpOiB2b2lkO1xuICAgIHB1YmxpYyBhdHRhY2hRdWV1ZWQoYm91bmRUbzogT2JqZWN0LCBoYW5kbGVyOiAoZGF0YTogVCkgPT4gUHJvbWlzZTx2b2lkPiwgb3B0cz86IFF1ZXVlZEV2ZW50T3B0cyk6IHZvaWQ7XG4gICAgcHVibGljIGF0dGFjaFF1ZXVlZChldmVudDogUG9zdGFibGU8VD4sIG9wdHM/OiBRdWV1ZWRFdmVudE9wdHMpOiB2b2lkO1xuICAgIHB1YmxpYyBhdHRhY2hRdWV1ZWQoLi4uYXJnczogYW55W10pOiB2b2lkIHtcbiAgICAgICAgYXJncy51bnNoaWZ0KEV2ZW50VHlwZS5RdWV1ZWQpO1xuICAgICAgICB0aGlzLmF0dGFjaC5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25jZVF1ZXVlZChoYW5kbGVyOiAoZGF0YTogVCkgPT4gUHJvbWlzZTx2b2lkPiwgb3B0cz86IFF1ZXVlZEV2ZW50T3B0cyk6IHZvaWQ7XG4gICAgcHVibGljIG9uY2VRdWV1ZWQoYm91bmRUbzogT2JqZWN0LCBoYW5kbGVyOiAoZGF0YTogVCkgPT4gUHJvbWlzZTx2b2lkPiwgb3B0cz86IFF1ZXVlZEV2ZW50T3B0cyk6IHZvaWQ7XG4gICAgcHVibGljIG9uY2VRdWV1ZWQoZXZlbnQ6IFBvc3RhYmxlPFQ+LCBvcHRzPzogUXVldWVkRXZlbnRPcHRzKTogdm9pZDtcbiAgICBwdWJsaWMgb25jZVF1ZXVlZCguLi5hcmdzOiBhbnlbXSk6IHZvaWQge1xuICAgICAgICBhcmdzLnVuc2hpZnQoRXZlbnRUeXBlLlF1ZXVlZCk7XG4gICAgICAgIHRoaXMub25jZS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZGV0YWNoKGhhbmRsZXI6IChkYXRhOiBUKSA9PiBQcm9taXNlPHZvaWQ+KTogdm9pZDtcbiAgICBwdWJsaWMgZGV0YWNoKGJvdW5kVG86IE9iamVjdCwgaGFuZGxlcjogKGRhdGE6IFQpID0+IFByb21pc2U8dm9pZD4pOiB2b2lkO1xuICAgIHB1YmxpYyBkZXRhY2goYm91bmRUbzogT2JqZWN0KTogdm9pZDtcbiAgICBwdWJsaWMgZGV0YWNoKGV2ZW50OiBQb3N0YWJsZTxUPik6IHZvaWQ7XG4gICAgcHVibGljIGRldGFjaCgpOiB2b2lkO1xuICAgIC8qKlxuICAgICAqIERldGFjaCBldmVudCBoYW5kbGVycyByZWdhcmRsZXNzIG9mIHR5cGVcbiAgICAgKi9cbiAgICBwdWJsaWMgZGV0YWNoKC4uLmFyZ3M6IGFueVtdKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHByZXZDb3VudCA9ICghIXRoaXMuZXZ0TGFzdERldGFjaGVkID8gdGhpcy5saXN0ZW5lckNvdW50KCkgOiAwKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9ldmVudHMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIHRoaXMuX2V2ZW50c1tpXS5kZXRhY2guYXBwbHkodGhpcy5fZXZlbnRzW2ldLCBhcmdzKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoISF0aGlzLmV2dExhc3REZXRhY2hlZCAmJiBwcmV2Q291bnQgPiAwICYmIHRoaXMubGlzdGVuZXJDb3VudCgpID09PSAwKSB7XG4gICAgICAgICAgICB0aGlzLmV2dExhc3REZXRhY2hlZC5wb3N0KCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQb3N0IGFuIGV2ZW50IHRvIGFsbCBjdXJyZW50IGxpc3RlbmVyc1xuICAgICAqL1xuICAgIHB1YmxpYyBhc3luYyBwb3N0KGRhdGE6IFQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgLy8gbWFrZSBhIGNvcHkgb2YgdGhlIGFycmF5IGZpcnN0IHRvIGNvdmVyIHRoZSBjYXNlIHdoZXJlIGV2ZW50IGhhbmRsZXJzXG4gICAgICAgIC8vIGFyZSBhdHRhY2hlZCBkdXJpbmcgdGhlIHBvc3RcbiAgICAgICAgY29uc3QgZXZlbnRzOiBCYXNlRXZlbnQ8VD5bXSA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2V2ZW50cy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgZXZlbnRzLnB1c2godGhpcy5fZXZlbnRzW2ldKTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGV2ZW50cy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgYXdhaXQgZXZlbnRzW2ldLnBvc3QoZGF0YSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIGF0dGFjaGVkIGxpc3RlbmVyc1xuICAgICAqL1xuICAgIHB1YmxpYyBsaXN0ZW5lckNvdW50KCk6IG51bWJlciB7XG4gICAgICAgIGxldCByZXN1bHQgPSAwO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2V2ZW50cy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgcmVzdWx0ICs9IHRoaXMuX2V2ZW50c1tpXS5saXN0ZW5lckNvdW50KCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG59XG5cbi8qKlxuICogQ29udmVuaWVuY2UgY2xhc3MgZm9yIEFueUV2ZW50cyB3aXRob3V0IGRhdGFcbiAqL1xuZXhwb3J0IGNsYXNzIFZvaWRBbnlFdmVudCBleHRlbmRzIEFueUV2ZW50PHZvaWQ+IHtcblxuICAgIC8qKlxuICAgICAqIFNlbmQgdGhlIEFzeW5jRXZlbnQuXG4gICAgICovXG4gICAgcHVibGljIHBvc3QoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBzdXBlci5wb3N0KHVuZGVmaW5lZCk7XG4gICAgfVxufVxuXG4vKipcbiAqIFNpbWlsYXIgdG8gJ2Vycm9yJyBldmVudCBvbiBFdmVudEVtaXR0ZXI6IHRocm93cyB3aGVuIGEgcG9zdCgpIG9jY3VycyB3aGlsZSBubyBoYW5kbGVycyBzZXQuXG4gKi9cbmV4cG9ydCBjbGFzcyBFcnJvckFueUV2ZW50IGV4dGVuZHMgQW55RXZlbnQ8RXJyb3I+IHtcblxuICAgIHB1YmxpYyBwb3N0KGRhdGE6IEVycm9yKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGlmICh0aGlzLmxpc3RlbmVyQ291bnQoKSA9PT0gMCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBlcnJvciBldmVudCBwb3N0ZWQgd2hpbGUgbm8gbGlzdGVuZXJzIGF0dGFjaGVkLiBFcnJvcjogJHtkYXRhLm1lc3NhZ2V9YCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHN1cGVyLnBvc3QoZGF0YSk7XG4gICAgfVxufVxuIl19