UNPKG

ts-events

Version:

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

328 lines 40.1 kB
// Copyright © 2015 Rogier Schouten<github@workingcode.ninja> // License: ISC 'use strict'; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { 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 extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.ErrorAnyEvent = exports.VoidAnyEvent = exports.AnyEvent = exports.EventType = void 0; 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 = /** @class */ (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(); } } Object.defineProperty(AnyEvent.prototype, "evtListenersChanged", { /** * Sent when someone attaches or detaches */ get: function () { if (!this._listenersChanged) { // need to delay-load to avoid stack overflow in constructor this._listenersChanged = new sync_event_1.VoidSyncEvent(); } return this._listenersChanged; }, enumerable: false, configurable: true }); 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]; } return 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]; } return this._attach(mode, boundTo, handler, postable, opts, true); }; AnyEvent.prototype._attach = function (mode, boundTo, handler, postable, opts, once) { var _this = this; 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'); } var detacher; if (once) { if (postable) { detacher = event.once(postable); } else { detacher = event.once(boundTo, handler); } } else { if (postable) { detacher = event.attach(postable); } else { detacher = event.attach(boundTo, handler); } } if (this.evtFirstAttached && prevCount === 0) { this.evtFirstAttached.post(); } if (this.evtListenersChanged && prevCount !== this.listenerCount()) { this.evtListenersChanged.post(); } return function () { var prevCount = (!!_this.evtLastDetached ? _this.listenerCount() : 0); detacher(); if (!!_this.evtLastDetached && prevCount > 0 && _this.listenerCount() === 0) { _this.evtLastDetached.post(); } if (_this.evtListenersChanged && prevCount !== _this.listenerCount()) { _this.evtListenersChanged.post(); } }; }; AnyEvent.prototype.attachSync = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } args.unshift(EventType.Sync); return 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); return 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); return 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); return 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); return 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); return 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.listenerCount(); for (var i = 0; i < this._events.length; ++i) { this._events[i].detach.apply(this._events[i], args); } if (this.evtListenersChanged && prevCount !== this.listenerCount()) { this.evtListenersChanged.post(); } if (!!this.evtLastDetached && prevCount > 0 && this.listenerCount() === 0) { this.evtLastDetached.post(); } }; /** * Post an event to all current listeners */ AnyEvent.prototype.post = function (data) { // make a copy of the array first to cover the case where event handlers // are attached during the post var events = []; for (var i = 0; i < this._events.length; ++i) { events.push(this._events[i]); } for (var i = 0; i < events.length; ++i) { events[i].post(data); } }; /** * 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 = /** @class */ (function (_super) { __extends(VoidAnyEvent, _super); function VoidAnyEvent() { return _super !== null && _super.apply(this, arguments) || this; } /** * Send the AsyncEvent. */ VoidAnyEvent.prototype.post = function () { _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 = /** @class */ (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); } _super.prototype.post.call(this, data); }; return ErrorAnyEvent; }(AnyEvent)); exports.ErrorAnyEvent = ErrorAnyEvent; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW55LWV2ZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2xpYi9hbnktZXZlbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsNkRBQTZEO0FBQzdELGVBQWU7QUFFZixZQUFZLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7QUFFYixxQ0FBd0M7QUFHeEMsMkNBQXNEO0FBQ3RELDZDQUF5RDtBQUN6RCwrQ0FBNEQ7QUFFNUQsSUFBWSxTQUlYO0FBSkQsV0FBWSxTQUFTO0lBQ2pCLHlDQUFJLENBQUE7SUFDSiwyQ0FBSyxDQUFBO0lBQ0wsNkNBQU0sQ0FBQTtBQUNWLENBQUMsRUFKVyxTQUFTLEdBQVQsaUJBQVMsS0FBVCxpQkFBUyxRQUlwQjtBQVNEOzs7R0FHRztBQUNIO0lBaUNJLGtCQUFZLElBQW1CO1FBTC9COztXQUVHO1FBQ0ssWUFBTyxHQUFtQixFQUFFLENBQUM7UUFHakMsSUFBSSxJQUFJLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRTtZQUM1QixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztZQUMzQyxJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7U0FDN0M7SUFDTCxDQUFDO0lBbENELHNCQUFXLHlDQUFtQjtRQUg5Qjs7V0FFRzthQUNIO1lBQ0ksSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRTtnQkFDekIsNERBQTREO2dCQUM1RCxJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSwwQkFBYSxFQUFFLENBQUM7YUFDaEQ7WUFDRCxPQUFPLElBQUksQ0FBQyxpQkFBaUIsQ0FBQztRQUNsQyxDQUFDOzs7T0FBQTtJQXlDTSx5QkFBTSxHQUFiO1FBQWMsY0FBYzthQUFkLFVBQWMsRUFBZCxxQkFBYyxFQUFkLElBQWM7WUFBZCx5QkFBYzs7UUFDeEIsSUFBSSxJQUFJLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQztRQUMxQixJQUFJLElBQUksQ0FBQyxNQUFN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MjAxNSBSb2dpZXIgU2Nob3V0ZW48Z2l0aHViQHdvcmtpbmdjb2RlLm5pbmphPlxuLy8gTGljZW5zZTogSVNDXG5cbid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHtzaGFsbG93RXF1YWxzfSBmcm9tICcuL29iamVjdHMnO1xuXG5pbXBvcnQge0Jhc2VFdmVudCwgUG9zdGFibGV9IGZyb20gJy4vYmFzZS1ldmVudCc7XG5pbXBvcnQge1N5bmNFdmVudCwgVm9pZFN5bmNFdmVudH0gZnJvbSAnLi9zeW5jLWV2ZW50JztcbmltcG9ydCB7QXN5bmNFdmVudCwgQXN5bmNFdmVudE9wdHN9IGZyb20gJy4vYXN5bmMtZXZlbnQnO1xuaW1wb3J0IHtRdWV1ZWRFdmVudCwgUXVldWVkRXZlbnRPcHRzfSBmcm9tICcuL3F1ZXVlZC1ldmVudCc7XG5cbmV4cG9ydCBlbnVtIEV2ZW50VHlwZSB7XG4gICAgU3luYyxcbiAgICBBc3luYyxcbiAgICBRdWV1ZWRcbn1cblxuZXhwb3J0IGludGVyZmFjZSBBbnlFdmVudE9wdHMge1xuICAgIC8qKlxuICAgICAqIENyZWF0ZSBldnRGaXJzdEF0dGFjaGVkIGFuZCBldnRMYXN0RGV0YWNoZWQgc28geW91IGNhbiBtb25pdG9yIHdoZW4gc29tZW9uZSBpcyBzdWJzY3JpYmVkXG4gICAgICovXG4gICAgbW9uaXRvckF0dGFjaD86IGJvb2xlYW47XG59XG5cbi8qKlxuICogQW4gZXZlbnQgdGhhdCBiZWhhdmVzIGxpa2UgYSBTeW5jL0FzeW5jL1F1ZXVlZCBldmVudCBkZXBlbmRpbmcgb24gaG93XG4gKiB5b3Ugc3Vic2NyaWJlLlxuICovXG5leHBvcnQgY2xhc3MgQW55RXZlbnQ8VD4gaW1wbGVtZW50cyBQb3N0YWJsZTxUPiB7XG4gICAgLyoqXG4gICAgICogU2VudCB3aGVuIHNvbWVvbmUgYXR0YWNoZXMgb3IgZGV0YWNoZXNcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IGV2dExpc3RlbmVyc0NoYW5nZWQoKTogVm9pZFN5bmNFdmVudCB7XG4gICAgICAgIGlmICghdGhpcy5fbGlzdGVuZXJzQ2hhbmdlZCkge1xuICAgICAgICAgICAgLy8gbmVlZCB0byBkZWxheS1sb2FkIHRvIGF2b2lkIHN0YWNrIG92ZXJmbG93IGluIGNvbnN0cnVjdG9yXG4gICAgICAgICAgICB0aGlzLl9saXN0ZW5lcnNDaGFuZ2VkID0gbmV3IFZvaWRTeW5jRXZlbnQoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fbGlzdGVuZXJzQ2hhbmdlZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFdmVudCBmb3IgbGlzdGVuaW5nIHRvIGxpc3RlbmVyIGNvdW50XG4gICAgICovXG4gICAgcHJpdmF0ZSBfbGlzdGVuZXJzQ2hhbmdlZD86IFZvaWRTeW5jRXZlbnQ7XG5cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyZWQgd2hlbmV2ZXIgc29tZW9uZSBhdHRhY2hlcyBhbmQgbm9ib2R5IHdhcyBhdHRhY2hlZC5cbiAgICAgKiBOb3RlOiB5b3UgbXVzdCBjYWxsIHRoZSBjb25zdHJ1Y3RvciB3aXRoIG1vbml0b3JBdHRhY2ggc2V0IHRvIHRydWUgdG8gY3JlYXRlIHRoaXMgZXZlbnQhXG4gICAgICovXG4gICAgcHVibGljIGV2dEZpcnN0QXR0YWNoZWQ6IFZvaWRBbnlFdmVudDtcbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyZWQgd2hlbmV2ZXIgc29tZW9uZSBkZXRhY2hlcyBhbmQgbm9ib2R5IGlzIGF0dGFjaGVkIGFueW1vcmVcbiAgICAgKiBOb3RlOiB5b3UgbXVzdCBjYWxsIHRoZSBjb25zdHJ1Y3RvciB3aXRoIG1vbml0b3JBdHRhY2ggc2V0IHRvIHRydWUgdG8gY3JlYXRlIHRoaXMgZXZlbnQhXG4gICAgICovXG4gICAgcHVibGljIGV2dExhc3REZXRhY2hlZDogVm9pZEFueUV2ZW50O1xuXG4gICAgLyoqXG4gICAgICogVW5kZXJseWluZyBldmVudCBpbXBsZW1lbnRhdGlvbnM7IG9uZSBmb3IgZXZlcnkgYXR0YWNoIHR5cGUgKyBvcHRzIGNvbWJpbmF0aW9uXG4gICAgICovXG4gICAgcHJpdmF0ZSBfZXZlbnRzOiBCYXNlRXZlbnQ8VD5bXSA9IFtdO1xuXG4gICAgY29uc3RydWN0b3Iob3B0cz86IEFueUV2ZW50T3B0cykge1xuICAgICAgICBpZiAob3B0cyAmJiBvcHRzLm1vbml0b3JBdHRhY2gpIHtcbiAgICAgICAgICAgIHRoaXMuZXZ0Rmlyc3RBdHRhY2hlZCA9IG5ldyBWb2lkQW55RXZlbnQoKTtcbiAgICAgICAgICAgIHRoaXMuZXZ0TGFzdERldGFjaGVkID0gbmV3IFZvaWRBbnlFdmVudCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTGVnYWN5IG1ldGhvZFxuICAgICAqIHNhbWUgYXMgYXR0YWNoU3luYy9hdHRhY2hBc3luYy9hdHRhY2hRdWV1ZWQ7IGJhc2VkIG9uIHRoZSBnaXZlbiBlbnVtXG4gICAgICogQHBhcmFtIG1vZGUgZGV0ZXJtaW5lcyB3aGV0aGVyIHRvIGF0dGFjaCBzeW5jL2FzeW5jL3F1ZXVlZFxuICAgICAqL1xuICAgIHB1YmxpYyBhdHRhY2goaGFuZGxlcjogKGRhdGE6IFQpID0+IHZvaWQsIG9wdHM/OiBBc3luY0V2ZW50T3B0cyB8IFF1ZXVlZEV2ZW50T3B0cyk6ICgpID0+IHZvaWQ7XG4gICAgcHVibGljIGF0dGFjaChib3VuZFRvOiBPYmplY3QsIGhhbmRsZXI6IChkYXRhOiBUKSA9PiB2b2lkLCBvcHRzPzogQXN5bmNFdmVudE9wdHMgfCBRdWV1ZWRFdmVudE9wdHMpOiAoKSA9PiB2b2lkO1xuICAgIHB1YmxpYyBhdHRhY2goZXZlbnQ6IFBvc3RhYmxlPFQ+LCBvcHRzPzogQXN5bmNFdmVudE9wdHMgfCBRdWV1ZWRFdmVudE9wdHMpOiAoKSA9PiB2b2lkO1xuICAgIHB1YmxpYyBhdHRhY2gobW9kZTogRXZlbnRUeXBlLCBoYW5kbGVyOiAoZGF0YTogVCkgPT4gdm9pZCwgb3B0cz86IEFzeW5jRXZlbnRPcHRzIHwgUXVldWVkRXZlbnRPcHRzKTogKCkgPT4gdm9pZDtcbiAgICBwdWJsaWMgYXR0YWNoKG1vZGU6IEV2ZW50VHlwZSwgYm91bmRUbzogT2JqZWN0LCBoYW5kbGVyOiAoZGF0YTogVCkgPT4gdm9pZCwgb3B0cz86IEFzeW5jRXZlbnRPcHRzIHwgUXVldWVkRXZlbnRPcHRzKTogKCkgPT4gdm9pZDtcbiAgICBwdWJsaWMgYXR0YWNoKG1vZGU6IEV2ZW50VHlwZSwgZXZlbnQ6IFBvc3RhYmxlPFQ+LCBvcHRzPzogQXN5bmNFdmVudE9wdHMgfCBRdWV1ZWRFdmVudE9wdHMpOiAoKSA9PiB2b2lkO1xuICAgIHB1YmxpYyBhdHRhY2goLi4uYXJnczogYW55W10pOiAoKSA9PiB2b2lkIHtcbiAgICAgICAgbGV0IG1vZGUgPSBFdmVudFR5cGUuU3luYztcbiAgICAgICAgaWYgKGFyZ3MubGVuZ3RoID4gMCAmJiB0eXBlb2YgYXJnc1swXSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgIG1vZGUgPSBhcmdzLnNoaWZ0KCkgYXMgRXZlbnRUeXBlO1xuICAgICAgICB9XG4gICAgICAgIGxldCBib3VuZFRvOiBPYmplY3QgPSB0aGlzOyAvLyBhZGQgb3Vyc2VsdmVzIGFzIGRlZmF1bHQgJ2JvdW5kVG8nIGFyZ3VtZW50XG4gICAgICAgIGxldCBoYW5kbGVyOiAoKGRhdGE6IFQpID0+IHZvaWQpIHwgdW5kZWZpbmVkO1xuICAgICAgICBsZXQgb3B0czogQXN5bmNFdmVudE9wdHMgfCBRdWV1ZWRFdmVudE9wdHM7XG4gICAgICAgIGxldCBwb3N0YWJsZTogUG9zdGFibGU8VD4gfCB1bmRlZmluZWQ7XG4gICAgICAgIGlmICh0eXBlb2YgYXJnc1swXSA9PT0gJ2Z1bmN0aW9uJyB8fCAoYXJnc1swXSAmJiB0eXBlb2YgYXJnc1swXSA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIGFyZ3NbMF0ucG9zdCA9PT0gJ2Z1bmN0aW9uJykpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgYXJnc1swXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgIGhhbmRsZXIgPSBhcmdzWzBdO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBwb3N0YWJsZSA9IGFyZ3NbMF07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBvcHRzID0gYXJnc1sxXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGJvdW5kVG8gPSBhcmdzWzBdO1xuICAgICAgICAgICAgaGFuZGxlciA9IGFyZ3NbMV07XG4gICAgICAgICAgICBvcHRzID0gYXJnc1syXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fYXR0YWNoKG1vZGUsIGJvdW5kVG8sIGhhbmRsZXIsIHBvc3RhYmxlLCBvcHRzLCBmYWxzZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTGVnYWN5IG1ldGhvZFxuICAgICAqIHNhbWUgYXMgb25jZVN5bmMvb25jZUFzeW5jL29uY2VRdWV1ZWQ7IGJhc2VkIG9uIHRoZSBnaXZlbiBlbnVtXG4gICAgICogQHBhcmFtIG1vZGUgZGV0ZXJtaW5lcyB3aGV0aGVyIHRvIG9uY2Ugc3luYy9hc3luYy9xdWV1ZWRcbiAgICAgKi9cbiAgICBwdWJsaWMgb25jZShoYW5kbGVyOiAoZGF0YTogVCkgPT4gdm9pZCwgb3B0cz86IEFzeW5jRXZlbnRPcHRzIHwgUXVldWVkRXZlbnRPcHRzKTogKCkgPT4gdm9pZDtcbiAgICBwdWJsaWMgb25jZShib3VuZFRvOiBPYmplY3QsIGhhbmRsZXI6IChkYXRhOiBUKSA9PiB2b2lkLCBvcHRzPzogQXN5bmNFdmVudE9wdHMgfCBRdWV1ZWRFdmVudE9wdHMpOiAoKSA9PiB2b2lkO1xuICAgIHB1YmxpYyBvbmNlKGV2ZW50OiBQb3N0YWJsZTxUPiwgb3B0cz86IEFzeW5jRXZlbnRPcHRzIHwgUXVldWVkRXZlbnRPcHRzKTogKCkgPT4gdm9pZDtcbiAgICBwdWJsaWMgb25jZShtb2RlOiBFdmVudFR5cGUsIGhhbmRsZXI6IChkYXRhOiBUKSA9PiB2b2lkLCBvcHRzPzogQXN5bmNFdmVudE9wdHMgfCBRdWV1ZWRFdmVudE9wdHMpOiAoKSA9PiB2b2lkO1xuICAgIHB1YmxpYyBvbmNlKG1vZGU6IEV2ZW50VHlwZSwgYm91bmRUbzogT2JqZWN0LCBoYW5kbGVyOiAoZGF0YTogVCkgPT4gdm9pZCwgb3B0cz86IEFzeW5jRXZlbnRPcHRzIHwgUXVldWVkRXZlbnRPcHRzKTogKCkgPT4gdm9pZDtcbiAgICBwdWJsaWMgb25jZShtb2RlOiBFdmVudFR5cGUsIGV2ZW50OiBQb3N0YWJsZTxUPiwgb3B0cz86IEFzeW5jRXZlbnRPcHRzIHwgUXVldWVkRXZlbnRPcHRzKTogKCkgPT4gdm9pZDtcbiAgICBwdWJsaWMgb25jZSguLi5hcmdzOiBhbnlbXSk6ICgpID0+IHZvaWQge1xuICAgICAgICBsZXQgbW9kZSA9IEV2ZW50VHlwZS5TeW5jO1xuICAgICAgICBpZiAoYXJncy5sZW5ndGggPiAwICYmIHR5cGVvZiBhcmdzWzBdID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgbW9kZSA9IGFyZ3Muc2hpZnQoKSBhcyBFdmVudFR5cGU7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGJvdW5kVG86IG9iamVjdCA9IHRoaXM7IC8vIGFkZCBvdXJzZWx2ZXMgYXMgZGVmYXVsdCAnYm91bmRUbycgYXJndW1lbnRcbiAgICAgICAgbGV0IGhhbmRsZXI6ICgoZGF0YTogVCkgPT4gdm9pZCkgfCB1bmRlZmluZWQ7XG4gICAgICAgIGxldCBvcHRzOiBBc3luY0V2ZW50T3B0cyB8IFF1ZXVlZEV2ZW50T3B0cztcbiAgICAgICAgbGV0IHBvc3RhYmxlOiBQb3N0YWJsZTxUPiB8IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKHR5cGVvZiBhcmdzWzBdID09PSAnZnVuY3Rpb24nIHx8IChhcmdzWzBdICYmIHR5cGVvZiBhcmdzWzBdID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgYXJnc1swXS5wb3N0ID09PSAnZnVuY3Rpb24nKSkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBhcmdzWzBdID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgaGFuZGxlciA9IGFyZ3NbMF07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHBvc3RhYmxlID0gYXJnc1swXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG9wdHMgPSBhcmdzWzFdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYm91bmRUbyA9IGFyZ3NbMF07XG4gICAgICAgICAgICBoYW5kbGVyID0gYXJnc1sxXTtcbiAgICAgICAgICAgIG9wdHMgPSBhcmdzWzJdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9hdHRhY2gobW9kZSwgYm91bmRUbywgaGFuZGxlciwgcG9zdGFibGUsIG9wdHMsIHRydWUpO1xuICAgIH1cblxuICAgIHByaXZhdGUgX2F0dGFjaChcbiAgICAgICAgbW9kZTogRXZlbnRUeXBlLFxuICAgICAgICBib3VuZFRvOiBPYmplY3QgfCB1bmRlZmluZWQsXG4gICAgICAgIGhhbmRsZXI6ICgoZGF0YTogVCkgPT4gdm9pZCkgfCB1bmRlZmluZWQsXG4gICAgICAgIHBvc3RhYmxlOiBQb3N0YWJsZTxUPiB8IHVuZGVmaW5lZCxcbiAgICAgICAgb3B0czogQXN5bmNFdmVudE9wdHMgfCBRdWV1ZWRFdmVudE9wdHMgfCB1bmRlZmluZWQsXG4gICAgICAgIG9uY2U6IGJvb2xlYW5cbiAgICApOiAoKSA9PiB2b2lkIHtcbiAgICAgICAgY29uc3QgcHJldkNvdW50ID0gKCEhdGhpcy5ldnRGaXJzdEF0dGFjaGVkID8gdGhpcy5saXN0ZW5lckNvdW50KCkgOiAwKTtcbiAgICAgICAgbGV0IGV2ZW50OiBCYXNlRXZlbnQ8VD4gfCB1bmRlZmluZWQ7XG4gICAgICAgIHN3aXRjaCAobW9kZSkge1xuICAgICAgICAgICAgY2FzZSBFdmVudFR5cGUuU3luYzoge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgZXZ0IG9mIHRoaXMuX2V2ZW50cykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXZ0IGluc3RhbmNlb2YgU3luY0V2ZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudCA9IGV2dDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIWV2ZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50ID0gbmV3IFN5bmNFdmVudDxUPigpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9ldmVudHMucHVzaChldmVudCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRXZlbnRUeXBlLkFzeW5jOiB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBldnQgb2YgdGhpcy5fZXZlbnRzKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChldnQgaW5zdGFuY2VvZiBBc3luY0V2ZW50ICYmIHNoYWxsb3dFcXVhbHMoKDxBc3luY0V2ZW50PFQ+PmV2dCkub3B0aW9ucywgb3B0cykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50ID0gZXZ0O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghZXZlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQgPSBuZXcgQXN5bmNFdmVudDxUPihvcHRzKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZXZlbnRzLnB1c2goZXZlbnQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEV2ZW50VHlwZS5RdWV1ZWQ6IHtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGV2dCBvZiB0aGlzLl9ldmVudHMpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGV2dCBpbnN0YW5jZW9mIFF1ZXVlZEV2ZW50ICYmIHNoYWxsb3dFcXVhbHMoKDxRdWV1ZWRFdmVudDxUPj5ldnQpLm9wdGlvbnMsIG9wdHMpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudCA9IGV2dDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIWV2ZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50ID0gbmV3IFF1ZXVlZEV2ZW50PFQ+KG9wdHMpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9ldmVudHMucHVzaChldmVudCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd1bmtub3duIEV2ZW50VHlwZScpO1xuICAgICAgICB9XG4gICAgICAgIGxldCBkZXRhY2hlcjogKCkgPT4gdm9pZDtcbiAgICAgICAgaWYgKG9uY2UpIHtcbiAgICAgICAgICAgIGlmIChwb3N0YWJsZSkge1xuICAgICAgICAgICAgICAgIGRldGFjaGVyID0gZXZlbnQub25jZShwb3N0YWJsZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGRldGFjaGVyID0gZXZlbnQub25jZShib3VuZFRvISwgaGFuZGxlciEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKHBvc3RhYmxlKSB7XG4gICAgICAgICAgICAgICAgZGV0YWNoZXIgPSBldmVudC5hdHRhY2gocG9zdGFibGUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBkZXRhY2hlciA9IGV2ZW50LmF0dGFjaChib3VuZFRvISwgaGFuZGxlciEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmV2dEZpcnN0QXR0YWNoZWQgJiYgcHJldkNvdW50ID09PSAwKSB7XG4gICAgICAgICAgICB0aGlzLmV2dEZpcnN0QXR0YWNoZWQucG9zdCgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmV2dExpc3RlbmVyc0NoYW5nZWQgJiYgcHJldkNvdW50ICE9PSB0aGlzLmxpc3RlbmVyQ291bnQoKSkge1xuICAgICAgICAgICAgdGhpcy5ldnRMaXN0ZW5lcnNDaGFuZ2VkLnBvc3QoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gKCk6IHZvaWQgPT4ge1xuICAgICAgICAgICAgY29uc3QgcHJldkNvdW50ID0gKCEhdGhpcy5ldnRMYXN0RGV0YWNoZWQgPyB0aGlzLmxpc3RlbmVyQ291bnQoKSA6IDApO1xuICAgICAgICAgICAgZGV0YWNoZXIoKTtcbiAgICAgICAgICAgIGlmICghIXRoaXMuZXZ0TGFzdERldGFjaGVkICYmIHByZXZDb3VudCA+IDAgJiYgdGhpcy5saXN0ZW5lckNvdW50KCkgPT09IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLmV2dExhc3REZXRhY2hlZC5wb3N0KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5ldnRMaXN0ZW5lcnNDaGFuZ2VkICYmIHByZXZDb3VudCAhPT0gdGhpcy5saXN0ZW5lckNvdW50KCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmV2dExpc3RlbmVyc0NoYW5nZWQucG9zdCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHB1YmxpYyBhdHRhY2hTeW5jKGhhbmRsZXI6IChkYXRhOiBUKSA9PiB2b2lkKTogKCkgPT4gdm9pZDtcbiAgICBwdWJsaWMgYXR0YWNoU3luYyhib3VuZFRvOiBPYmplY3QsIGhhbmRsZXI6IChkYXRhOiBUKSA9PiB2b2lkKTogKCkgPT4gdm9pZDtcbiAgICBwdWJsaWMgYXR0YWNoU3luYyhldmVudDogUG9zdGFibGU8VD4pOiAoKSA9PiB2b2lkO1xuICAgIHB1YmxpYyBhdHRhY2hTeW5jKC4uLmFyZ3M6IGFueVtdKTogKCkgPT4gdm9pZCB7XG4gICAgICAgIGFyZ3MudW5zaGlmdChFdmVudFR5cGUuU3luYyk7XG4gICAgICAgIHJldHVybiB0aGlzLmF0dGFjaC5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25jZVN5bmMoaGFuZGxlcjogKGRhdGE6IFQpID0+IHZvaWQpOiAoKSA9PiB2b2lkO1xuICAgIHB1YmxpYyBvbmNlU3luYyhib3VuZFRvOiBPYmplY3QsIGhhbmRsZXI6IChkYXRhOiBUKSA9PiB2b2lkKTogKCkgPT4gdm9pZDtcbiAgICBwdWJsaWMgb25jZVN5bmMoZXZlbnQ6IFBvc3RhYmxlPFQ+KTogKCkgPT4gdm9pZDtcbiAgICBwdWJsaWMgb25jZVN5bmMoLi4uYXJnczogYW55W10pOiAoKSA9PiB2b2lkIHtcbiAgICAgICAgYXJncy51bnNoaWZ0KEV2ZW50VHlwZS5TeW5jKTtcbiAgICAgICAgcmV0dXJuIHRoaXMub25jZS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXR0YWNoQXN5bmMoaGFuZGxlcjogKGRhdGE6IFQpID0+IHZvaWQsIG9wdHM/OiBBc3luY0V2ZW50T3B0cyk6ICgpID0+IHZvaWQ7XG4gICAgcHVibGljIGF0dGFjaEFzeW5jKGJvdW5kVG86IE9iamVjdCwgaGFuZGxlcjogKGRhdGE6IFQpID0+IHZvaWQsIG9wdHM/OiBBc3luY0V2ZW50T3B0cyk6ICgpID0+IHZvaWQ7XG4gICAgcHVibGljIGF0dGFjaEFzeW5jKGV2ZW50OiBQb3N0YWJsZTxUPiwgb3B0cz86IEFzeW5jRXZlbnRPcHRzKTogKCkgPT4gdm9pZDtcbiAgICBwdWJsaWMgYXR0YWNoQXN5bmMoLi4uYXJnczogYW55W10pOiAoKSA9PiB2b2lkIHtcbiAgICAgICAgYXJncy51bnNoaWZ0KEV2ZW50VHlwZS5Bc3luYyk7XG4gICAgICAgIHJldHVybiB0aGlzLmF0dGFjaC5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25jZUFzeW5jKGhhbmRsZXI6IChkYXRhOiBUKSA9PiB2b2lkLCBvcHRzPzogQXN5bmNFdmVudE9wdHMpOiAoKSA9PiB2b2lkO1xuICAgIHB1YmxpYyBvbmNlQXN5bmMoYm91bmRUbzogT2JqZWN0LCBoYW5kbGVyOiAoZGF0YTogVCkgPT4gdm9pZCwgb3B0cz86IEFzeW5jRXZlbnRPcHRzKTogKCkgPT4gdm9pZDtcbiAgICBwdWJsaWMgb25jZUFzeW5jKGV2ZW50OiBQb3N0YWJsZTxUPiwgb3B0cz86IEFzeW5jRXZlbnRPcHRzKTogKCkgPT4gdm9pZDtcbiAgICBwdWJsaWMgb25jZUFzeW5jKC4uLmFyZ3M6IGFueVtdKTogKCkgPT4gdm9pZCB7XG4gICAgICAgIGFyZ3MudW5zaGlmdChFdmVudFR5cGUuQXN5bmMpO1xuICAgICAgICByZXR1cm4gdGhpcy5vbmNlLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhdHRhY2hRdWV1ZWQoaGFuZGxlcjogKGRhdGE6IFQpID0+IHZvaWQsIG9wdHM/OiBRdWV1ZWRFdmVudE9wdHMpOiAoKSA9PiB2b2lkO1xuICAgIHB1YmxpYyBhdHRhY2hRdWV1ZWQoYm91bmRUbzogT2JqZWN0LCBoYW5kbGVyOiAoZGF0YTogVCkgPT4gdm9pZCwgb3B0cz86IFF1ZXVlZEV2ZW50T3B0cyk6ICgpID0+IHZvaWQ7XG4gICAgcHVibGljIGF0dGFjaFF1ZXVlZChldmVudDogUG9zdGFibGU8VD4sIG9wdHM/OiBRdWV1ZWRFdmVudE9wdHMpOiAoKSA9PiB2b2lkO1xuICAgIHB1YmxpYyBhdHRhY2hRdWV1ZWQoLi4uYXJnczogYW55W10pOiAoKSA9PiB2b2lkIHtcbiAgICAgICAgYXJncy51bnNoaWZ0KEV2ZW50VHlwZS5RdWV1ZWQpO1xuICAgICAgICByZXR1cm4gdGhpcy5hdHRhY2guYXBwbHkodGhpcywgYXJncyk7XG4gICAgfVxuXG4gICAgcHVibGljIG9uY2VRdWV1ZWQoaGFuZGxlcjogKGRhdGE6IFQpID0+IHZvaWQsIG9wdHM/OiBRdWV1ZWRFdmVudE9wdHMpOiAoKSA9PiB2b2lkO1xuICAgIHB1YmxpYyBvbmNlUXVldWVkKGJvdW5kVG86IE9iamVjdCwgaGFuZGxlcjogKGRhdGE6IFQpID0+IHZvaWQsIG9wdHM/OiBRdWV1ZWRFdmVudE9wdHMpOiAoKSA9PiB2b2lkO1xuICAgIHB1YmxpYyBvbmNlUXVldWVkKGV2ZW50OiBQb3N0YWJsZTxUPiwgb3B0cz86IFF1ZXVlZEV2ZW50T3B0cyk6ICgpID0+IHZvaWQ7XG4gICAgcHVibGljIG9uY2VRdWV1ZWQoLi4uYXJnczogYW55W10pOiAoKSA9PiB2b2lkIHtcbiAgICAgICAgYXJncy51bnNoaWZ0KEV2ZW50VHlwZS5RdWV1ZWQpO1xuICAgICAgICByZXR1cm4gdGhpcy5vbmNlLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH1cblxuICAgIHB1YmxpYyBkZXRhY2goaGFuZGxlcjogKGRhdGE6IFQpID0+IHZvaWQpOiB2b2lkO1xuICAgIHB1YmxpYyBkZXRhY2goYm91bmRUbzogT2JqZWN0LCBoYW5kbGVyOiAoZGF0YTogVCkgPT4gdm9pZCk6IHZvaWQ7XG4gICAgcHVibGljIGRldGFjaChib3VuZFRvOiBPYmplY3QpOiB2b2lkO1xuICAgIHB1YmxpYyBkZXRhY2goZXZlbnQ6IFBvc3RhYmxlPFQ+KTogdm9pZDtcbiAgICBwdWJsaWMgZGV0YWNoKCk6IHZvaWQ7XG4gICAgLyoqXG4gICAgICogRGV0YWNoIGV2ZW50IGhhbmRsZXJzIHJlZ2FyZGxlc3Mgb2YgdHlwZVxuICAgICAqL1xuICAgIHB1YmxpYyBkZXRhY2goLi4uYXJnczogYW55W10pOiB2b2lkIHtcbiAgICAgICAgY29uc3QgcHJldkNvdW50ID0gdGhpcy5saXN0ZW5lckNvdW50KCk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fZXZlbnRzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICB0aGlzLl9ldmVudHNbaV0uZGV0YWNoLmFwcGx5KHRoaXMuX2V2ZW50c1tpXSwgYXJncyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuZXZ0TGlzdGVuZXJzQ2hhbmdlZCAmJiBwcmV2Q291bnQgIT09IHRoaXMubGlzdGVuZXJDb3VudCgpKSB7XG4gICAgICAgICAgICB0aGlzLmV2dExpc3RlbmVyc0NoYW5nZWQucG9zdCgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghIXRoaXMuZXZ0TGFzdERldGFjaGVkICYmIHByZXZDb3VudCA+IDAgJiYgdGhpcy5saXN0ZW5lckNvdW50KCkgPT09IDApIHtcbiAgICAgICAgICAgIHRoaXMuZXZ0TGFzdERldGFjaGVkLnBvc3QoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBvc3QgYW4gZXZlbnQgdG8gYWxsIGN1cnJlbnQgbGlzdGVuZXJzXG4gICAgICovXG4gICAgcHVibGljIHBvc3QoZGF0YTogVCk6IHZvaWQge1xuICAgICAgICAvLyBtYWtlIGEgY29weSBvZiB0aGUgYXJyYXkgZmlyc3QgdG8gY292ZXIgdGhlIGNhc2Ugd2hlcmUgZXZlbnQgaGFuZGxlcnNcbiAgICAgICAgLy8gYXJlIGF0dGFjaGVkIGR1cmluZyB0aGUgcG9zdFxuICAgICAgICBjb25zdCBldmVudHM6IEJhc2VFdmVudDxUPltdID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fZXZlbnRzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICBldmVudHMucHVzaCh0aGlzLl9ldmVudHNbaV0pO1xuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZXZlbnRzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICBldmVudHNbaV0ucG9zdChkYXRhKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2YgYXR0YWNoZWQgbGlzdGVuZXJzXG4gICAgICovXG4gICAgcHVibGljIGxpc3RlbmVyQ291bnQoKTogbnVtYmVyIHtcbiAgICAgICAgbGV0IHJlc3VsdCA9IDA7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fZXZlbnRzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICByZXN1bHQgKz0gdGhpcy5fZXZlbnRzW2ldLmxpc3RlbmVyQ291bnQoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbn1cblxuLyoqXG4gKiBDb252ZW5pZW5jZSBjbGFzcyBmb3IgQW55RXZlbnRzIHdpdGhvdXQgZGF0YVxuICovXG5leHBvcnQgY2xhc3MgVm9pZEFueUV2ZW50IGV4dGVuZHMgQW55RXZlbnQ8dm9pZD4ge1xuXG4gICAgLyoqXG4gICAgICogU2VuZCB0aGUgQXN5bmNFdmVudC5cbiAgICAgKi9cbiAgICBwdWJsaWMgcG9zdCgpOiB2b2lkIHtcbiAgICAgICAgc3VwZXIucG9zdCh1bmRlZmluZWQpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBTaW1pbGFyIHRvICdlcnJvcicgZXZlbnQgb24gRXZlbnRFbWl0dGVyOiB0aHJvd3Mgd2hlbiBhIHBvc3QoKSBvY2N1cnMgd2hpbGUgbm8gaGFuZGxlcnMgc2V0LlxuICovXG5leHBvcnQgY2xhc3MgRXJyb3JBbnlFdmVudCBleHRlbmRzIEFueUV2ZW50PEVycm9yPiB7XG5cbiAgICBwdWJsaWMgcG9zdChkYXRhOiBFcnJvcik6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5saXN0ZW5lckNvdW50KCkgPT09IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgZXJyb3IgZXZlbnQgcG9zdGVkIHdoaWxlIG5vIGxpc3RlbmVycyBhdHRhY2hlZC4gRXJyb3I6ICR7ZGF0YS5tZXNzYWdlfWApO1xuICAgICAgICB9XG4gICAgICAgIHN1cGVyLnBvc3QoZGF0YSk7XG4gICAgfVxufVxuIl19