@synerty/vortexjs
Version:
Custom observable data serialisation and routing based on Angular 2+
246 lines • 40.3 kB
JavaScript
import { Tuple } from "../Tuple";
import { TupleSelector } from "../TupleSelector";
import { distinctUntilChanged, skip, takeUntil } from "rxjs/operators";
import { dateStr } from "../UtilMisc";
import { _DataLoaderActionType, _DataLoaderTupleAction, _DataLockStatusTuple, _LockDataTupleAction, } from "./TupleDataLoaderTuples";
/*
* The `TupleDataLoader` class manages the observable and action push service for
* the data loaders. Delegates for each form need to be registered with the data
* loader using the `setDelegate` method.
*
* The `TupleDataLoader` can be instantiated in a `Component` or `Service` and
* takes in an `EventEmitter<string>` event which notifies when to unsubscribe
* to the subscriptions' setup by the loader
* */
export class TupleDataLoader {
ngLifeCycleEvents;
action;
observer;
delegateByUuidByTupleType = {};
constructor(ngLifeCycleEvents, action, observer) {
this.ngLifeCycleEvents = ngLifeCycleEvents;
this.action = action;
this.observer = observer;
}
delegateByUuid(tupleType, create = false) {
if (this.delegateByUuidByTupleType[tupleType] != null) {
return this.delegateByUuidByTupleType[tupleType];
}
if (!create) {
return null;
}
const newDict = {};
this.delegateByUuidByTupleType[tupleType] = newDict;
return newDict;
}
/*
* The `setDelegate` method registers a data `tuple` to be handled by the
* `delegate`.
* */
removeDelegate(tuple, delegate) {
const tupleType = tuple instanceof Tuple ? tuple._tupleType : tuple;
if ((this.delegateByUuid(tupleType) || {})[delegate.uuid] == null) {
throw new Error(`removeDelegate: Delegate with UUID ${delegate.uuid}` +
` and tuple type ${tupleType}` +
` does not exist`);
}
delete this.delegateByUuidByTupleType[tupleType][delegate.uuid];
}
/*
* The `setDelegate` method registers a data `tuple` to be handled by the
* `delegate`.
* */
addDelegate(tuple, delegate, destroyEvent) {
const tupleType = tuple instanceof Tuple ? tuple._tupleType : tuple;
if ((this.delegateByUuid(tupleType) || {})[delegate.uuid] != null) {
throw new Error(`addDelegate: Delegate with UUID ${delegate.uuid}` +
` and tuple type ${tupleType}` +
` already exists`);
}
this.delegateByUuid(tupleType, true)[delegate.uuid] = delegate;
delegate["setDataLoader"](this);
delegate["registeredName"] = tupleType;
destroyEvent.onDestroyEvent.subscribe(() => this.removeDelegate(tuple, delegate));
const distinctSelector$ = delegate.selector$.pipe(distinctUntilChanged((s1, s2) => s1?.toOrderedJsonStr() === s2?.toOrderedJsonStr()));
distinctSelector$
.pipe(takeUntil(this.ngLifeCycleEvents.onDestroyEvent))
.subscribe((selector) => {
if (selector == null) {
return;
}
if (tupleType != selector.name) {
console.log("TupleDataLoader: distinctSelector$ Selector and" +
" data missmatch" +
` tupleType=${tupleType}` +
` vs selector.name=${selector.name}`);
return;
}
console.log("TupleDataLoader: distinctSelector$ Observed selector$" +
" change" +
` refreshing ${selector.toOrderedJsonStr()}`);
const selectorChangePipe = distinctSelector$.pipe(skip(1));
this.observer
.subscribeToTupleSelector(selector)
.pipe(takeUntil(this.ngLifeCycleEvents.onDestroyEvent), takeUntil(selectorChangePipe))
.subscribe((tuples) => {
if (tuples.length > 0) {
console.log("TupleDataLoader:" +
" distinctSelector$ tupleObserver," +
" TupleDataLoaderTupleABC received from server," +
` selector: ${selector.toOrderedJsonStr()}`);
delegate["processDataUpdate"](tuples[0]);
}
});
// The locking tuple selector uses the _DataLockStatusTuple and
// the tuple selector for the form.
this.observer
.subscribeToTupleSelector(new TupleSelector(_DataLockStatusTuple.tupleType, {
dataTupleSelector: selector,
}))
.pipe(takeUntil(this.ngLifeCycleEvents.onDestroyEvent), takeUntil(selectorChangePipe))
.subscribe((tuples) => {
if (tuples.length > 0) {
console.log("TupleDataLoader:" +
" distinctSelector$ tupleObserver," +
" _DataLockStatusTuple received from server," +
` selector: ${selector.toOrderedJsonStr()}`);
delegate["processLockStatus"](tuples[0]);
}
});
});
}
/*
* The `store` method will save the data by calling the `writeData` method
* of the registered delegate in the backend code. It will also release any
* locks on this form and discard the live value.
* */
async create(delegate) {
const data = delegate.data;
const tupleType = data._tupleName();
if ((this.delegateByUuid(tupleType) || {})[delegate.uuid] == null) {
console.log(`${dateStr()} CREATE Delegate with UUID ${delegate.uuid}` +
` not registered for tupleType ${tupleType}`);
return;
}
if (data == null) {
return;
}
const action = new _DataLoaderTupleAction();
action.userUuid = delegate["userUuid$"].getValue();
action.delegateUuid = delegate.uuid;
action.dataTuple = data;
action.action = _DataLoaderActionType.Create;
// noinspection JSUnusedLocalSymbols
const response = this.convertResponse(await this.action.pushAction(action));
delegate.selector$.next(response.tupleDataSelector);
}
/*
* The `store` method will save the data by calling the `writeData` method
* of the registered delegate in the backend code. It will also release any
* locks on this form and discard the live value.
* */
async store(delegate) {
const data = delegate.data;
const selector = delegate.selector;
const tupleType = selector.name;
if ((this.delegateByUuid(tupleType) || {})[delegate.uuid] == null) {
console.log(`${dateStr()} STORE Delegate with UUID ${delegate.uuid}` +
` not registered for tupleType ${tupleType}`);
return;
}
if (data == null || selector == null) {
return;
}
const action = new _DataLoaderTupleAction();
action.userUuid = delegate["userUuid$"].getValue();
action.delegateUuid = delegate.uuid;
action.dataTuple = data;
action.action = _DataLoaderActionType.Store;
action.tupleDataSelector = selector;
// noinspection JSUnusedLocalSymbols
const response = this.convertResponse(await this.action.pushAction(action));
// If there is a TupleSelector update, apply it.
if (response.tupleDataSelector != null) {
delegate.selector$.next(response.tupleDataSelector);
}
}
/*
* The `load` method will load the data using the `readData` method of the
* registered delegate in the backend. It will discard any live values and
* also release the locks.
* */
async load(delegate) {
const selector = delegate.selector;
const tupleType = selector.name;
if ((this.delegateByUuid(tupleType) || {})[delegate.uuid] == null) {
console.log(`${dateStr()} LOAD Delegate with UUID ${delegate.uuid}` +
` not registered for tupleType ${tupleType}`);
return;
}
if (selector == null) {
throw new Error("TupleSelector not set to load data");
}
const action = new _DataLoaderTupleAction();
// This does not matter for revert
action.userUuid = delegate["userUuid$"].getValue();
action.delegateUuid = delegate.uuid;
action.dataTuple = delegate.data;
action.action = _DataLoaderActionType.Load;
action.tupleDataSelector = selector;
// noinspection JSUnusedLocalSymbols
const response = this.convertResponse(await this.action.pushAction(action));
}
/*
* The `delete` method will call `deleteData` method of the registered
* delegate in the backend code
* */
async delete(delegate) {
const data = delegate.data;
const selector = delegate.selector;
const tupleType = selector.name;
if ((this.delegateByUuid(tupleType) || {})[delegate.uuid] == null) {
console.log(`${dateStr()} DELETE Delegate with UUID ${delegate.uuid}` +
` not registered for tupleType ${tupleType}`);
return;
}
if (selector == null) {
throw new Error("TupleSelector not set to delete data");
}
const action = new _DataLoaderTupleAction();
// This does not matter for delete
action.userUuid = delegate["userUuid$"].getValue();
action.delegateUuid = delegate.uuid;
action.dataTuple = delegate.data;
action.action = _DataLoaderActionType.Delete;
action.tupleDataSelector = selector;
// noinspection JSUnusedLocalSymbols
const response = this.convertResponse(await this.action.pushAction(action));
}
/*
* The `lock` method will acquire a lock on the data or throw an exception
* if the lock is already held by someone else on the current tuple selector
* */
async lock(delegate) {
const selector = delegate.selector;
const tupleType = selector.name;
if ((this.delegateByUuid(tupleType) || {})[delegate.uuid] == null) {
console.log(`${dateStr()} LOCK Delegate with UUID ${delegate.uuid}` +
` not registered for tupleType ${tupleType}`);
return;
}
if (selector == null) {
throw new Error("TupleSelector not set to lock form for");
}
const action = new _LockDataTupleAction();
action.delegateUuid = delegate.uuid;
action.userUuid = delegate["userUuid$"].getValue();
action.lock = true;
action.tupleDataSelector = selector;
action.liveUpdateDataTuple = delegate.data;
await this.action.pushAction(action);
}
convertResponse(tuples) {
return tuples[0];
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVHVwbGVEYXRhTG9hZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL3ZvcnRleC9kYXRhLWxvYWRlci9UdXBsZURhdGFMb2FkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBR0EsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUNqQyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDakQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN2RSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBTXRDLE9BQU8sRUFDSCxxQkFBcUIsRUFDckIsc0JBQXNCLEVBRXRCLG9CQUFvQixFQUNwQixvQkFBb0IsR0FDdkIsTUFBTSx5QkFBeUIsQ0FBQztBQUtqQzs7Ozs7Ozs7S0FRSztBQUNMLE1BQU0sT0FBTyxlQUFlO0lBSVo7SUFDUztJQUNBO0lBTGIseUJBQXlCLEdBQStCLEVBQUUsQ0FBQztJQUVuRSxZQUNZLGlCQUFvQyxFQUMzQixNQUE4QixFQUM5QixRQUFrQztRQUYzQyxzQkFBaUIsR0FBakIsaUJBQWlCLENBQW1CO1FBQzNCLFdBQU0sR0FBTixNQUFNLENBQXdCO1FBQzlCLGFBQVEsR0FBUixRQUFRLENBQTBCO0lBQ3BELENBQUM7SUFFSSxjQUFjLENBQ2xCLFNBQWlCLEVBQ2pCLE1BQU0sR0FBRyxLQUFLO1FBRWQsSUFBSSxJQUFJLENBQUMseUJBQXlCLENBQUMsU0FBUyxDQUFDLElBQUksSUFBSSxFQUFFO1lBQ25ELE9BQU8sSUFBSSxDQUFDLHlCQUF5QixDQUFDLFNBQVMsQ0FBQyxDQUFDO1NBQ3BEO1FBQ0QsSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNULE9BQU8sSUFBSSxDQUFDO1NBQ2Y7UUFDRCxNQUFNLE9BQU8sR0FBb0IsRUFBRSxDQUFDO1FBQ3BDLElBQUksQ0FBQyx5QkFB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SSxDQUNOLFFBQW9DO1FBRXBDLE1BQU0sUUFBUSxHQUFHLFFBQVEsQ0FBQyxRQUFRLENBQUM7UUFDbkMsTUFBTSxTQUFTLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQztRQUNoQyxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxFQUFFO1lBQy9ELE9BQU8sQ0FBQyxHQUFHLENBQ1AsR0FBRyxPQUFPLEVBQUUsNEJBQTRCLFFBQVEsQ0FBQyxJQUFJLEVBQUU7Z0JBQ25ELGlDQUFpQyxTQUFTLEVBQUUsQ0FDbkQsQ0FBQztZQUNGLE9BQU87U0FDVjtRQUVELElBQUksUUFBUSxJQUFJLElBQUksRUFBRTtZQUNsQixNQUFNLElBQUksS0FBSyxDQUFDLHdDQUF3QyxDQUFDLENBQUM7U0FDN0Q7UUFFRCxNQUFNLE1BQU0sR0FBRyxJQUFJLG9CQUFvQixFQUFFLENBQUM7UUFDMUMsTUFBTSxDQUFDLFlBQVksR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDO1FBQ3BDLE1BQU0sQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ25ELE1BQU0sQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1FBQ25CLE1BQU0sQ0FBQyxpQkFBaUIsR0FBRyxRQUFRLENBQUM7UUFDcEMsTUFBTSxDQUFDLG1CQUFtQixHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUM7UUFDM0MsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRU8sZUFBZSxDQUNuQixNQUFlO1FBRWYsT0FBK0MsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzdELENBQUM7Q0FDSiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFR1cGxlQWN0aW9uUHVzaFNlcnZpY2UgfSBmcm9tIFwiLi4vYWN0aW9uLXNlcnZpY2UvVHVwbGVBY3Rpb25QdXNoU2VydmljZVwiO1xuaW1wb3J0IHsgVHVwbGVEYXRhT2JzZXJ2ZXJTZXJ2aWNlIH0gZnJvbSBcIi4uL29ic2VydmFibGUtc2VydmljZS9UdXBsZURhdGFPYnNlcnZlclNlcnZpY2VcIjtcbmltcG9ydCB7IFR1cGxlRGF0YUxvYWRlckRlbGVnYXRlIH0gZnJvbSBcIi4vVHVwbGVEYXRhTG9hZGVyRGVsZWdhdGVcIjtcbmltcG9ydCB7IFR1cGxlIH0gZnJvbSBcIi4uL1R1cGxlXCI7XG5pbXBvcnQgeyBUdXBsZVNlbGVjdG9yIH0gZnJvbSBcIi4uL1R1cGxlU2VsZWN0b3JcIjtcbmltcG9ydCB7IGRpc3RpbmN0VW50aWxDaGFuZ2VkLCBza2lwLCB0YWtlVW50aWwgfSBmcm9tIFwicnhqcy9vcGVyYXRvcnNcIjtcbmltcG9ydCB7IGRhdGVTdHIgfSBmcm9tIFwiLi4vVXRpbE1pc2NcIjtcbmltcG9ydCB7XG4gICAgTmdMaWZlQ3ljbGVFdmVudHMsXG4gICAgTmdPbkRlc3Ryb3lFdmVudEksXG59IGZyb20gXCIuLi8uLi91dGlsL05nTGlmZUN5Y2xlRXZlbnRzXCI7XG5pbXBvcnQgeyBUdXBsZURhdGFMb2FkZXJUdXBsZUFCQyB9IGZyb20gXCIuL1R1cGxlRGF0YUxvYWRlclR1cGxlQUJDXCI7XG5pbXBvcnQge1xuICAgIF9EYXRhTG9hZGVyQWN0aW9uVHlwZSxcbiAgICBfRGF0YUxvYWRlclR1cGxlQWN0aW9uLFxuICAgIF9EYXRhTG9hZGVyVHVwbGVBY3Rpb25SZXNwb25zZVR1cGxlLFxuICAgIF9EYXRhTG9ja1N0YXR1c1R1cGxlLFxuICAgIF9Mb2NrRGF0YVR1cGxlQWN0aW9uLFxufSBmcm9tIFwiLi9UdXBsZURhdGFMb2FkZXJUdXBsZXNcIjtcblxudHlwZSBEZWxlZ2F0ZUJ5VXVpZFQgPSB7IFtkZWxlZ2F0ZVV1aWQ6IHN0cmluZ106IFR1cGxlRGF0YUxvYWRlckRlbGVnYXRlPGFueT4gfTtcbnR5cGUgRGVsZWdhdGVCeVV1aWRCeVR1cGxlVHlwZVQgPSB7IFt0dXBsZVR5cGU6IHN0cmluZ106IERlbGVnYXRlQnlVdWlkVCB9O1xuXG4vKlxuICogVGhlIGBUdXBsZURhdGFMb2FkZXJgIGNsYXNzIG1hbmFnZXMgdGhlIG9ic2VydmFibGUgYW5kIGFjdGlvbiBwdXNoIHNlcnZpY2UgZm9yXG4gKiB0aGUgZGF0YSBsb2FkZXJzLiBEZWxlZ2F0ZXMgZm9yIGVhY2ggZm9ybSBuZWVkIHRvIGJlIHJlZ2lzdGVyZWQgd2l0aCB0aGUgZGF0YVxuICogbG9hZGVyIHVzaW5nIHRoZSBgc2V0RGVsZWdhdGVgIG1ldGhvZC5cbiAqXG4gKiBUaGUgYFR1cGxlRGF0YUxvYWRlcmAgY2FuIGJlIGluc3RhbnRpYXRlZCBpbiBhIGBDb21wb25lbnRgIG9yIGBTZXJ2aWNlYCBhbmRcbiAqIHRha2VzIGluIGFuIGBFdmVudEVtaXR0ZXI8c3RyaW5nPmAgZXZlbnQgd2hpY2ggbm90aWZpZXMgd2hlbiB0byB1bnN1YnNjcmliZVxuICogdG8gdGhlIHN1YnNjcmlwdGlvbnMnIHNldHVwIGJ5IHRoZSBsb2FkZXJcbiAqICovXG5leHBvcnQgY2xhc3MgVHVwbGVEYXRhTG9hZGVyIHtcbiAgICBwcml2YXRlIGRlbGVnYXRlQnlVdWlkQnlUdXBsZVR5cGU6IERlbGVnYXRlQnlVdWlkQnlUdXBsZVR5cGVUID0ge307XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSBuZ0xpZmVDeWNsZUV2ZW50czogTmdMaWZlQ3ljbGVFdmVudHMsXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgYWN0aW9uOiBUdXBsZUFjdGlvblB1c2hTZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IG9ic2VydmVyOiBUdXBsZURhdGFPYnNlcnZlclNlcnZpY2UsXG4gICAgKSB7fVxuXG4gICAgcHJpdmF0ZSBkZWxlZ2F0ZUJ5VXVpZChcbiAgICAgICAgdHVwbGVUeXBlOiBzdHJpbmcsXG4gICAgICAgIGNyZWF0ZSA9IGZhbHNlLFxuICAgICk6IERlbGVnYXRlQnlVdWlkVCB8IG51bGwge1xuICAgICAgICBpZiAodGhpcy5kZWxlZ2F0ZUJ5VXVpZEJ5VHVwbGVUeXBlW3R1cGxlVHlwZV0gIT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGVsZWdhdGVCeVV1aWRCeVR1cGxlVHlwZVt0dXBsZVR5cGVdO1xuICAgICAgICB9XG4gICAgICAgIGlmICghY3JlYXRlKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBuZXdEaWN0OiBEZWxlZ2F0ZUJ5VXVpZFQgPSB7fTtcbiAgICAgICAgdGhpcy5kZWxlZ2F0ZUJ5VXVpZEJ5VHVwbGVUeXBlW3R1cGxlVHlwZV0gPSBuZXdEaWN0O1xuICAgICAgICByZXR1cm4gbmV3RGljdDtcbiAgICB9XG5cbiAgICAvKlxuICAgICAqIFRoZSBgc2V0RGVsZWdhdGVgIG1ldGhvZCByZWdpc3RlcnMgYSBkYXRhIGB0dXBsZWAgdG8gYmUgaGFuZGxlZCBieSB0aGVcbiAgICAgKiBgZGVsZWdhdGVgLlxuICAgICAqICovXG4gICAgcmVtb3ZlRGVsZWdhdGU8VCBleHRlbmRzIFR1cGxlRGF0YUxvYWRlclR1cGxlQUJDPihcbiAgICAgICAgdHVwbGU6IHN0cmluZyB8IFR1cGxlLFxuICAgICAgICBkZWxlZ2F0ZTogVHVwbGVEYXRhTG9hZGVyRGVsZWdhdGU8VD4sXG4gICAgKSB7XG4gICAgICAgIGNvbnN0IHR1cGxlVHlwZSA9IHR1cGxlIGluc3RhbmNlb2YgVHVwbGUgPyB0dXBsZS5fdHVwbGVUeXBlIDogdHVwbGU7XG5cbiAgICAgICAgaWYgKCh0aGlzLmRlbGVnYXRlQnlVdWlkKHR1cGxlVHlwZSkgfHwge30pW2RlbGVnYXRlLnV1aWRdID09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICBgcmVtb3ZlRGVsZWdhdGU6IERlbGVnYXRlIHdpdGggVVVJRCAke2RlbGVnYXRlLnV1aWR9YCArXG4gICAgICAgICAgICAgICAgICAgIGAgYW5kIHR1cGxlIHR5cGUgJHt0dXBsZVR5cGV9YCArXG4gICAgICAgICAgICAgICAgICAgIGAgZG9lcyBub3QgZXhpc3RgLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGRlbGV0ZSB0aGlzLmRlbGVnYXRlQnlVdWlkQnlUdXBsZVR5cGVbdHVwbGVUeXBlXVtkZWxlZ2F0ZS51dWlkXTtcbiAgICB9XG5cbiAgICAvKlxuICAgICAqIFRoZSBgc2V0RGVsZWdhdGVgIG1ldGhvZCByZWdpc3RlcnMgYSBkYXRhIGB0dXBsZWAgdG8gYmUgaGFuZGxlZCBieSB0aGVcbiAgICAgKiBgZGVsZWdhdGVgLlxuICAgICAqICovXG4gICAgYWRkRGVsZWdhdGU8VCBleHRlbmRzIFR1cGxlRGF0YUxvYWRlclR1cGxlQUJDPihcbiAgICAgICAgdHVwbGU6IHN0cmluZyB8IFR1cGxlLFxuICAgICAgICBkZWxlZ2F0ZTogVHVwbGVEYXRhTG9hZGVyRGVsZWdhdGU8VD4sXG4gICAgICAgIGRlc3Ryb3lFdmVudDogTmdPbkRlc3Ryb3lFdmVudEksXG4gICAgKSB7XG4gICAgICAgIGNvbnN0IHR1cGxlVHlwZSA9IHR1cGxlIGluc3RhbmNlb2YgVHVwbGUgPyB0dXBsZS5fdHVwbGVUeXBlIDogdHVwbGU7XG4gICAgICAgIGlmICgodGhpcy5kZWxlZ2F0ZUJ5VXVpZCh0dXBsZVR5cGUpIHx8IHt9KVtkZWxlZ2F0ZS51dWlkXSAhPSBudWxsKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgYGFkZERlbGVnYXRlOiBEZWxlZ2F0ZSB3aXRoIFVVSUQgJHtkZWxlZ2F0ZS51dWlkfWAgK1xuICAgICAgICAgICAgICAgICAgICBgIGFuZCB0dXBsZSB0eXBlICR7dHVwbGVUeXBlfWAgK1xuICAgICAgICAgICAgICAgICAgICBgIGFscmVhZHkgZXhpc3RzYCxcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmRlbGVnYXRlQnlVdWlkKHR1cGxlVHlwZSwgdHJ1ZSlbZGVsZWdhdGUudXVpZF0gPSBkZWxlZ2F0ZTtcbiAgICAgICAgZGVsZWdhdGVbXCJzZXREYXRhTG9hZGVyXCJdKHRoaXMpO1xuICAgICAgICBkZWxlZ2F0ZVtcInJlZ2lzdGVyZWROYW1lXCJdID0gdHVwbGVUeXBlO1xuXG4gICAgICAgIGRlc3Ryb3lFdmVudC5vbkRlc3Ryb3lFdmVudC5zdWJzY3JpYmUoKCkgPT5cbiAgICAgICAgICAgIHRoaXMucmVtb3ZlRGVsZWdhdGUodHVwbGUsIGRlbGVnYXRlKSxcbiAgICAgICAgKTtcblxuICAgICAgICBjb25zdCBkaXN0aW5jdFNlbGVjdG9yJCA9IGRlbGVnYXRlLnNlbGVjdG9yJC5waXBlKFxuICAgICAgICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoXG4gICAgICAgICAgICAgICAgKHMxLCBzMikgPT4gczE/LnRvT3JkZXJlZEpzb25TdHIoKSA9PT0gczI/LnRvT3JkZXJlZEpzb25TdHIoKSxcbiAgICAgICAgICAgICksXG4gICAgICAgICk7XG4gICAgICAgIGRpc3RpbmN0U2VsZWN0b3IkXG4gICAgICAgICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5uZ0xpZmVDeWNsZUV2ZW50cy5vbkRlc3Ryb3lFdmVudCkpXG4gICAgICAgICAgICAuc3Vic2NyaWJlKChzZWxlY3RvcikgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChzZWxlY3RvciA9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAodHVwbGVUeXBlICE9IHNlbGVjdG9yLm5hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICAgICAgICAgICAgICBcIlR1cGxlRGF0YUxvYWRlcjogZGlzdGluY3RTZWxlY3RvciQgU2VsZWN0b3IgYW5kXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiIGRhdGEgbWlzc21hdGNoXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGAgdHVwbGVUeXBlPSR7dHVwbGVUeXBlfWAgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGAgdnMgc2VsZWN0b3IubmFtZT0ke3NlbGVjdG9yLm5hbWV9YCxcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgICAgICAgICBcIlR1cGxlRGF0YUxvYWRlcjogZGlzdGluY3RTZWxlY3RvciQgT2JzZXJ2ZWQgc2VsZWN0b3IkXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgXCIgY2hhbmdlXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgYCByZWZyZXNoaW5nICR7c2VsZWN0b3IudG9PcmRlcmVkSnNvblN0cigpfWAsXG4gICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgIGNvbnN0IHNlbGVjdG9yQ2hhbmdlUGlwZSA9IGRpc3RpbmN0U2VsZWN0b3IkLnBpcGUoc2tpcCgxKSk7XG5cbiAgICAgICAgICAgICAgICB0aGlzLm9ic2VydmVyXG4gICAgICAgICAgICAgICAgICAgIC5zdWJzY3JpYmVUb1R1cGxlU2VsZWN0b3Ioc2VsZWN0b3IpXG4gICAgICAgICAgICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICAgICAgICAgICAgdGFrZVVudGlsKHRoaXMubmdMaWZlQ3ljbGVFdmVudHMub25EZXN0cm95RXZlbnQpLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGFrZVVudGlsKHNlbGVjdG9yQ2hhbmdlUGlwZSksXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgLnN1YnNjcmliZSgodHVwbGVzOiBUW10pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0dXBsZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIlR1cGxlRGF0YUxvYWRlcjpcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIiBkaXN0aW5jdFNlbGVjdG9yJCB0dXBsZU9ic2VydmVyLFwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiIFR1cGxlRGF0YUxvYWRlclR1cGxlQUJDIHJlY2VpdmVkIGZyb20gc2VydmVyLFwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGAgc2VsZWN0b3I6ICR7c2VsZWN0b3IudG9PcmRlcmVkSnNvblN0cigpfWAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxlZ2F0ZVtcInByb2Nlc3NEYXRhVXBkYXRlXCJdKHR1cGxlc1swXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgLy8gVGhlIGxvY2tpbmcgdHVwbGUgc2VsZWN0b3IgdXNlcyB0aGUgX0RhdGFMb2NrU3RhdHVzVHVwbGUgYW5kXG4gICAgICAgICAgICAgICAgLy8gdGhlIHR1cGxlIHNlbGVjdG9yIGZvciB0aGUgZm9ybS5cbiAgICAgICAgICAgICAgICB0aGlzLm9ic2VydmVyXG4gICAgICAgICAgICAgICAgICAgIC5zdWJzY3JpYmVUb1R1cGxlU2VsZWN0b3IoXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXcgVHVwbGVTZWxlY3RvcihfRGF0YUxvY2tTdGF0dXNUdXBsZS50dXBsZVR5cGUsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhVHVwbGVTZWxlY3Rvcjogc2VsZWN0b3IsXG4gICAgICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICAgICAgICAgIHRha2VVbnRpbCh0aGlzLm5nTGlmZUN5Y2xlRXZlbnRzLm9uRGVzdHJveUV2ZW50KSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRha2VVbnRpbChzZWxlY3RvckNoYW5nZVBpcGUpLFxuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUoKHR1cGxlczogX0RhdGFMb2NrU3RhdHVzVHVwbGU8YW55PltdKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodHVwbGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJUdXBsZURhdGFMb2FkZXI6XCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCIgZGlzdGluY3RTZWxlY3RvciQgdHVwbGVPYnNlcnZlcixcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIiBfRGF0YUxvY2tTdGF0dXNUdXBsZSByZWNlaXZlZCBmcm9tIHNlcnZlcixcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgIHNlbGVjdG9yOiAke3NlbGVjdG9yLnRvT3JkZXJlZEpzb25TdHIoKX1gLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZWdhdGVbXCJwcm9jZXNzTG9ja1N0YXR1c1wiXSh0dXBsZXNbMF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qXG4gICAgICogVGhlIGBzdG9yZWAgbWV0aG9kIHdpbGwgc2F2ZSB0aGUgZGF0YSBieSBjYWxsaW5nIHRoZSBgd3JpdGVEYXRhYCBtZXRob2RcbiAgICAgKiBvZiB0aGUgcmVnaXN0ZXJlZCBkZWxlZ2F0ZSBpbiB0aGUgYmFja2VuZCBjb2RlLiBJdCB3aWxsIGFsc28gcmVsZWFzZSBhbnlcbiAgICAgKiBsb2NrcyBvbiB0aGlzIGZvcm0gYW5kIGRpc2NhcmQgdGhlIGxpdmUgdmFsdWUuXG4gICAgICogKi9cbiAgICBhc3luYyBjcmVhdGU8VCBleHRlbmRzIFR1cGxlRGF0YUxvYWRlclR1cGxlQUJDPihcbiAgICAgICAgZGVsZWdhdGU6IFR1cGxlRGF0YUxvYWRlckRlbGVnYXRlPFQ+LFxuICAgICk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBjb25zdCBkYXRhID0gZGVsZWdhdGUuZGF0YTtcbiAgICAgICAgY29uc3QgdHVwbGVUeXBlID0gZGF0YS5fdHVwbGVOYW1lKCk7XG4gICAgICAgIGlmICgodGhpcy5kZWxlZ2F0ZUJ5VXVpZCh0dXBsZVR5cGUpIHx8IHt9KVtkZWxlZ2F0ZS51dWlkXSA9PSBudWxsKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgICAgICBgJHtkYXRlU3RyKCl9IENSRUFURSBEZWxlZ2F0ZSB3aXRoIFVVSUQgJHtkZWxlZ2F0ZS51dWlkfWAgK1xuICAgICAgICAgICAgICAgICAgICBgIG5vdCByZWdpc3RlcmVkIGZvciB0dXBsZVR5cGUgJHt0dXBsZVR5cGV9YCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZGF0YSA9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBhY3Rpb24gPSBuZXcgX0RhdGFMb2FkZXJUdXBsZUFjdGlvbigpO1xuICAgICAgICBhY3Rpb24udXNlclV1aWQgPSBkZWxlZ2F0ZVtcInVzZXJVdWlkJFwiXS5nZXRWYWx1ZSgpO1xuICAgICAgICBhY3Rpb24uZGVsZWdhdGVVdWlkID0gZGVsZWdhdGUudXVpZDtcbiAgICAgICAgYWN0aW9uLmRhdGFUdXBsZSA9IGRhdGE7XG4gICAgICAgIGFjdGlvbi5hY3Rpb24gPSBfRGF0YUxvYWRlckFjdGlvblR5cGUuQ3JlYXRlO1xuXG4gICAgICAgIC8vIG5vaW5zcGVjdGlvbiBKU1VudXNlZExvY2FsU3ltYm9sc1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IHRoaXMuY29udmVydFJlc3BvbnNlKFxuICAgICAgICAgICAgYXdhaXQgdGhpcy5hY3Rpb24ucHVzaEFjdGlvbihhY3Rpb24pLFxuICAgICAgICApO1xuXG4gICAgICAgIGRlbGVnYXRlLnNlbGVjdG9yJC5uZXh0KHJlc3BvbnNlLnR1cGxlRGF0YVNlbGVjdG9yKTtcbiAgICB9XG5cbiAgICAvKlxuICAgICAqIFRoZSBgc3RvcmVgIG1ldGhvZCB3aWxsIHNhdmUgdGhlIGRhdGEgYnkgY2FsbGluZyB0aGUgYHdyaXRlRGF0YWAgbWV0aG9kXG4gICAgICogb2YgdGhlIHJlZ2lzdGVyZWQgZGVsZWdhdGUgaW4gdGhlIGJhY2tlbmQgY29kZS4gSXQgd2lsbCBhbHNvIHJlbGVhc2UgYW55XG4gICAgICogbG9ja3Mgb24gdGhpcyBmb3JtIGFuZCBkaXNjYXJkIHRoZSBsaXZlIHZhbHVlLlxuICAgICAqICovXG4gICAgYXN5bmMgc3RvcmU8VCBleHRlbmRzIFR1cGxlRGF0YUxvYWRlclR1cGxlQUJDPihcbiAgICAgICAgZGVsZWdhdGU6IFR1cGxlRGF0YUxvYWRlckRlbGVnYXRlPFQ+LFxuICAgICk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBjb25zdCBkYXRhID0gZGVsZWdhdGUuZGF0YTtcbiAgICAgICAgY29uc3Qgc2VsZWN0b3IgPSBkZWxlZ2F0ZS5zZWxlY3RvcjtcbiAgICAgICAgY29uc3QgdHVwbGVUeXBlID0gc2VsZWN0b3IubmFtZTtcbiAgICAgICAgaWYgKCh0aGlzLmRlbGVnYXRlQnlVdWlkKHR1cGxlVHlwZSkgfHwge30pW2RlbGVnYXRlLnV1aWRdID09IG51bGwpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgICAgIGAke2RhdGVTdHIoKX0gU1RPUkUgRGVsZWdhdGUgd2l0aCBVVUlEICR7ZGVsZWdhdGUudXVpZH1gICtcbiAgICAgICAgICAgICAgICAgICAgYCBub3QgcmVnaXN0ZXJlZCBmb3IgdHVwbGVUeXBlICR7dHVwbGVUeXBlfWAsXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGRhdGEgPT0gbnVsbCB8fCBzZWxlY3RvciA9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBhY3Rpb24gPSBuZXcgX0RhdGFMb2FkZXJUdXBsZUFjdGlvbigpO1xuICAgICAgICBhY3Rpb24udXNlclV1aWQgPSBkZWxlZ2F0ZVtcInVzZXJVdWlkJFwiXS5nZXRWYWx1ZSgpO1xuICAgICAgICBhY3Rpb24uZGVsZWdhdGVVdWlkID0gZGVsZWdhdGUudXVpZDtcbiAgICAgICAgYWN0aW9uLmRhdGFUdXBsZSA9IGRhdGE7XG4gICAgICAgIGFjdGlvbi5hY3Rpb24gPSBfRGF0YUxvYWRlckFjdGlvblR5cGUuU3RvcmU7XG4gICAgICAgIGFjdGlvbi50dXBsZURhdGFTZWxlY3RvciA9IHNlbGVjdG9yO1xuXG4gICAgICAgIC8vIG5vaW5zcGVjdGlvbiBKU1VudXNlZExvY2FsU3ltYm9sc1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IHRoaXMuY29udmVydFJlc3BvbnNlKFxuICAgICAgICAgICAgYXdhaXQgdGhpcy5hY3Rpb24ucHVzaEFjdGlvbihhY3Rpb24pLFxuICAgICAgICApO1xuXG4gICAgICAgIC8vIElmIHRoZXJlIGlzIGEgVHVwbGVTZWxlY3RvciB1cGRhdGUsIGFwcGx5IGl0LlxuICAgICAgICBpZiAocmVzcG9uc2UudHVwbGVEYXRhU2VsZWN0b3IgIT0gbnVsbCkge1xuICAgICAgICAgICAgZGVsZWdhdGUuc2VsZWN0b3IkLm5leHQocmVzcG9uc2UudHVwbGVEYXRhU2VsZWN0b3IpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLypcbiAgICAgKiBUaGUgYGxvYWRgIG1ldGhvZCB3aWxsIGxvYWQgdGhlIGRhdGEgdXNpbmcgdGhlIGByZWFkRGF0YWAgbWV0aG9kIG9mIHRoZVxuICAgICAqIHJlZ2lzdGVyZWQgZGVsZWdhdGUgaW4gdGhlIGJhY2tlbmQuIEl0IHdpbGwgZGlzY2FyZCBhbnkgbGl2ZSB2YWx1ZXMgYW5kXG4gICAgICogYWxzbyByZWxlYXNlIHRoZSBsb2Nrcy5cbiAgICAgKiAqL1xuICAgIGFzeW5jIGxvYWQ8VCBleHRlbmRzIFR1cGxlRGF0YUxvYWRlclR1cGxlQUJDPihcbiAgICAgICAgZGVsZWdhdGU6IFR1cGxlRGF0YUxvYWRlckRlbGVnYXRlPFQ+LFxuICAgICk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBjb25zdCBzZWxlY3RvciA9IGRlbGVnYXRlLnNlbGVjdG9yO1xuICAgICAgICBjb25zdCB0dXBsZVR5cGUgPSBzZWxlY3Rvci5uYW1lO1xuICAgICAgICBpZiAoKHRoaXMuZGVsZWdhdGVCeVV1aWQodHVwbGVUeXBlKSB8fCB7fSlbZGVsZWdhdGUudXVpZF0gPT0gbnVsbCkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICAgICAgYCR7ZGF0ZVN0cigpfSBMT0FEICBEZWxlZ2F0ZSB3aXRoIFVVSUQgJHtkZWxlZ2F0ZS51dWlkfWAgK1xuICAgICAgICAgICAgICAgICAgICBgIG5vdCByZWdpc3RlcmVkIGZvciB0dXBsZVR5cGUgJHt0dXBsZVR5cGV9YCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNlbGVjdG9yID09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlR1cGxlU2VsZWN0b3Igbm90IHNldCB0byBsb2FkIGRhdGFcIik7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBhY3Rpb24gPSBuZXcgX0RhdGFMb2FkZXJUdXBsZUFjdGlvbigpO1xuICAgICAgICAvLyBUaGlzIGRvZXMgbm90IG1hdHRlciBmb3IgcmV2ZXJ0XG4gICAgICAgIGFjdGlvbi51c2VyVXVpZCA9IGRlbGVnYXRlW1widXNlclV1aWQkXCJdLmdldFZhbHVlKCk7XG4gICAgICAgIGFjdGlvbi5kZWxlZ2F0ZVV1aWQgPSBkZWxlZ2F0ZS51dWlkO1xuICAgICAgICBhY3Rpb24uZGF0YVR1cGxlID0gZGVsZWdhdGUuZGF0YTtcbiAgICAgICAgYWN0aW9uLmFjdGlvbiA9IF9EYXRhTG9hZGVyQWN0aW9uVHlwZS5Mb2FkO1xuICAgICAgICBhY3Rpb24udHVwbGVEYXRhU2VsZWN0b3IgPSBzZWxlY3RvcjtcblxuICAgICAgICAvLyBub2luc3BlY3Rpb24gSlNVbnVzZWRMb2NhbFN5bWJvbHNcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSB0aGlzLmNvbnZlcnRSZXNwb25zZShcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuYWN0aW9uLnB1c2hBY3Rpb24oYWN0aW9uKSxcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKlxuICAgICAqIFRoZSBgZGVsZXRlYCBtZXRob2Qgd2lsbCBjYWxsIGBkZWxldGVEYXRhYCBtZXRob2Qgb2YgdGhlIHJlZ2lzdGVyZWRcbiAgICAgKiBkZWxlZ2F0ZSBpbiB0aGUgYmFja2VuZCBjb2RlXG4gICAgICogKi9cbiAgICBhc3luYyBkZWxldGU8VCBleHRlbmRzIFR1cGxlRGF0YUxvYWRlclR1cGxlQUJDPihcbiAgICAgICAgZGVsZWdhdGU6IFR1cGxlRGF0YUxvYWRlckRlbGVnYXRlPFQ+LFxuICAgICk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBjb25zdCBkYXRhID0gZGVsZWdhdGUuZGF0YTtcbiAgICAgICAgY29uc3Qgc2VsZWN0b3IgPSBkZWxlZ2F0ZS5zZWxlY3RvcjtcbiAgICAgICAgY29uc3QgdHVwbGVUeXBlID0gc2VsZWN0b3IubmFtZTtcbiAgICAgICAgaWYgKCh0aGlzLmRlbGVnYXRlQnlVdWlkKHR1cGxlVHlwZSkgfHwge30pW2RlbGVnYXRlLnV1aWRdID09IG51bGwpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgICAgIGAke2RhdGVTdHIoKX0gREVMRVRFIERlbGVnYXRlIHdpdGggVVVJRCAke2RlbGVnYXRlLnV1aWR9YCArXG4gICAgICAgICAgICAgICAgICAgIGAgbm90IHJlZ2lzdGVyZWQgZm9yIHR1cGxlVHlwZSAke3R1cGxlVHlwZX1gLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzZWxlY3RvciA9PSBudWxsKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUdXBsZVNlbGVjdG9yIG5vdCBzZXQgdG8gZGVsZXRlIGRhdGFcIik7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBhY3Rpb24gPSBuZXcgX0RhdGFMb2FkZXJUdXBsZUFjdGlvbigpO1xuICAgICAgICAvLyBUaGlzIGRvZXMgbm90IG1hdHRlciBmb3IgZGVsZXRlXG4gICAgICAgIGFjdGlvbi51c2VyVXVpZCA9IGRlbGVnYXRlW1widXNlclV1aWQkXCJdLmdldFZhbHVlKCk7XG4gICAgICAgIGFjdGlvbi5kZWxlZ2F0ZVV1aWQgPSBkZWxlZ2F0ZS51dWlkO1xuICAgICAgICBhY3Rpb24uZGF0YVR1cGxlID0gZGVsZWdhdGUuZGF0YTtcbiAgICAgICAgYWN0aW9uLmFjdGlvbiA9IF9EYXRhTG9hZGVyQWN0aW9uVHlwZS5EZWxldGU7XG4gICAgICAgIGFjdGlvbi50dXBsZURhdGFTZWxlY3RvciA9IHNlbGVjdG9yO1xuXG4gICAgICAgIC8vIG5vaW5zcGVjdGlvbiBKU1VudXNlZExvY2FsU3ltYm9sc1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IHRoaXMuY29udmVydFJlc3BvbnNlKFxuICAgICAgICAgICAgYXdhaXQgdGhpcy5hY3Rpb24ucHVzaEFjdGlvbihhY3Rpb24pLFxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qXG4gICAgICogVGhlIGBsb2NrYCBtZXRob2Qgd2lsbCBhY3F1aXJlIGEgbG9jayBvbiB0aGUgZGF0YSBvciB0aHJvdyBhbiBleGNlcHRpb25cbiAgICAgKiBpZiB0aGUgbG9jayBpcyBhbHJlYWR5IGhlbGQgYnkgc29tZW9uZSBlbHNlIG9uIHRoZSBjdXJyZW50IHR1cGxlIHNlbGVjdG9yXG4gICAgICogKi9cbiAgICBhc3luYyBsb2NrPFQgZXh0ZW5kcyBUdXBsZURhdGFMb2FkZXJUdXBsZUFCQz4oXG4gICAgICAgIGRlbGVnYXRlOiBUdXBsZURhdGFMb2FkZXJEZWxlZ2F0ZTxUPixcbiAgICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgY29uc3Qgc2VsZWN0b3IgPSBkZWxlZ2F0ZS5zZWxlY3RvcjtcbiAgICAgICAgY29uc3QgdHVwbGVUeXBlID0gc2VsZWN0b3IubmFtZTtcbiAgICAgICAgaWYgKCh0aGlzLmRlbGVnYXRlQnlVdWlkKHR1cGxlVHlwZSkgfHwge30pW2RlbGVnYXRlLnV1aWRdID09IG51bGwpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgICAgIGAke2RhdGVTdHIoKX0gTE9DSyBEZWxlZ2F0ZSB3aXRoIFVVSUQgJHtkZWxlZ2F0ZS51dWlkfWAgK1xuICAgICAgICAgICAgICAgICAgICBgIG5vdCByZWdpc3RlcmVkIGZvciB0dXBsZVR5cGUgJHt0dXBsZVR5cGV9YCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc2VsZWN0b3IgPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVHVwbGVTZWxlY3RvciBub3Qgc2V0IHRvIGxvY2sgZm9ybSBmb3JcIik7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBhY3Rpb24gPSBuZXcgX0xvY2tEYXRhVHVwbGVBY3Rpb24oKTtcbiAgICAgICAgYWN0aW9uLmRlbGVnYXRlVXVpZCA9IGRlbGVnYXRlLnV1aWQ7XG4gICAgICAgIGFjdGlvbi51c2VyVXVpZCA9IGRlbGVnYXRlW1widXNlclV1aWQkXCJdLmdldFZhbHVlKCk7XG4gICAgICAgIGFjdGlvbi5sb2NrID0gdHJ1ZTtcbiAgICAgICAgYWN0aW9uLnR1cGxlRGF0YVNlbGVjdG9yID0gc2VsZWN0b3I7XG4gICAgICAgIGFjdGlvbi5saXZlVXBkYXRlRGF0YVR1cGxlID0gZGVsZWdhdGUuZGF0YTtcbiAgICAgICAgYXdhaXQgdGhpcy5hY3Rpb24ucHVzaEFjdGlvbihhY3Rpb24pO1xuICAgIH1cblxuICAgIHByaXZhdGUgY29udmVydFJlc3BvbnNlPFQgZXh0ZW5kcyBUdXBsZURhdGFMb2FkZXJUdXBsZUFCQz4oXG4gICAgICAgIHR1cGxlczogVHVwbGVbXSxcbiAgICApOiBfRGF0YUxvYWRlclR1cGxlQWN0aW9uUmVzcG9uc2VUdXBsZTxUPiB7XG4gICAgICAgIHJldHVybiA8X0RhdGFMb2FkZXJUdXBsZUFjdGlvblJlc3BvbnNlVHVwbGU8VD4+dHVwbGVzWzBdO1xuICAgIH1cbn1cbiJdfQ==