UNPKG

@orbit/core

Version:

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

331 lines 35.5 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.TaskQueue = void 0; const main_1 = require("./main"); const task_processor_1 = require("./task-processor"); const evented_1 = require("./evented"); const { assert } = main_1.Orbit; /** * `TaskQueue` is a FIFO queue of asynchronous tasks that should be * performed sequentially. * * Tasks are added to the queue with `push`. Each task will be processed by * calling its `process` method. * * By default, task queues will be processed automatically, as soon as tasks * are pushed to them. This can be overridden by setting the `autoProcess` * setting to `false` and calling `process` when you'd like to start * processing. */ let TaskQueue = class TaskQueue { /** * Creates an instance of `TaskQueue`. */ constructor(target, settings = {}) { this._tasks = []; this._processors = []; this._performer = target; this._name = settings.name; this._bucket = settings.bucket; this.autoProcess = settings.autoProcess === undefined ? true : settings.autoProcess; if (this._bucket) { assert('TaskQueue requires a name if it has a bucket', !!this._name); } const autoActivate = settings.autoActivate === undefined || settings.autoActivate; if (autoActivate) { this.activate(); } else { this._reify(); } } async activate() { await this._reify(); if (this.length > 0 && this.autoProcess) { this.process(); } } /** * Name used for tracking / debugging this queue. */ get name() { return this._name; } /** * The object which will `perform` the tasks in this queue. */ get performer() { return this._performer; } /** * A bucket used to persist the state of this queue. */ get bucket() { return this._bucket; } /** * The number of tasks in the queue. */ get length() { return this._tasks.length; } /** * The tasks in the queue. */ get entries() { return this._tasks; } /** * The current task being processed (if actively processing), or the next * task to be processed (if not actively processing). */ get current() { return this._tasks[0]; } /** * The processor wrapper that is processing the current task (or next task, * if none are being processed). */ get currentProcessor() { return this._processors[0]; } /** * If an error occurs while processing a task, processing will be halted, the * `fail` event will be emitted, and this property will reflect the error * encountered. */ get error() { return this._error; } /** * Is the queue empty? */ get empty() { return this.length === 0; } /** * Is the queue actively processing a task? */ get processing() { const processor = this.currentProcessor; return processor !== undefined && processor.started && !processor.settled; } /** * Resolves when the queue has been fully reified from its associated bucket, * if applicable. */ get reified() { return this._reified; } /** * Push a new task onto the end of the queue. * * If `autoProcess` is enabled, this will automatically trigger processing of * the queue. * * Returns the result of processing the pushed task. */ async push(task) { await this._reified; const processor = new task_processor_1.TaskProcessor(this._performer, task); this._tasks.push(task); this._processors.push(processor); await this._persist(); if (this.autoProcess) this._settle(); return processor.settle(); } /** * Cancels and re-tries processing the current task. * * Returns the result of the retried task. */ async retry() { await this._reified; this._cancel(); let processor = this.currentProcessor; processor.reset(); await this._persist(); this._settle(); return processor.settle(); } /** * Cancels and discards the current task. * * If `autoProcess` is enabled, this will automatically trigger processing of * the queue. */ async skip(e) { await this._reified; this._cancel(); this._tasks.shift(); let processor = this._processors.shift(); if (processor !== undefined && !processor.settled) { processor.reject(e || new Error('Processing cancelled via `TaskQueue#skip`')); } await this._persist(); if (this.autoProcess) this._settle(); } /** * Cancels the current task and completely clears the queue. */ async clear(e) { await this._reified; this._cancel(); this._tasks = []; for (let processor of this._processors) { if (!processor.settled) { processor.reject(e || new Error('Processing cancelled via `TaskQueue#clear`')); } } this._processors = []; await this._persist(); await this._settle(); } /** * Cancels the current task and removes it, but does not continue processing. * * Returns the canceled and removed task. */ async shift(e) { await this._reified; let task = this._tasks.shift(); if (task) { this._cancel(); let processor = this._processors.shift(); if (processor !== undefined && !processor.settled) { processor.reject(e || new Error('Processing cancelled via `TaskQueue#shift`')); } await this._persist(); } return task; } /** * Cancels processing the current task and inserts a new task at the beginning * of the queue. This new task will be processed next. * * Returns the result of processing the new task. */ async unshift(task) { await this._reified; let processor = new task_processor_1.TaskProcessor(this._performer, task); this._cancel(); this._tasks.unshift(task); this._processors.unshift(processor); await this._persist(); if (this.autoProcess) this._settle(); return processor.settle(); } /** * Processes all the tasks in the queue. Resolves when the queue is empty. */ async process() { await this._reified; let resolution = this._resolution; if (!resolution) { if (this._tasks.length === 0) { resolution = this._complete(); } else { this._error = undefined; this._resolution = resolution = new Promise((resolve, reject) => { this._resolve = resolve; this._reject = reject; }); await this._settleEach(resolution); } } return resolution; } async _settle() { try { await this.process(); } catch (e) { } } async _complete() { if (this._resolve) { this._resolve(); } this._resolve = undefined; this._reject = undefined; this._error = undefined; this._resolution = undefined; await (0, evented_1.settleInSeries)(this, 'complete'); } async _fail(task, e) { if (this._reject) { this._reject(e); } this._resolve = undefined; this._reject = undefined; this._error = e; this._resolution = undefined; await (0, evented_1.settleInSeries)(this, 'fail', task, e); } _cancel() { this._error = undefined; this._resolution = undefined; } async _settleEach(resolution) { if (this._tasks.length === 0) { return this._complete(); } else { const task = this._tasks[0]; const processor = this._processors[0]; try { await (0, evented_1.settleInSeries)(this, 'beforeTask', task); await processor.process(); if (resolution === this._resolution) { this._tasks.shift(); this._processors.shift(); await this._persist(); await (0, evented_1.settleInSeries)(this, 'task', task); await this._settleEach(resolution); } } catch (e) { if (resolution === this._resolution) { return this._fail(task, e); } } } } _reify() { this._tasks = []; this._processors = []; this._reified = this._loadTasksFromBucket().then((tasks) => { if (tasks) { this._tasks = tasks; this._processors = tasks.map((task) => new task_processor_1.TaskProcessor(this._performer, task)); } }); return this._reified; } async _loadTasksFromBucket() { if (this._bucket && this._name) { return this._bucket.getItem(this._name); } } async _persist() { this.emit('change'); if (this._bucket && this._name) { await this._bucket.setItem(this._name, this._tasks); } } }; TaskQueue = __decorate([ evented_1.evented ], TaskQueue); exports.TaskQueue = TaskQueue; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFzay1xdWV1ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90YXNrLXF1ZXVlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQUFBLGlDQUErQjtBQUUvQixxREFBaUQ7QUFFakQsdUNBQTZEO0FBRTdELE1BQU0sRUFBRSxNQUFNLEVBQUUsR0FBRyxZQUFLLENBQUM7QUF5Q3pCOzs7Ozs7Ozs7OztHQVdHO0FBRUgsSUFBYSxTQUFTLEdBQXRCLE1BQWEsU0FBUztJQW1CcEI7O09BRUc7SUFDSCxZQUNFLE1BQThDLEVBQzlDLFdBQW1ELEVBQUU7UUFiL0MsV0FBTSxHQUFnQyxFQUFFLENBQUM7UUFDekMsZ0JBQVcsR0FBaUQsRUFBRSxDQUFDO1FBY3JFLElBQUksQ0FBQyxVQUFVLEdBQUcsTUFBTSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxLQUFLLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQztRQUMzQixJQUFJLENBQUMsT0FBTyxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUM7UUFDL0IsSUFBSSxDQUFDLFdBQVc7WUFDZCxRQUFRLENBQUMsV0FBVyxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDO1FBRW5FLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUNoQixNQUFNLENBQUMsOENBQThDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUN0RTtRQUVELE1BQU0sWUFBWSxHQUNoQixRQUFRLENBQUMsWUFBWSxLQUFLLFNBQVMsSUFBSSxRQUFRLENBQUMsWUFBWSxDQUFDO1FBRS9ELElBQUksWUFBWSxFQUFFO1lBQ2hCLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztTQUNqQjthQUFNO1lBQ0wsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1NBQ2Y7SUFDSCxDQUFDO0lBRUQsS0FBSyxDQUFDLFFBQVE7UUFDWixNQUFNLElB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QUssRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7U0FDckQ7SUFDSCxDQUFDO0NBQ0YsQ0FBQTtBQWxYWSxTQUFTO0lBRHJCLGlCQUFPO0dBQ0ssU0FBUyxDQWtYckI7QUFsWFksOEJBQVMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBPcmJpdCB9IGZyb20gJy4vbWFpbic7XG5pbXBvcnQgeyBUYXNrLCBQZXJmb3JtZXIgfSBmcm9tICcuL3Rhc2snO1xuaW1wb3J0IHsgVGFza1Byb2Nlc3NvciB9IGZyb20gJy4vdGFzay1wcm9jZXNzb3InO1xuaW1wb3J0IHsgQnVja2V0IH0gZnJvbSAnLi9idWNrZXQnO1xuaW1wb3J0IHsgZXZlbnRlZCwgRXZlbnRlZCwgc2V0dGxlSW5TZXJpZXMgfSBmcm9tICcuL2V2ZW50ZWQnO1xuXG5jb25zdCB7IGFzc2VydCB9ID0gT3JiaXQ7XG5cbi8qKlxuICogU2V0dGluZ3MgZm9yIGEgYFRhc2tRdWV1ZWAuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVGFza1F1ZXVlU2V0dGluZ3M8XG4gIFR5cGUgPSBzdHJpbmcsXG4gIERhdGEgPSB1bmtub3duLFxuICBPcHRpb25zID0gdW5rbm93blxuPiB7XG4gIC8qKlxuICAgKiBOYW1lIHVzZWQgZm9yIHRyYWNraW5nIGFuZCBkZWJ1Z2dpbmcgYSB0YXNrIHF1ZXVlLlxuICAgKi9cbiAgbmFtZT86IHN0cmluZztcblxuICAvKipcbiAgICogQSBidWNrZXQgaW4gd2hpY2ggdG8gcGVyc2lzdCBxdWV1ZSBzdGF0ZS5cbiAgICovXG4gIGJ1Y2tldD86IEJ1Y2tldDxUYXNrPFR5cGUsIERhdGEsIE9wdGlvbnM+W10+O1xuXG4gIC8qKlxuICAgKiBBIGZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHRhc2tzIHNob3VsZCBiZSBwcm9jZXNzZWQgYXMgc29vbiBhcyB0aGV5IGFyZVxuICAgKiBwdXNoZWQgaW50byBhIHF1ZXVlLiBTZXQgdG8gYGZhbHNlYCB0byBvdmVycmlkZSB0aGUgZGVmYXVsdCBgdHJ1ZWBcbiAgICogYmVoYXZpb3IuXG4gICAqL1xuICBhdXRvUHJvY2Vzcz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEEgZmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgYWN0aXZhdGlvbiBzaG91bGQgaGFwcGVuIGFzIHBhcnQgb2ZcbiAgICogaW5zdGFudGlhdGlvbi4gU2V0IHRvIGBmYWxzZWAgdG8gb3ZlcnJpZGUgdGhlIGRlZmF1bHQgYHRydWVgIGJlaGF2aW9yLiBXaGVuXG4gICAqIGBhdXRvQWN0aXZhdGUgPT09IGZhbHNlYCwgbm8gdGFza3MgcmVpZmllZCBmcm9tIHRoZSBxdWV1ZSdzIGJ1Y2tldCB3aWxsIGJlXG4gICAqIGF1dG9tYXRpY2FsbHkgcHJvY2Vzc2VkIGFzIHBhcnQgb2YgcXVldWUgaW5zdGFudGlhdGlvbiwgcmVnYXJkbGVzcyBvZiB0aGVcbiAgICogYGF1dG9Qcm9jZXNzYCBzZXR0aW5nLiBJbnZva2UgYHF1ZXVlLmFjdGl2YXRlKClgIGFzIGEgc2VwYXJhdGUgc3RlcCB0b1xuICAgKiBmaW5pc2ggYWN0aXZhdGlvbiBhbmQgc3RhcnQgcHJvY2Vzc2luZyB0YXNrcy5cbiAgICovXG4gIGF1dG9BY3RpdmF0ZT86IGJvb2xlYW47XG59XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZW1wdHktaW50ZXJmYWNlXG5leHBvcnQgaW50ZXJmYWNlIFRhc2tRdWV1ZSBleHRlbmRzIEV2ZW50ZWQge31cblxuLyoqXG4gKiBgVGFza1F1ZXVlYCBpcyBhIEZJRk8gcXVldWUgb2YgYXN5bmNocm9ub3VzIHRhc2tzIHRoYXQgc2hvdWxkIGJlXG4gKiBwZXJmb3JtZWQgc2VxdWVudGlhbGx5LlxuICpcbiAqIFRhc2tzIGFyZSBhZGRlZCB0byB0aGUgcXVldWUgd2l0aCBgcHVzaGAuIEVhY2ggdGFzayB3aWxsIGJlIHByb2Nlc3NlZCBieVxuICogY2FsbGluZyBpdHMgYHByb2Nlc3NgIG1ldGhvZC5cbiAqXG4gKiBCeSBkZWZhdWx0LCB0YXNrIHF1ZXVlcyB3aWxsIGJlIHByb2Nlc3NlZCBhdXRvbWF0aWNhbGx5LCBhcyBzb29uIGFzIHRhc2tzXG4gKiBhcmUgcHVzaGVkIHRvIHRoZW0uIFRoaXMgY2FuIGJlIG92ZXJyaWRkZW4gYnkgc2V0dGluZyB0aGUgYGF1dG9Qcm9jZXNzYFxuICogc2V0dGluZyB0byBgZmFsc2VgIGFuZCBjYWxsaW5nIGBwcm9jZXNzYCB3aGVuIHlvdSdkIGxpa2UgdG8gc3RhcnRcbiAqIHByb2Nlc3NpbmcuXG4gKi9cbkBldmVudGVkXG5leHBvcnQgY2xhc3MgVGFza1F1ZXVlPFxuICBUeXBlID0gc3RyaW5nLFxuICBEYXRhID0gdW5rbm93bixcbiAgT3B0aW9ucyA9IHVua25vd24sXG4gIFJlc3VsdCA9IHVua25vd25cbj4ge1xuICBwdWJsaWMgYXV0b1Byb2Nlc3M6IGJvb2xlYW47XG5cbiAgcHJpdmF0ZSBfcGVyZm9ybWVyOiBQZXJmb3JtZXI8VHlwZSwgRGF0YSwgT3B0aW9ucywgUmVzdWx0PjtcbiAgcHJpdmF0ZSBfbmFtZT86IHN0cmluZztcbiAgcHJpdmF0ZSBfYnVja2V0PzogQnVja2V0PFRhc2s8VHlwZSwgRGF0YSwgT3B0aW9ucz5bXT47XG4gIHByaXZhdGUgX3Rhc2tzOiBUYXNrPFR5cGUsIERhdGEsIE9wdGlvbnM+W10gPSBbXTtcbiAgcHJpdmF0ZSBfcHJvY2Vzc29yczogVGFza1Byb2Nlc3NvcjxUeXBlLCBEYXRhLCBPcHRpb25zLCBSZXN1bHQ+W10gPSBbXTtcbiAgcHJpdmF0ZSBfZXJyb3I/OiBFcnJvcjtcbiAgcHJpdmF0ZSBfcmVzb2x1dGlvbj86IFByb21pc2U8dm9pZD47XG4gIHByaXZhdGUgX3Jlc29sdmU/OiAoKSA9PiB2b2lkO1xuICBwcml2YXRlIF9yZWplY3Q/OiAoZTogRXJyb3IpID0+IHZvaWQ7XG4gIHByaXZhdGUgX3JlaWZpZWQhOiBQcm9taXNlPHZvaWQ+O1xuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIGBUYXNrUXVldWVgLlxuICAgKi9cbiAgY29uc3RydWN0b3IoXG4gICAgdGFyZ2V0OiBQZXJmb3JtZXI8VHlwZSwgRGF0YSwgT3B0aW9ucywgUmVzdWx0PixcbiAgICBzZXR0aW5nczogVGFza1F1ZXVlU2V0dGluZ3M8VHlwZSwgRGF0YSwgT3B0aW9ucz4gPSB7fVxuICApIHtcbiAgICB0aGlzLl9wZXJmb3JtZXIgPSB0YXJnZXQ7XG4gICAgdGhpcy5fbmFtZSA9IHNldHRpbmdzLm5hbWU7XG4gICAgdGhpcy5fYnVja2V0ID0gc2V0dGluZ3MuYnVja2V0O1xuICAgIHRoaXMuYXV0b1Byb2Nlc3MgPVxuICAgICAgc2V0dGluZ3MuYXV0b1Byb2Nlc3MgPT09IHVuZGVmaW5lZCA/IHRydWUgOiBzZXR0aW5ncy5hdXRvUHJvY2VzcztcblxuICAgIGlmICh0aGlzLl9idWNrZXQpIHtcbiAgICAgIGFzc2VydCgnVGFza1F1ZXVlIHJlcXVpcmVzIGEgbmFtZSBpZiBpdCBoYXMgYSBidWNrZXQnLCAhIXRoaXMuX25hbWUpO1xuICAgIH1cblxuICAgIGNvbnN0IGF1dG9BY3RpdmF0ZSA9XG4gICAgICBzZXR0aW5ncy5hdXRvQWN0aXZhdGUgPT09IHVuZGVmaW5lZCB8fCBzZXR0aW5ncy5hdXRvQWN0aXZhdGU7XG5cbiAgICBpZiAoYXV0b0FjdGl2YXRlKSB7XG4gICAgICB0aGlzLmFjdGl2YXRlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX3JlaWZ5KCk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgYWN0aXZhdGUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5fcmVpZnkoKTtcblxuICAgIGlmICh0aGlzLmxlbmd0aCA+IDAgJiYgdGhpcy5hdXRvUHJvY2Vzcykge1xuICAgICAgdGhpcy5wcm9jZXNzKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE5hbWUgdXNlZCBmb3IgdHJhY2tpbmcgLyBkZWJ1Z2dpbmcgdGhpcyBxdWV1ZS5cbiAgICovXG4gIGdldCBuYW1lKCk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuX25hbWU7XG4gIH1cblxuICAvKipcbiAgICogVGhlIG9iamVjdCB3aGljaCB3aWxsIGBwZXJmb3JtYCB0aGUgdGFza3MgaW4gdGhpcyBxdWV1ZS5cbiAgICovXG4gIGdldCBwZXJmb3JtZXIoKTogUGVyZm9ybWVyPFR5cGUsIERhdGEsIE9wdGlvbnMsIFJlc3VsdD4ge1xuICAgIHJldHVybiB0aGlzLl9wZXJmb3JtZXI7XG4gIH1cblxuICAvKipcbiAgICogQSBidWNrZXQgdXNlZCB0byBwZXJzaXN0IHRoZSBzdGF0ZSBvZiB0aGlzIHF1ZXVlLlxuICAgKi9cbiAgZ2V0IGJ1Y2tldCgpOiBCdWNrZXQ8VGFzazxUeXBlLCBEYXRhPltdPiB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuX2J1Y2tldDtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgbnVtYmVyIG9mIHRhc2tzIGluIHRoZSBxdWV1ZS5cbiAgICovXG4gIGdldCBsZW5ndGgoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5fdGFza3MubGVuZ3RoO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSB0YXNrcyBpbiB0aGUgcXVldWUuXG4gICAqL1xuICBnZXQgZW50cmllcygpOiBUYXNrPFR5cGUsIERhdGE+W10ge1xuICAgIHJldHVybiB0aGlzLl90YXNrcztcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgY3VycmVudCB0YXNrIGJlaW5nIHByb2Nlc3NlZCAoaWYgYWN0aXZlbHkgcHJvY2Vzc2luZyksIG9yIHRoZSBuZXh0XG4gICAqIHRhc2sgdG8gYmUgcHJvY2Vzc2VkIChpZiBub3QgYWN0aXZlbHkgcHJvY2Vzc2luZykuXG4gICAqL1xuICBnZXQgY3VycmVudCgpOiBUYXNrPFR5cGUsIERhdGE+IHtcbiAgICByZXR1cm4gdGhpcy5fdGFza3NbMF07XG4gIH1cblxuICAvKipcbiAgICogVGhlIHByb2Nlc3NvciB3cmFwcGVyIHRoYXQgaXMgcHJvY2Vzc2luZyB0aGUgY3VycmVudCB0YXNrIChvciBuZXh0IHRhc2ssXG4gICAqIGlmIG5vbmUgYXJlIGJlaW5nIHByb2Nlc3NlZCkuXG4gICAqL1xuICBnZXQgY3VycmVudFByb2Nlc3NvcigpOiBUYXNrUHJvY2Vzc29yPFR5cGUsIERhdGEsIE9wdGlvbnMsIFJlc3VsdD4ge1xuICAgIHJldHVybiB0aGlzLl9wcm9jZXNzb3JzWzBdO1xuICB9XG5cbiAgLyoqXG4gICAqIElmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBwcm9jZXNzaW5nIGEgdGFzaywgcHJvY2Vzc2luZyB3aWxsIGJlIGhhbHRlZCwgdGhlXG4gICAqIGBmYWlsYCBldmVudCB3aWxsIGJlIGVtaXR0ZWQsIGFuZCB0aGlzIHByb3BlcnR5IHdpbGwgcmVmbGVjdCB0aGUgZXJyb3JcbiAgICogZW5jb3VudGVyZWQuXG4gICAqL1xuICBnZXQgZXJyb3IoKTogRXJyb3IgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLl9lcnJvcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBJcyB0aGUgcXVldWUgZW1wdHk/XG4gICAqL1xuICBnZXQgZW1wdHkoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMubGVuZ3RoID09PSAwO1xuICB9XG5cbiAgLyoqXG4gICAqIElzIHRoZSBxdWV1ZSBhY3RpdmVseSBwcm9jZXNzaW5nIGEgdGFzaz9cbiAgICovXG4gIGdldCBwcm9jZXNzaW5nKCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHByb2Nlc3NvciA9IHRoaXMuY3VycmVudFByb2Nlc3NvcjtcblxuICAgIHJldHVybiBwcm9jZXNzb3IgIT09IHVuZGVmaW5lZCAmJiBwcm9jZXNzb3Iuc3RhcnRlZCAmJiAhcHJvY2Vzc29yLnNldHRsZWQ7XG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZXMgd2hlbiB0aGUgcXVldWUgaGFzIGJlZW4gZnVsbHkgcmVpZmllZCBmcm9tIGl0cyBhc3NvY2lhdGVkIGJ1Y2tldCxcbiAgICogaWYgYXBwbGljYWJsZS5cbiAgICovXG4gIGdldCByZWlmaWVkKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLl9yZWlmaWVkO1xuICB9XG5cbiAgLyoqXG4gICAqIFB1c2ggYSBuZXcgdGFzayBvbnRvIHRoZSBlbmQgb2YgdGhlIHF1ZXVlLlxuICAgKlxuICAgKiBJZiBgYXV0b1Byb2Nlc3NgIGlzIGVuYWJsZWQsIHRoaXMgd2lsbCBhdXRvbWF0aWNhbGx5IHRyaWdnZXIgcHJvY2Vzc2luZyBvZlxuICAgKiB0aGUgcXVldWUuXG4gICAqXG4gICAqIFJldHVybnMgdGhlIHJlc3VsdCBvZiBwcm9jZXNzaW5nIHRoZSBwdXNoZWQgdGFzay5cbiAgICovXG4gIGFzeW5jIHB1c2godGFzazogVGFzazxUeXBlLCBEYXRhLCBPcHRpb25zPik6IFByb21pc2U8UmVzdWx0PiB7XG4gICAgYXdhaXQgdGhpcy5fcmVpZmllZDtcblxuICAgIGNvbnN0IHByb2Nlc3NvciA9IG5ldyBUYXNrUHJvY2Vzc29yKHRoaXMuX3BlcmZvcm1lciwgdGFzayk7XG4gICAgdGhpcy5fdGFza3MucHVzaCh0YXNrKTtcbiAgICB0aGlzLl9wcm9jZXNzb3JzLnB1c2gocHJvY2Vzc29yKTtcbiAgICBhd2FpdCB0aGlzLl9wZXJzaXN0KCk7XG4gICAgaWYgKHRoaXMuYXV0b1Byb2Nlc3MpIHRoaXMuX3NldHRsZSgpO1xuICAgIHJldHVybiBwcm9jZXNzb3Iuc2V0dGxlKCk7XG4gIH1cblxuICAvKipcbiAgICogQ2FuY2VscyBhbmQgcmUtdHJpZXMgcHJvY2Vzc2luZyB0aGUgY3VycmVudCB0YXNrLlxuICAgKlxuICAgKiBSZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHJldHJpZWQgdGFzay5cbiAgICovXG4gIGFzeW5jIHJldHJ5KCk6IFByb21pc2U8UmVzdWx0PiB7XG4gICAgYXdhaXQgdGhpcy5fcmVpZmllZDtcblxuICAgIHRoaXMuX2NhbmNlbCgpO1xuICAgIGxldCBwcm9jZXNzb3IgPSB0aGlzLmN1cnJlbnRQcm9jZXNzb3I7XG4gICAgcHJvY2Vzc29yLnJlc2V0KCk7XG4gICAgYXdhaXQgdGhpcy5fcGVyc2lzdCgpO1xuICAgIHRoaXMuX3NldHRsZSgpO1xuICAgIHJldHVybiBwcm9jZXNzb3Iuc2V0dGxlKCk7XG4gIH1cblxuICAvKipcbiAgICogQ2FuY2VscyBhbmQgZGlzY2FyZHMgdGhlIGN1cnJlbnQgdGFzay5cbiAgICpcbiAgICogSWYgYGF1dG9Qcm9jZXNzYCBpcyBlbmFibGVkLCB0aGlzIHdpbGwgYXV0b21hdGljYWxseSB0cmlnZ2VyIHByb2Nlc3Npbmcgb2ZcbiAgICogdGhlIHF1ZXVlLlxuICAgKi9cbiAgYXN5bmMgc2tpcChlPzogRXJyb3IpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLl9yZWlmaWVkO1xuXG4gICAgdGhpcy5fY2FuY2VsKCk7XG4gICAgdGhpcy5fdGFza3Muc2hpZnQoKTtcbiAgICBsZXQgcHJvY2Vzc29yID0gdGhpcy5fcHJvY2Vzc29ycy5zaGlmdCgpO1xuICAgIGlmIChwcm9jZXNzb3IgIT09IHVuZGVmaW5lZCAmJiAhcHJvY2Vzc29yLnNldHRsZWQpIHtcbiAgICAgIHByb2Nlc3Nvci5yZWplY3QoXG4gICAgICAgIGUgfHwgbmV3IEVycm9yKCdQcm9jZXNzaW5nIGNhbmNlbGxlZCB2aWEgYFRhc2tRdWV1ZSNza2lwYCcpXG4gICAgICApO1xuICAgIH1cbiAgICBhd2FpdCB0aGlzLl9wZXJzaXN0KCk7XG4gICAgaWYgKHRoaXMuYXV0b1Byb2Nlc3MpIHRoaXMuX3NldHRsZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbmNlbHMgdGhlIGN1cnJlbnQgdGFzayBhbmQgY29tcGxldGVseSBjbGVhcnMgdGhlIHF1ZXVlLlxuICAgKi9cbiAgYXN5bmMgY2xlYXIoZT86IEVycm9yKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5fcmVpZmllZDtcblxuICAgIHRoaXMuX2NhbmNlbCgpO1xuICAgIHRoaXMuX3Rhc2tzID0gW107XG4gICAgZm9yIChsZXQgcHJvY2Vzc29yIG9mIHRoaXMuX3Byb2Nlc3NvcnMpIHtcbiAgICAgIGlmICghcHJvY2Vzc29yLnNldHRsZWQpIHtcbiAgICAgICAgcHJvY2Vzc29yLnJlamVjdChcbiAgICAgICAgICBlIHx8IG5ldyBFcnJvcignUHJvY2Vzc2luZyBjYW5jZWxsZWQgdmlhIGBUYXNrUXVldWUjY2xlYXJgJylcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5fcHJvY2Vzc29ycyA9IFtdO1xuICAgIGF3YWl0IHRoaXMuX3BlcnNpc3QoKTtcbiAgICBhd2FpdCB0aGlzLl9zZXR0bGUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYW5jZWxzIHRoZSBjdXJyZW50IHRhc2sgYW5kIHJlbW92ZXMgaXQsIGJ1dCBkb2VzIG5vdCBjb250aW51ZSBwcm9jZXNzaW5nLlxuICAgKlxuICAgKiBSZXR1cm5zIHRoZSBjYW5jZWxlZCBhbmQgcmVtb3ZlZCB0YXNrLlxuICAgKi9cbiAgYXN5bmMgc2hpZnQoZT86IEVycm9yKTogUHJvbWlzZTxUYXNrPFR5cGUsIERhdGE+IHwgdW5kZWZpbmVkPiB7XG4gICAgYXdhaXQgdGhpcy5fcmVpZmllZDtcblxuICAgIGxldCB0YXNrID0gdGhpcy5fdGFza3Muc2hpZnQoKTtcbiAgICBpZiAodGFzaykge1xuICAgICAgdGhpcy5fY2FuY2VsKCk7XG4gICAgICBsZXQgcHJvY2Vzc29yID0gdGhpcy5fcHJvY2Vzc29ycy5zaGlmdCgpO1xuICAgICAgaWYgKHByb2Nlc3NvciAhPT0gdW5kZWZpbmVkICYmICFwcm9jZXNzb3Iuc2V0dGxlZCkge1xuICAgICAgICBwcm9jZXNzb3IucmVqZWN0KFxuICAgICAgICAgIGUgfHwgbmV3IEVycm9yKCdQcm9jZXNzaW5nIGNhbmNlbGxlZCB2aWEgYFRhc2tRdWV1ZSNzaGlmdGAnKVxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgYXdhaXQgdGhpcy5fcGVyc2lzdCgpO1xuICAgIH1cbiAgICByZXR1cm4gdGFzaztcbiAgfVxuXG4gIC8qKlxuICAgKiBDYW5jZWxzIHByb2Nlc3NpbmcgdGhlIGN1cnJlbnQgdGFzayBhbmQgaW5zZXJ0cyBhIG5ldyB0YXNrIGF0IHRoZSBiZWdpbm5pbmdcbiAgICogb2YgdGhlIHF1ZXVlLiBUaGlzIG5ldyB0YXNrIHdpbGwgYmUgcHJvY2Vzc2VkIG5leHQuXG4gICAqXG4gICAqIFJldHVybnMgdGhlIHJlc3VsdCBvZiBwcm9jZXNzaW5nIHRoZSBuZXcgdGFzay5cbiAgICovXG4gIGFzeW5jIHVuc2hpZnQodGFzazogVGFzazxUeXBlLCBEYXRhLCBPcHRpb25zPik6IFByb21pc2U8UmVzdWx0PiB7XG4gICAgYXdhaXQgdGhpcy5fcmVpZmllZDtcblxuICAgIGxldCBwcm9jZXNzb3IgPSBuZXcgVGFza1Byb2Nlc3NvcjxUeXBlLCBEYXRhLCBPcHRpb25zLCBSZXN1bHQ+KFxuICAgICAgdGhpcy5fcGVyZm9ybWVyLFxuICAgICAgdGFza1xuICAgICk7XG4gICAgdGhpcy5fY2FuY2VsKCk7XG4gICAgdGhpcy5fdGFza3MudW5zaGlmdCh0YXNrKTtcbiAgICB0aGlzLl9wcm9jZXNzb3JzLnVuc2hpZnQocHJvY2Vzc29yKTtcbiAgICBhd2FpdCB0aGlzLl9wZXJzaXN0KCk7XG4gICAgaWYgKHRoaXMuYXV0b1Byb2Nlc3MpIHRoaXMuX3NldHRsZSgpO1xuICAgIHJldHVybiBwcm9jZXNzb3Iuc2V0dGxlKCk7XG4gIH1cblxuICAvKipcbiAgICogUHJvY2Vzc2VzIGFsbCB0aGUgdGFza3MgaW4gdGhlIHF1ZXVlLiBSZXNvbHZlcyB3aGVuIHRoZSBxdWV1ZSBpcyBlbXB0eS5cbiAgICovXG4gIGFzeW5jIHByb2Nlc3MoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5fcmVpZmllZDtcblxuICAgIGxldCByZXNvbHV0aW9uID0gdGhpcy5fcmVzb2x1dGlvbjtcbiAgICBpZiAoIXJlc29sdXRpb24pIHtcbiAgICAgIGlmICh0aGlzLl90YXNrcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmVzb2x1dGlvbiA9IHRoaXMuX2NvbXBsZXRlKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9lcnJvciA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5fcmVzb2x1dGlvbiA9IHJlc29sdXRpb24gPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgdGhpcy5fcmVzb2x2ZSA9IHJlc29sdmU7XG4gICAgICAgICAgdGhpcy5fcmVqZWN0ID0gcmVqZWN0O1xuICAgICAgICB9KTtcbiAgICAgICAgYXdhaXQgdGhpcy5fc2V0dGxlRWFjaChyZXNvbHV0aW9uKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc29sdXRpb247XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIF9zZXR0bGUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMucHJvY2VzcygpO1xuICAgIH0gY2F0Y2ggKGUpIHt9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIF9jb21wbGV0ZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5fcmVzb2x2ZSkge1xuICAgICAgdGhpcy5fcmVzb2x2ZSgpO1xuICAgIH1cbiAgICB0aGlzLl9yZXNvbHZlID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX3JlamVjdCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl9lcnJvciA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl9yZXNvbHV0aW9uID0gdW5kZWZpbmVkO1xuICAgIGF3YWl0IHNldHRsZUluU2VyaWVzKHRoaXMsICdjb21wbGV0ZScpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBfZmFpbCh0YXNrOiBUYXNrPFR5cGUsIERhdGE+LCBlOiBFcnJvcik6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLl9yZWplY3QpIHtcbiAgICAgIHRoaXMuX3JlamVjdChlKTtcbiAgICB9XG4gICAgdGhpcy5fcmVzb2x2ZSA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl9yZWplY3QgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5fZXJyb3IgPSBlO1xuICAgIHRoaXMuX3Jlc29sdXRpb24gPSB1bmRlZmluZWQ7XG4gICAgYXdhaXQgc2V0dGxlSW5TZXJpZXModGhpcywgJ2ZhaWwnLCB0YXNrLCBlKTtcbiAgfVxuXG4gIHByaXZhdGUgX2NhbmNlbCgpOiB2b2lkIHtcbiAgICB0aGlzLl9lcnJvciA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl9yZXNvbHV0aW9uID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBfc2V0dGxlRWFjaChyZXNvbHV0aW9uOiBhbnkpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5fdGFza3MubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gdGhpcy5fY29tcGxldGUoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgdGFzayA9IHRoaXMuX3Rhc2tzWzBdO1xuICAgICAgY29uc3QgcHJvY2Vzc29yID0gdGhpcy5fcHJvY2Vzc29yc1swXTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgc2V0dGxlSW5TZXJpZXModGhpcywgJ2JlZm9yZVRhc2snLCB0YXNrKTtcbiAgICAgICAgYXdhaXQgcHJvY2Vzc29yLnByb2Nlc3MoKTtcbiAgICAgICAgaWYgKHJlc29sdXRpb24gPT09IHRoaXMuX3Jlc29sdXRpb24pIHtcbiAgICAgICAgICB0aGlzLl90YXNrcy5zaGlmdCgpO1xuICAgICAgICAgIHRoaXMuX3Byb2Nlc3NvcnMuc2hpZnQoKTtcblxuICAgICAgICAgIGF3YWl0IHRoaXMuX3BlcnNpc3QoKTtcbiAgICAgICAgICBhd2FpdCBzZXR0bGVJblNlcmllcyh0aGlzLCAndGFzaycsIHRhc2spO1xuICAgICAgICAgIGF3YWl0IHRoaXMuX3NldHRsZUVhY2gocmVzb2x1dGlvbik7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgaWYgKHJlc29sdXRpb24gPT09IHRoaXMuX3Jlc29sdXRpb24pIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5fZmFpbCh0YXNrLCBlIGFzIEVycm9yKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX3JlaWZ5KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuX3Rhc2tzID0gW107XG4gICAgdGhpcy5fcHJvY2Vzc29ycyA9IFtdO1xuXG4gICAgdGhpcy5fcmVpZmllZCA9IHRoaXMuX2xvYWRUYXNrc0Zyb21CdWNrZXQoKS50aGVuKFxuICAgICAgKHRhc2tzOiBUYXNrPFR5cGUsIERhdGEsIE9wdGlvbnM+W10gfCB1bmRlZmluZWQpID0+IHtcbiAgICAgICAgaWYgKHRhc2tzKSB7XG4gICAgICAgICAgdGhpcy5fdGFza3MgPSB0YXNrcztcbiAgICAgICAgICB0aGlzLl9wcm9jZXNzb3JzID0gdGFza3MubWFwKFxuICAgICAgICAgICAgKHRhc2spID0+IG5ldyBUYXNrUHJvY2Vzc29yKHRoaXMuX3BlcmZvcm1lciwgdGFzaylcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgKTtcblxuICAgIHJldHVybiB0aGlzLl9yZWlmaWVkO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBfbG9hZFRhc2tzRnJvbUJ1Y2tldCgpOiBQcm9taXNlPFxuICAgIFRhc2s8VHlwZSwgRGF0YSwgT3B0aW9ucz5bXSB8IHVuZGVmaW5lZFxuICA+IHtcbiAgICBpZiAodGhpcy5fYnVja2V0ICYmIHRoaXMuX25hbWUpIHtcbiAgICAgIHJldHVybiB0aGlzLl9idWNrZXQuZ2V0SXRlbSh0aGlzLl9uYW1lKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIF9wZXJzaXN0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuZW1pdCgnY2hhbmdlJyk7XG4gICAgaWYgKHRoaXMuX2J1Y2tldCAmJiB0aGlzLl9uYW1lKSB7XG4gICAgICBhd2FpdCB0aGlzLl9idWNrZXQuc2V0SXRlbSh0aGlzLl9uYW1lLCB0aGlzLl90YXNrcyk7XG4gICAgfVxuICB9XG59XG4iXX0=