com.phloxui
Version:
PhloxUI Ng2+ Framework
536 lines (535 loc) • 47 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
import { EventEmitter } from '@angular/core';
import { LoaderStatus } from './LoaderStatus';
import { DefaultLoadTask } from './DefaultLoadTask';
import { EventUtils } from '../share/utils/EventUtils';
import { TASK_START_EVENT, TASK_COMPLETE_EVENT, TASK_RESOLVE_EVENT, TASK_REJECT_EVENT, PAUSE_EVENT, RESUME_EVENT, STOP_EVENT } from '../share/CustomEventType';
export class LoadProcess {
/**
* @param {?} name
* @param {?=} continueOnReject
*/
constructor(name, continueOnReject) {
this.name = name;
this.status = LoaderStatus.STOPPED;
this.tasks = [];
this.successResult = {};
this.rejectResult = {};
this.disabled = false;
this.isFirstStarted = false;
this.percent = 0;
this.currentTask = null;
this.taskStartEvent = new EventEmitter();
this.taskCompleteEvent = new EventEmitter();
this.taskResolveEvent = new EventEmitter();
this.taskRejectEvent = new EventEmitter();
this.pauseEvent = new EventEmitter();
this.resumeEvent = new EventEmitter();
this.startEvent = new EventEmitter();
this.stopEvent = new EventEmitter();
if (continueOnReject === null || typeof continueOnReject !== 'boolean') {
this.continueOnReject = true;
}
else {
this.continueOnReject = continueOnReject;
}
}
/**
* @param {?} taskCount
* @return {?}
*/
updatePercent(taskCount) {
let /** @type {?} */ allTask = (this.tasks.length > 0) ? this.tasks.length : 0;
let /** @type {?} */ perTask = 0;
if (allTask > 0) {
perTask = 100 / allTask;
}
let /** @type {?} */ totalPercent = taskCount * perTask;
if (taskCount === allTask) {
totalPercent = 100;
}
this.percent = totalPercent;
}
/**
* @return {?}
*/
getResultObject() {
let /** @type {?} */ result = {
success: this.successResult,
error: this.rejectResult
};
return result;
}
/**
* @param {?} type
* @param {?} name
* @param {?} success
* @param {?} error
* @return {?}
*/
getCustomEventObject(type, name, success, error) {
let /** @type {?} */ successCount = Object.keys(this.successResult).length;
let /** @type {?} */ errorCount = Object.keys(this.rejectResult).length;
let /** @type {?} */ wrapData = {
name: name,
success: success,
error: error,
percent: this.percent,
totalCount: this.tasks.length,
processed: successCount + errorCount,
successCount: successCount,
errorCount: errorCount
};
let /** @type {?} */ ev = EventUtils.newCustomEvent(type, null, wrapData, null);
return ev;
}
/**
* @param {?} index
* @return {?}
*/
wrapPromise(index) {
if (index <= -1 || index >= this.tasks.length) {
return Promise.resolve();
}
if (this.isStopped()) {
let /** @type {?} */ result = {
loadStatus: LoaderStatus.STOPPED,
index: index
};
return Promise.reject(result);
}
if (index >= this.tasks.length) {
return Promise.resolve(null);
}
if (this.isPaused()) {
return this.delayPromise(Promise.resolve(), 500).then((result) => {
return this.wrapPromise(index);
});
}
let /** @type {?} */ currentResult = this.getResultObject();
this.currentTask = this.tasks[index];
let /** @type {?} */ taskName = this.currentTask.getName();
let /** @type {?} */ compEv = this.getCustomEventObject(TASK_START_EVENT, taskName, null, null);
this.taskStartEvent.emit(compEv);
let /** @type {?} */ exeProm = null;
try {
exeProm = this.tasks[index].execute(currentResult);
}
catch (/** @type {?} */ e) {
exeProm = Promise.reject(e);
}
return exeProm.then((result) => {
this.successResult[taskName] = result;
// update percent
this.updatePercent(index + 1);
// emit complete event
let /** @type {?} */ ev = this.getCustomEventObject(TASK_RESOLVE_EVENT, taskName, result, null);
this.taskResolveEvent.emit(ev);
let /** @type {?} */ compEv = this.getCustomEventObject(TASK_COMPLETE_EVENT, taskName, result, null);
this.taskCompleteEvent.emit(compEv);
this.currentTask = null;
return this.wrapPromise(++index);
}, (rejResult) => {
if (rejResult !== null && rejResult !== 'undefined') {
if (rejResult.loadStatus !== LoaderStatus.STOPPED) {
// this is real reject result
let /** @type {?} */ taskName = this.tasks[index].getName();
this.rejectResult[taskName] = rejResult;
// continue to next promise
if (this.continueOnReject) {
this.updatePercent(index + 1);
// emit complated event
let /** @type {?} */ ev = this.getCustomEventObject(TASK_REJECT_EVENT, taskName, null, rejResult);
this.taskRejectEvent.emit(ev);
let /** @type {?} */ compEv = this.getCustomEventObject(TASK_COMPLETE_EVENT, taskName, null, rejResult);
this.taskCompleteEvent.emit(compEv);
this.currentTask = null;
return this.wrapPromise(++index);
}
}
}
// that mean not continue to next promise
if (rejResult.loadStatus !== LoaderStatus.STOPPED) {
this.updatePercent(index + 1);
let /** @type {?} */ ev = this.getCustomEventObject(TASK_REJECT_EVENT, taskName, null, rejResult);
this.taskRejectEvent.emit(ev);
let /** @type {?} */ compEv = this.getCustomEventObject(TASK_COMPLETE_EVENT, taskName, null, rejResult);
this.taskCompleteEvent.emit(compEv);
this.currentTask = null;
}
return Promise.reject(rejResult);
});
}
/**
* @param {?} prom
* @param {?} delayMS
* @return {?}
*/
delayPromise(prom, delayMS) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, delayMS);
}).then(() => {
return prom;
});
}
/**
* @param {?} name
* @param {?} taskFunc
* @return {?}
*/
add(name, taskFunc) {
if (this.isFirstStarted) {
throw new Error('Process was started or has been process');
}
this.tasks.push(new DefaultLoadTask(name, taskFunc));
return this;
}
/**
* @param {?} task
* @return {?}
*/
addTask(task) {
if (this.isFirstStarted) {
throw new Error('Process was started or has been process');
}
if (task !== null && task !== undefined) {
this.tasks.push(task);
}
return this;
}
/**
* @param {?} task
* @return {?}
*/
removeTask(task) {
if (this.isFirstStarted) {
throw new Error('Process was started or has been process');
}
let /** @type {?} */ index = this.tasks.indexOf(task);
return this.remove(index);
}
/**
* @param {?} index
* @return {?}
*/
remove(index) {
if (this.isFirstStarted) {
throw new Error('Process was started or has been process');
}
if (index < this.tasks.length) {
this.tasks.splice(index, 1);
}
return this;
}
/**
* @param {?} disabled
* @return {?}
*/
setDisabled(disabled) {
this.disabled = disabled;
}
/**
* @return {?}
*/
isDisabled() {
return this.disabled;
}
/**
* @return {?}
*/
start() {
if (this.disabled) {
throw new Error('Process is disabled');
}
if (this.isFirstStarted) {
throw new Error('Process was started or has been process');
}
if (this.isStopped()) {
this.status = LoaderStatus.RUNNING;
this.isFirstStarted = true;
}
// promise start
return new Promise((resolve, reject) => {
this.wrapPromise(0).then((result) => {
let /** @type {?} */ resolveResult = this.getResultObject();
resolve(resolveResult);
}, (rejectResult) => {
let /** @type {?} */ resolveResult = this.getResultObject();
if (rejectResult !== null && rejectResult !== undefined && rejectResult.loadStatus === LoaderStatus.STOPPED) {
// break for STOP status
resolve(resolveResult);
}
else {
if (this.continueOnReject) {
// resolve whatever rejected
resolve(resolveResult);
}
else {
// reject if any of reject was found
reject(resolveResult);
}
}
});
});
}
/**
* @return {?}
*/
pause() {
if (this.disabled) {
throw new Error('Process is disabled');
}
if (this.isRunning()) {
this.status = LoaderStatus.PAUSED;
}
let /** @type {?} */ ev = this.getCustomEventObject(PAUSE_EVENT, null, null, null);
this.pauseEvent.emit(ev);
}
/**
* @return {?}
*/
resume() {
if (this.disabled) {
throw new Error('Process is disabled');
}
if (this.isPaused()) {
this.status = LoaderStatus.RUNNING;
}
let /** @type {?} */ taskName = null;
if (this.currentTask !== null) {
taskName = this.currentTask.getName();
}
let /** @type {?} */ ev = this.getCustomEventObject(RESUME_EVENT, taskName, null, null);
this.resumeEvent.emit(ev);
}
/**
* @return {?}
*/
stop() {
if (this.disabled) {
throw new Error('Process is disabled');
}
if (this.isRunning() || this.isPaused()) {
this.status = LoaderStatus.STOPPED;
}
let /** @type {?} */ taskName = null;
if (this.currentTask !== null) {
taskName = this.currentTask.getName();
}
let /** @type {?} */ ev = this.getCustomEventObject(STOP_EVENT, taskName, null, null);
this.stopEvent.emit(ev);
}
/**
* @return {?}
*/
getState() {
return this.status;
}
/**
* @return {?}
*/
isRunning() {
return this.status === LoaderStatus.RUNNING;
}
/**
* @return {?}
*/
isPaused() {
return this.status === LoaderStatus.PAUSED;
}
/**
* @return {?}
*/
isStopped() {
return this.status === LoaderStatus.STOPPED;
}
/**
* @return {?}
*/
getContinueOnReject() {
return this.continueOnReject;
}
/**
* @param {?} continueOnReject
* @return {?}
*/
setContinueOnReject(continueOnReject) {
if (this.isFirstStarted) {
throw new Error('Process was started or has been process');
}
this.continueOnReject = continueOnReject;
}
/**
* @return {?}
*/
getPercent() {
return this.percent;
}
/**
* @return {?}
*/
getTaskCount() {
return this.tasks.length;
}
/**
* @return {?}
*/
getName() {
return this.name;
}
/**
* @param {?} name
* @return {?}
*/
setName(name) {
this.name = name;
}
/**
* @return {?}
*/
getTaskStartEvent() {
return this.taskStartEvent;
}
/**
* @param {?} taskStartEvent
* @return {?}
*/
setTaskStartEvent(taskStartEvent) {
this.taskStartEvent = taskStartEvent;
}
/**
* @return {?}
*/
getTaskCompleteEvent() {
return this.taskCompleteEvent;
}
/**
* @param {?} taskCompleteEvent
* @return {?}
*/
setTaskCompleteEvent(taskCompleteEvent) {
this.taskCompleteEvent = taskCompleteEvent;
}
/**
* @return {?}
*/
getTaskResolveEvent() {
return this.taskResolveEvent;
}
/**
* @param {?} taskResolveEvent
* @return {?}
*/
setTaskResolveEvent(taskResolveEvent) {
this.taskResolveEvent = taskResolveEvent;
}
/**
* @return {?}
*/
getTaskRejectEvent() {
return this.taskRejectEvent;
}
/**
* @param {?} taskRejectEvent
* @return {?}
*/
setTaskRejectEvent(taskRejectEvent) {
this.taskRejectEvent = taskRejectEvent;
}
/**
* @return {?}
*/
getPauseEvent() {
return this.pauseEvent;
}
/**
* @param {?} pauseEvent
* @return {?}
*/
setPauseEvent(pauseEvent) {
this.pauseEvent = pauseEvent;
}
/**
* @return {?}
*/
getResumeEvent() {
return this.resumeEvent;
}
/**
* @param {?} resumeEvent
* @return {?}
*/
setResumeEvent(resumeEvent) {
this.resumeEvent = resumeEvent;
}
/**
* @return {?}
*/
getStartEvent() {
return this.startEvent;
}
/**
* @param {?} startEvent
* @return {?}
*/
setStartEvent(startEvent) {
this.startEvent = startEvent;
}
/**
* @return {?}
*/
getStopEvent() {
return this.stopEvent;
}
/**
* @param {?} stopEvent
* @return {?}
*/
setStopEvent(stopEvent) {
this.stopEvent = stopEvent;
}
}
function LoadProcess_tsickle_Closure_declarations() {
/** @type {?} */
LoadProcess.prototype.tasks;
/** @type {?} */
LoadProcess.prototype.disabled;
/** @type {?} */
LoadProcess.prototype.status;
/** @type {?} */
LoadProcess.prototype.successResult;
/** @type {?} */
LoadProcess.prototype.rejectResult;
/** @type {?} */
LoadProcess.prototype.continueOnReject;
/** @type {?} */
LoadProcess.prototype.isFirstStarted;
/** @type {?} */
LoadProcess.prototype.percent;
/** @type {?} */
LoadProcess.prototype.name;
/** @type {?} */
LoadProcess.prototype.currentTask;
/** @type {?} */
LoadProcess.prototype.taskStartEvent;
/** @type {?} */
LoadProcess.prototype.taskCompleteEvent;
/** @type {?} */
LoadProcess.prototype.taskResolveEvent;
/** @type {?} */
LoadProcess.prototype.taskRejectEvent;
/** @type {?} */
LoadProcess.prototype.pauseEvent;
/** @type {?} */
LoadProcess.prototype.resumeEvent;
/** @type {?} */
LoadProcess.prototype.startEvent;
/** @type {?} */
LoadProcess.prototype.stopEvent;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTG9hZFByb2Nlc3MuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9jb20ucGhsb3h1aS8iLCJzb3VyY2VzIjpbImxpYi9jb21wb25lbnQvTG9hZFByb2Nlc3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFHN0MsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDdkQsT0FBTyxFQUNMLGdCQUFnQixFQUFFLG1CQUFtQixFQUFFLGtCQUFrQixFQUFFLGlCQUFpQixFQUFFLFdBQVcsRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUNwSCxNQUFNLDBCQUEwQixDQUFDO0FBRWxDLE1BQU07Ozs7O0lBcUJKLFlBQVksSUFBWSxFQUFFLGdCQUEwQjtRQUNsRCxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUNqQixJQUFJLENBQUMsTUFBTSxHQUFHLFlBQVksQ0FBQyxPQUFPLENBQUM7UUFDbkMsSUFBSSxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUM7UUFDaEIsSUFBSSxDQUFDLGFBQWEsR0FBRyxFQUFFLENBQUM7UUFDeEIsSUFBSSxDQUFDLFlBQVksR0FBRyxFQUFFLENBQUM7UUFDdkIsSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUM7UUFDdEIsSUFBSSxDQUFDLGNBQWMsR0FBRyxLQUFLLENBQUM7UUFDNUIsSUFBSSxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUM7UUFDakIsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7UUFFeEIsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBQ3pDLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBQzVDLElB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LENBQUM7Ozs7OztJQUduQixjQUFjLENBQUMsV0FBOEI7UUFDbEQsSUFBSSxDQUFDLFdBQVcsR0FBRyxXQUFXLENBQUM7Ozs7O0lBRzFCLGFBQWE7UUFDbEIsTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUM7Ozs7OztJQUdsQixhQUFhLENBQUMsVUFBNkI7UUFDaEQsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7Ozs7O0lBR3hCLFlBQVk7UUFDakIsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUM7Ozs7OztJQUdqQixZQUFZLENBQUMsU0FBNEI7UUFDOUMsSUFBSSxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUM7O0NBRTlCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRXZlbnRFbWl0dGVyIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBJTG9hZGVyIH0gZnJvbSAnLi9JTG9hZGVyJztcbmltcG9ydCB7IElMb2FkVGFzayB9IGZyb20gJy4vSUxvYWRUYXNrJztcbmltcG9ydCB7IExvYWRlclN0YXR1cyB9IGZyb20gJy4vTG9hZGVyU3RhdHVzJztcbmltcG9ydCB7IERlZmF1bHRMb2FkVGFzayB9IGZyb20gJy4vRGVmYXVsdExvYWRUYXNrJztcbmltcG9ydCB7IEV2ZW50VXRpbHMgfSBmcm9tICcuLi9zaGFyZS91dGlscy9FdmVudFV0aWxzJztcbmltcG9ydCB7XG4gIFRBU0tfU1RBUlRfRVZFTlQsIFRBU0tfQ09NUExFVEVfRVZFTlQsIFRBU0tfUkVTT0xWRV9FVkVOVCwgVEFTS19SRUpFQ1RfRVZFTlQsIFBBVVNFX0VWRU5ULCBSRVNVTUVfRVZFTlQsIFNUT1BfRVZFTlRcbn0gZnJvbSAnLi4vc2hhcmUvQ3VzdG9tRXZlbnRUeXBlJztcblxuZXhwb3J0IGNsYXNzIExvYWRQcm9jZXNzIGltcGxlbWVudHMgSUxvYWRlciB7XG5cbiAgcHJpdmF0ZSB0YXNrczogSUxvYWRUYXNrW107XG4gIHByaXZhdGUgZGlzYWJsZWQ6IGJvb2xlYW47XG4gIHByaXZhdGUgc3RhdHVzOiBMb2FkZXJTdGF0dXM7XG4gIHByaXZhdGUgc3VjY2Vzc1Jlc3VsdDogYW55O1xuICBwcml2YXRlIHJlamVjdFJlc3VsdDogYW55O1xuICBwcml2YXRlIGNvbnRpbnVlT25SZWplY3Q6IGJvb2xlYW47XG4gIHByaXZhdGUgaXNGaXJzdFN0YXJ0ZWQ6IGJvb2xlYW47XG4gIHByaXZhdGUgcGVyY2VudDogbnVtYmVyO1xuICBwcml2YXRlIG5hbWU6IHN0cmluZztcbiAgcHJpdmF0ZSBjdXJyZW50VGFzazogSUxvYWRUYXNrO1xuICBwcml2YXRlIHRhc2tTdGFydEV2ZW50OiBFdmVudEVtaXR0ZXI8YW55PjtcbiAgcHJpdmF0ZSB0YXNrQ29tcGxldGVFdmVudDogRXZlbnRFbWl0dGVyPGFueT47XG4gIHByaXZhdGUgdGFza1Jlc29sdmVFdmVudDogRXZlbnRFbWl0dGVyPGFueT47XG4gIHByaXZhdGUgdGFza1JlamVjdEV2ZW50OiBFdmVudEVtaXR0ZXI8YW55PjtcbiAgcHJpdmF0ZSBwYXVzZUV2ZW50OiBFdmVudEVtaXR0ZXI8YW55PjtcbiAgcHJpdmF0ZSByZXN1bWVFdmVudDogRXZlbnRFbWl0dGVyPGFueT47XG4gIHByaXZhdGUgc3RhcnRFdmVudDogRXZlbnRFbWl0dGVyPGFueT47XG4gIHByaXZhdGUgc3RvcEV2ZW50OiBFdmVudEVtaXR0ZXI8YW55PjtcblxuICBjb25zdHJ1Y3RvcihuYW1lOiBzdHJpbmcsIGNvbnRpbnVlT25SZWplY3Q/OiBib29sZWFuKSB7XG4gICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICB0aGlzLnN0YXR1cyA9IExvYWRlclN0YXR1cy5TVE9QUEVEO1xuICAgIHRoaXMudGFza3MgPSBbXTtcbiAgICB0aGlzLnN1Y2Nlc3NSZXN1bHQgPSB7fTtcbiAgICB0aGlzLnJlamVjdFJlc3VsdCA9IHt9O1xuICAgIHRoaXMuZGlzYWJsZWQgPSBmYWxzZTtcbiAgICB0aGlzLmlzRmlyc3RTdGFydGVkID0gZmFsc2U7XG4gICAgdGhpcy5wZXJjZW50ID0gMDtcbiAgICB0aGlzLmN1cnJlbnRUYXNrID0gbnVsbDtcblxuICAgIHRoaXMudGFza1N0YXJ0RXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgdGhpcy50YXNrQ29tcGxldGVFdmVudCA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgICB0aGlzLnRhc2tSZXNvbHZlRXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgdGhpcy50YXNrUmVqZWN0RXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgdGhpcy5wYXVzZUV2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAgIHRoaXMucmVzdW1lRXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgdGhpcy5zdGFydEV2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAgIHRoaXMuc3RvcEV2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gICAgaWYgKGNvbnRpbnVlT25SZWplY3QgPT09IG51bGwgfHwgdHlwZW9mIGNvbnRpbnVlT25SZWplY3QgIT09ICdib29sZWFuJykge1xuICAgICAgdGhpcy5jb250aW51ZU9uUmVqZWN0ID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5jb250aW51ZU9uUmVqZWN0ID0gY29udGludWVPblJlamVjdDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZVBlcmNlbnQodGFza0NvdW50OiBudW1iZXIpOiB2b2lkIHtcbiAgICBsZXQgYWxsVGFzayA9ICh0aGlzLnRhc2tzLmxlbmd0aCA+IDApID8gdGhpcy50YXNrcy5sZW5ndGggOiAwO1xuICAgIGxldCBwZXJUYXNrID0gMDtcbiAgICBpZiAoYWxsVGFzayA+IDApIHtcbiAgICAgIHBlclRhc2sgPSAxMDAgLyBhbGxUYXNrO1xuICAgIH1cbiAgICBsZXQgdG90YWxQZXJjZW50ID0gdGFza0NvdW50ICogcGVyVGFzaztcblxuICAgIGlmICh0YXNrQ291bnQgPT09IGFsbFRhc2spIHtcbiAgICAgIHRvdGFsUGVyY2VudCA9IDEwMDtcbiAgICB9XG5cbiAgICB0aGlzLnBlcmNlbnQgPSB0b3RhbFBlcmNlbnQ7XG4gIH1cblxuICBwcml2YXRlIGdldFJlc3VsdE9iamVjdCgpOiBhbnkge1xuICAgIGxldCByZXN1bHQ6IGFueSA9IHtcbiAgICAgIHN1Y2Nlc3M6IHRoaXMuc3VjY2Vzc1Jlc3VsdCxcbiAgICAgIGVycm9yOiB0aGlzLnJlamVjdFJlc3VsdFxuICAgIH07XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRDdXN0b21FdmVudE9iamVjdCh0eXBlOiBhbnksIG5hbWU6IGFueSwgc3VjY2VzczogYW55LCBlcnJvcjogYW55KTogYW55IHtcbiAgICBsZXQgc3VjY2Vzc0NvdW50ID0gT2JqZWN0LmtleXModGhpcy5zdWNjZXNzUmVzdWx0KS5sZW5ndGg7XG4gICAgbGV0IGVycm9yQ291bnQgPSBPYmplY3Qua2V5cyh0aGlzLnJlamVjdFJlc3VsdCkubGVuZ3RoO1xuXG4gICAgbGV0IHdyYXBEYXRhID0ge1xuICAgICAgbmFtZTogbmFtZSxcbiAgICAgIHN1Y2Nlc3M6IHN1Y2Nlc3MsXG4gICAgICBlcnJvcjogZXJyb3IsXG4gICAgICBwZXJjZW50OiB0aGlzLnBlcmNlbnQsXG4gICAgICB0b3RhbENvdW50OiB0aGlzLnRhc2tzLmxlbmd0aCxcbiAgICAgIHByb2Nlc3NlZDogc3VjY2Vzc0NvdW50ICsgZXJyb3JDb3VudCxcbiAgICAgIHN1Y2Nlc3NDb3VudDogc3VjY2Vzc0NvdW50LFxuICAgICAgZXJyb3JDb3VudDogZXJyb3JDb3VudFxuICAgIH07XG4gICAgbGV0IGV2ID0gRXZlbnRVdGlscy5uZXdDdXN0b21FdmVudCh0eXBlLCBudWxsLCB3cmFwRGF0YSwgbnVsbCk7XG5cbiAgICByZXR1cm4gZXY7XG4gIH1cblxuICBwcml2YXRlIHdyYXBQcm9taXNlKGluZGV4OiBudW1iZXIpOiBQcm9taXNlPGFueT4ge1xuICAgIGlmIChpbmRleCA8PSAtMSB8fCBpbmRleCA+PSB0aGlzLnRhc2tzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmlzU3RvcHBlZCgpKSB7XG4gICAgICBsZXQgcmVzdWx0ID0ge1xuICAgICAgICBsb2FkU3RhdHVzOiBMb2FkZXJTdGF0dXMuU1RPUFBFRCxcbiAgICAgICAgaW5kZXg6IGluZGV4XG4gICAgICB9O1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KHJlc3VsdCk7XG4gICAgfVxuXG4gICAgaWYgKGluZGV4ID49IHRoaXMudGFza3MubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG51bGwpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmlzUGF1c2VkKCkpIHtcbiAgICAgIHJldHVybiB0aGlzLmRlbGF5UHJvbWlzZShQcm9taXNlLnJlc29sdmUoKSwgNTAwKS50aGVuKChyZXN1bHQ6IGFueSkgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy53cmFwUHJvbWlzZShpbmRleCk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBsZXQgY3VycmVudFJlc3VsdCA9IHRoaXMuZ2V0UmVzdWx0T2JqZWN0KCk7XG5cbiAgICB0aGlzLmN1cnJlbnRUYXNrID0gdGhpcy50YXNrc1tpbmRleF07XG4gICAgbGV0IHRhc2tOYW1lID0gdGhpcy5jdXJyZW50VGFzay5nZXROYW1lKCk7XG4gICAgbGV0IGNvbXBFdiA9IHRoaXMuZ2V0Q3VzdG9tRXZlbnRPYmplY3QoVEFTS19TVEFSVF9FVkVOVCwgdGFza05hbWUsIG51bGwsIG51bGwpO1xuICAgIHRoaXMudGFza1N0YXJ0RXZlbnQuZW1pdChjb21wRXYpO1xuXG4gICAgbGV0IGV4ZVByb206IFByb21pc2U8YW55PiA9IG51bGw7XG5cbiAgICB0cnkge1xuICAgICAgZXhlUHJvbSA9IHRoaXMudGFza3NbaW5kZXhdLmV4ZWN1dGUoY3VycmVudFJlc3VsdCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgZXhlUHJvbSA9IFByb21pc2UucmVqZWN0KGUpO1xuICAgIH1cblxuICAgIHJldHVybiBleGVQcm9tLnRoZW4oKHJlc3VsdDogYW55KSA9PiB7XG4gICAgICB0aGlzLnN1Y2Nlc3NSZXN1bHRbdGFza05hbWVdID0gcmVzdWx0O1xuXG4gICAgICAvLyB1cGRhdGUgcGVyY2VudFxuICAgICAgdGhpcy51cGRhdGVQZXJjZW50KGluZGV4ICsgMSk7XG5cbiAgICAgIC8vIGVtaXQgY29tcGxldGUgZXZlbnRcbiAgICAgIGxldCBldiA9IHRoaXMuZ2V0Q3VzdG9tRXZlbnRPYmplY3QoVEFTS19SRVNPTFZFX0VWRU5ULCB0YXNrTmFtZSwgcmVzdWx0LCBudWxsKTtcbiAgICAgIHRoaXMudGFza1Jlc29sdmVFdmVudC5lbWl0KGV2KTtcbiAgICAgIGxldCBjb21wRXYgPSB0aGlzLmdldEN1c3RvbUV2ZW50T2JqZWN0KFRBU0tfQ09NUExFVEVfRVZFTlQsIHRhc2tOYW1lLCByZXN1bHQsIG51bGwpO1xuICAgICAgdGhpcy50YXNrQ29tcGxldGVFdmVudC5lbWl0KGNvbXBFdik7XG5cbiAgICAgIHRoaXMuY3VycmVudFRhc2sgPSBudWxsO1xuXG4gICAgICByZXR1cm4gdGhpcy53cmFwUHJvbWlzZSgrK2luZGV4KTtcbiAgICB9LCAocmVqUmVzdWx0OiBhbnkpID0+IHtcbiAgICAgIGlmIChyZWpSZXN1bHQgIT09IG51bGwgJiYgcmVqUmVzdWx0ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBpZiAocmVqUmVzdWx0LmxvYWRTdGF0dXMgIT09IExvYWRlclN0YXR1cy5TVE9QUEVEKSB7XG4gICAgICAgICAgLy8gdGhpcyBpcyByZWFsIHJlamVjdCByZXN1bHRcbiAgICAgICAgICBsZXQgdGFza05hbWUgPSB0aGlzLnRhc2tzW2luZGV4XS5nZXROYW1lKCk7XG4gICAgICAgICAgdGhpcy5yZWplY3RSZXN1bHRbdGFza05hbWVdID0gcmVqUmVzdWx0O1xuXG4gICAgICAgICAgLy8gY29udGludWUgdG8gbmV4dCBwcm9taXNlXG4gICAgICAgICAgaWYgKHRoaXMuY29udGludWVPblJlamVjdCkge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVQZXJjZW50KGluZGV4ICsgMSk7XG5cbiAgICAgICAgICAgIC8vIGVtaXQgY29tcGxhdGVkIGV2ZW50XG4gICAgICAgICAgICBsZXQgZXYgPSB0aGlzLmdldEN1c3RvbUV2ZW50T2JqZWN0KFRBU0tfUkVKRUNUX0VWRU5ULCB0YXNrTmFtZSwgbnVsbCwgcmVqUmVzdWx0KTtcbiAgICAgICAgICAgIHRoaXMudGFza1JlamVjdEV2ZW50LmVtaXQoZXYpO1xuICAgICAgICAgICAgbGV0IGNvbXBFdiA9IHRoaXMuZ2V0Q3VzdG9tRXZlbnRPYmplY3QoVEFTS19DT01QTEVURV9FVkVOVCwgdGFza05hbWUsIG51bGwsIHJlalJlc3VsdCk7XG4gICAgICAgICAgICB0aGlzLnRhc2tDb21wbGV0ZUV2ZW50LmVtaXQoY29tcEV2KTtcblxuICAgICAgICAgICAgdGhpcy5jdXJyZW50VGFzayA9IG51bGw7XG5cbiAgICAgICAgICAgIHJldHVybiB0aGlzLndyYXBQcm9taXNlKCsraW5kZXgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyB0aGF0IG1lYW4gbm90IGNvbnRpbnVlIHRvIG5leHQgcHJvbWlzZVxuICAgICAgaWYgKHJlalJlc3VsdC5sb2FkU3RhdHVzICE9PSBMb2FkZXJTdGF0dXMuU1RPUFBFRCkge1xuICAgICAgICB0aGlzLnVwZGF0ZVBlcmNlbnQoaW5kZXggKyAxKTtcblxuICAgICAgICBsZXQgZXYgPSB0aGlzLmdldEN1c3RvbUV2ZW50T2JqZWN0KFRBU0tfUkVKRUNUX0VWRU5ULCB0YXNrTmFtZSwgbnVsbCwgcmVqUmVzdWx0KTtcbiAgICAgICAgdGhpcy50YXNrUmVqZWN0RXZlbnQuZW1pdChldik7XG4gICAgICAgIGxldCBjb21wRXYgPSB0aGlzLmdldEN1c3RvbUV2ZW50T2JqZWN0KFRBU0tfQ09NUExFVEVfRVZFTlQsIHRhc2tOYW1lLCBudWxsLCByZWpSZXN1bHQpO1xuICAgICAgICB0aGlzLnRhc2tDb21wbGV0ZUV2ZW50LmVtaXQoY29tcEV2KTtcblxuICAgICAgICB0aGlzLmN1cnJlbnRUYXNrID0gbnVsbDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KHJlalJlc3VsdCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGRlbGF5UHJvbWlzZShwcm9tOiBQcm9taXNlPGFueT4sIGRlbGF5TVM6IG51bWJlcik6IFByb21pc2U8YW55PiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICByZXNvbHZlKCk7XG4gICAgICB9LCBkZWxheU1TKTtcbiAgICB9KS50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiBwcm9tO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFkZChuYW1lOiBzdHJpbmcsIHRhc2tGdW5jOiBGdW5jdGlvbik6IExvYWRQcm9jZXNzIHtcbiAgICBpZiAodGhpcy5pc0ZpcnN0U3RhcnRlZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdQcm9jZXNzIHdhcyBzdGFydGVkIG9yIGhhcyBiZWVuIHByb2Nlc3MnKTtcbiAgICB9XG5cbiAgICB0aGlzLnRhc2tzLnB1c2gobmV3IERlZmF1bHRMb2FkVGFzayhuYW1lLCB0YXNrRnVuYykpO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBwdWJsaWMgYWRkVGFzayh0YXNrOiBJTG9hZFRhc2spOiBMb2FkUHJvY2VzcyB7XG4gICAgaWYgKHRoaXMuaXNGaXJzdFN0YXJ0ZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUHJvY2VzcyB3YXMgc3RhcnRlZCBvciBoYXMgYmVlbiBwcm9jZXNzJyk7XG4gICAgfVxuXG4gICAgaWYgKHRhc2sgIT09IG51bGwgJiYgdGFzayAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLnRhc2tzLnB1c2godGFzayk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBwdWJsaWMgcmVtb3ZlVGFzayh0YXNrOiBJTG9hZFRhc2spOiBMb2FkUHJvY2VzcyB7XG4gICAgaWYgKHRoaXMuaXNGaXJzdFN0YXJ0ZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUHJvY2VzcyB3YXMgc3RhcnRlZCBvciBoYXMgYmVlbiBwcm9jZXNzJyk7XG4gICAgfVxuXG4gICAgbGV0IGluZGV4ID0gdGhpcy50YXNrcy5pbmRleE9mKHRhc2spO1xuICAgIHJldHVybiB0aGlzLnJlbW92ZShpbmRleCk7XG4gIH1cblxuICBwdWJsaWMgcmVtb3ZlKGluZGV4OiBudW1iZXIpOiBMb2FkUHJvY2VzcyB7XG4gICAgaWYgKHRoaXMuaXNGaXJzdFN0YXJ0ZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUHJvY2VzcyB3YXMgc3RhcnRlZCBvciBoYXMgYmVlbiBwcm9jZXNzJyk7XG4gICAgfVxuXG4gICAgaWYgKGluZGV4IDwgdGhpcy50YXNrcy5sZW5ndGgpIHtcbiAgICAgIHRoaXMudGFza3Muc3BsaWNlKGluZGV4LCAxKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIGlmIGlzRGlzYWJsZSBhbGwgYWN0aW9uXG4gIHB1YmxpYyBzZXREaXNhYmxlZChkaXNhYmxlZDogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMuZGlzYWJsZWQgPSBkaXNhYmxlZDtcbiAgfVxuXG4gIHB1YmxpYyBpc0Rpc2FibGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmRpc2FibGVkO1xuICB9XG5cbiAgcHVibGljIHN0YXJ0KCk6IFByb21pc2U8YW55PiB7XG4gICAgaWYgKHRoaXMuZGlzYWJsZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUHJvY2VzcyBpcyBkaXNhYmxlZCcpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmlzRmlyc3RTdGFydGVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Byb2Nlc3Mgd2FzIHN0YXJ0ZWQgb3IgaGFzIGJlZW4gcHJvY2VzcycpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmlzU3RvcHBlZCgpKSB7XG4gICAgICB0aGlzLnN0YXR1cyA9IExvYWRlclN0YXR1cy5SVU5OSU5HO1xuXG4gICAgICB0aGlzLmlzRmlyc3RTdGFydGVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICAvLyBwcm9taXNlIHN0YXJ0XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMud3JhcFByb21pc2UoMCkudGhlbigocmVzdWx0OiBhbnkpID0+IHtcbiAgICAgICAgbGV0IHJlc29sdmVSZXN1bHQ6IGFueSA9IHRoaXMuZ2V0UmVzdWx0T2JqZWN0KCk7XG5cbiAgICAgICAgcmVzb2x2ZShyZXNvbHZlUmVzdWx0KTtcbiAgICAgIH0sIChyZWplY3RSZXN1bHQ6IGFueSkgPT4ge1xuICAgICAgICBsZXQgcmVzb2x2ZVJlc3VsdDogYW55ID0gdGhpcy5nZXRSZXN1bHRPYmplY3QoKTtcblxuICAgICAgICBpZiAocmVqZWN0UmVzdWx0ICE9PSBudWxsICYmIHJlamVjdFJlc3VsdCAhPT0gdW5kZWZpbmVkICYmIHJlamVjdFJlc3VsdC5sb2FkU3RhdHVzID09PSBMb2FkZXJTdGF0dXMuU1RPUFBFRCkge1xuICAgICAgICAgIC8vIGJyZWFrIGZvciBTVE9QIHN0YXR1c1xuICAgICAgICAgIHJlc29sdmUocmVzb2x2ZVJlc3VsdCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKHRoaXMuY29udGludWVPblJlamVjdCkge1xuICAgICAgICAgICAgLy8gcmVzb2x2ZSB3aGF0ZXZlciByZWplY3RlZFxuICAgICAgICAgICAgcmVzb2x2ZShyZXNvbHZlUmVzdWx0KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gcmVqZWN0IGlmIGFueSBvZiByZWplY3Qgd2FzIGZvdW5kXG4gICAgICAgICAgICByZWplY3QocmVzb2x2ZVJlc3VsdCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBwYXVzZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5kaXNhYmxlZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdQcm9jZXNzIGlzIGRpc2FibGVkJyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaXNSdW5uaW5nKCkpIHtcbiAgICAgIHRoaXMuc3RhdHVzID0gTG9hZGVyU3RhdHVzLlBBVVNFRDtcbiAgICB9XG5cbiAgICBsZXQgZXYgPSB0aGlzLmdldEN1c3RvbUV2ZW50T2JqZWN0KFBBVVNFX0VWRU5ULCBudWxsLCBudWxsLCBudWxsKTtcbiAgICB0aGlzLnBhdXNlRXZlbnQuZW1pdChldik7XG4gIH1cblxuICBwdWJsaWMgcmVzdW1lKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmRpc2FibGVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Byb2Nlc3MgaXMgZGlzYWJsZWQnKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5pc1BhdXNlZCgpKSB7XG4gICAgICB0aGlzLnN0YXR1cyA9IExvYWRlclN0YXR1cy5SVU5OSU5HO1xuICAgIH1cblxuICAgIGxldCB0YXNrTmFtZSA9IG51bGw7XG4gICAgaWYgKHRoaXMuY3VycmVudFRhc2sgIT09IG51bGwpIHtcbiAgICAgIHRhc2tOYW1lID0gdGhpcy5jdXJyZW50VGFzay5nZXROYW1lKCk7XG4gICAgfVxuXG4gICAgbGV0IGV2ID0gdGhpcy5nZXRDdXN0b21FdmVudE9iamVjdChSRVNVTUVfRVZFTlQsIHRhc2tOYW1lLCBudWxsLCBudWxsKTtcbiAgICB0aGlzLnJlc3VtZUV2ZW50LmVtaXQoZXYpO1xuICB9XG5cbiAgcHVibGljIHN0b3AoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZGlzYWJsZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUHJvY2VzcyBpcyBkaXNhYmxlZCcpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmlzUnVubmluZygpIHx8IHRoaXMuaXNQYXVzZWQoKSkge1xuICAgICAgdGhpcy5zdGF0dXMgPSBMb2FkZXJTdGF0dXMuU1RPUFBFRDtcbiAgICB9XG5cbiAgICBsZXQgdGFza05hbWUgPSBudWxsO1xuICAgIGlmICh0aGlzLmN1cnJlbnRUYXNrICE9PSBudWxsKSB7XG4gICAgICB0YXNrTmFtZSA9IHRoaXMuY3VycmVudFRhc2suZ2V0TmFtZSgpO1xuICAgIH1cblxuICAgIGxldCBldiA9IHRoaXMuZ2V0Q3VzdG9tRXZlbnRPYmplY3QoU1RPUF9FVkVOVCwgdGFza05hbWUsIG51bGwsIG51bGwpO1xuICAgIHRoaXMuc3RvcEV2ZW50LmVtaXQoZXYpO1xuICB9XG5cbiAgcHVibGljIGdldFN0YXRlKCk6IExvYWRlclN0YXR1cyB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdHVzO1xuICB9XG5cbiAgcHVibGljIGlzUnVubmluZygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0dXMgPT09IExvYWRlclN0YXR1cy5SVU5OSU5HO1xuICB9XG5cbiAgcHVibGljIGlzUGF1c2VkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnN0YXR1cyA9PT0gTG9hZGVyU3RhdHVzLlBBVVNFRDtcbiAgfVxuXG4gIHB1YmxpYyBpc1N0b3BwZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdHVzID09PSBMb2FkZXJTdGF0dXMuU1RPUFBFRDtcbiAgfVxuXG4gIHB1YmxpYyBnZXRDb250aW51ZU9uUmVqZWN0KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmNvbnRpbnVlT25SZWplY3Q7XG4gIH1cblxuICBwdWJsaWMgc2V0Q29udGludWVPblJlamVjdChjb250aW51ZU9uUmVqZWN0OiBib29sZWFuKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNGaXJzdFN0YXJ0ZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUHJvY2VzcyB3YXMgc3RhcnRlZCBvciBoYXMgYmVlbiBwcm9jZXNzJyk7XG4gICAgfVxuXG4gICAgdGhpcy5jb250aW51ZU9uUmVqZWN0ID0gY29udGludWVPblJlamVjdDtcbiAgfVxuXG4gIHB1YmxpYyBnZXRQZXJjZW50KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMucGVyY2VudDtcbiAgfVxuXG4gIHB1YmxpYyBnZXRUYXNrQ291bnQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy50YXNrcy5sZW5ndGg7XG4gIH1cblxuICBwdWJsaWMgZ2V0TmFtZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLm5hbWU7XG4gIH1cblxuICBwdWJsaWMgc2V0TmFtZShuYW1lOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICB9XG5cbiAgcHVibGljIGdldFRhc2tTdGFydEV2ZW50KCk6IEV2ZW50RW1pdHRlcjxhbnk+IHtcbiAgICByZXR1cm4gdGhpcy50YXNrU3RhcnRFdmVudDtcbiAgfVxuXG4gIHB1YmxpYyBzZXRUYXNrU3RhcnRFdmVudCh0YXNrU3RhcnRFdmVudDogRXZlbnRFbWl0dGVyPGFueT4pOiB2b2lkIHtcbiAgICB0aGlzLnRhc2tTdGFydEV2ZW50ID0gdGFza1N0YXJ0RXZlbnQ7XG4gIH1cblxuICBwdWJsaWMgZ2V0VGFza0NvbXBsZXRlRXZlbnQoKTogRXZlbnRFbWl0dGVyPGFueT4ge1xuICAgIHJldHVybiB0aGlzLnRhc2tDb21wbGV0ZUV2ZW50O1xuICB9XG5cbiAgcHVibGljIHNldFRhc2tDb21wbGV0ZUV2ZW50KHRhc2tDb21wbGV0ZUV2ZW50OiBFdmVudEVtaXR0ZXI8YW55Pik6IHZvaWQge1xuICAgIHRoaXMudGFza0NvbXBsZXRlRXZlbnQgPSB0YXNrQ29tcGxldGVFdmVudDtcbiAgfVxuXG4gIHB1YmxpYyBnZXRUYXNrUmVzb2x2ZUV2ZW50KCk6IEV2ZW50RW1pdHRlcjxhbnk+IHtcbiAgICByZXR1cm4gdGhpcy50YXNrUmVzb2x2ZUV2ZW50O1xuICB9XG5cbiAgcHVibGljIHNldFRhc2tSZXNvbHZlRXZlbnQodGFza1Jlc29sdmVFdmVudDogRXZlbnRFbWl0dGVyPGFueT4pOiB2b2lkIHtcbiAgICB0aGlzLnRhc2tSZXNvbHZlRXZlbnQgPSB0YXNrUmVzb2x2ZUV2ZW50O1xuICB9XG5cbiAgcHVibGljIGdldFRhc2tSZWplY3RFdmVudCgpOiBFdmVudEVtaXR0ZXI8YW55PiB7XG4gICAgcmV0dXJuIHRoaXMudGFza1JlamVjdEV2ZW50O1xuICB9XG5cbiAgcHVibGljIHNldFRhc2tSZWplY3RFdmVudCh0YXNrUmVqZWN0RXZlbnQ6IEV2ZW50RW1pdHRlcjxhbnk+KTogdm9pZCB7XG4gICAgdGhpcy50YXNrUmVqZWN0RXZlbnQgPSB0YXNrUmVqZWN0RXZlbnQ7XG4gIH1cblxuICBwdWJsaWMgZ2V0UGF1c2VFdmVudCgpOiBFdmVudEVtaXR0ZXI8YW55PiB7XG4gICAgcmV0dXJuIHRoaXMucGF1c2VFdmVudDtcbiAgfVxuXG4gIHB1YmxpYyBzZXRQYXVzZUV2ZW50KHBhdXNlRXZlbnQ6IEV2ZW50RW1pdHRlcjxhbnk+KTogdm9pZCB7XG4gICAgdGhpcy5wYXVzZUV2ZW50ID0gcGF1c2VFdmVudDtcbiAgfVxuXG4gIHB1YmxpYyBnZXRSZXN1bWVFdmVudCgpOiBFdmVudEVtaXR0ZXI8YW55PiB7XG4gICAgcmV0dXJuIHRoaXMucmVzdW1lRXZlbnQ7XG4gIH1cblxuICBwdWJsaWMgc2V0UmVzdW1lRXZlbnQocmVzdW1lRXZlbnQ6IEV2ZW50RW1pdHRlcjxhbnk+KTogdm9pZCB7XG4gICAgdGhpcy5yZXN1bWVFdmVudCA9IHJlc3VtZUV2ZW50O1xuICB9XG5cbiAgcHVibGljIGdldFN0YXJ0RXZlbnQoKTogRXZlbnRFbWl0dGVyPGFueT4ge1xuICAgIHJldHVybiB0aGlzLnN0YXJ0RXZlbnQ7XG4gIH1cblxuICBwdWJsaWMgc2V0U3RhcnRFdmVudChzdGFydEV2ZW50OiBFdmVudEVtaXR0ZXI8YW55Pik6IHZvaWQge1xuICAgIHRoaXMuc3RhcnRFdmVudCA9IHN0YXJ0RXZlbnQ7XG4gIH1cblxuICBwdWJsaWMgZ2V0U3RvcEV2ZW50KCk6IEV2ZW50RW1pdHRlcjxhbnk+IHtcbiAgICByZXR1cm4gdGhpcy5zdG9wRXZlbnQ7XG4gIH1cblxuICBwdWJsaWMgc2V0U3RvcEV2ZW50KHN0b3BFdmVudDogRXZlbnRFbWl0dGVyPGFueT4pOiB2b2lkIHtcbiAgICB0aGlzLnN0b3BFdmVudCA9IHN0b3BFdmVudDtcbiAgfVxufVxuIl19