com.phloxui
Version:
PhloxUI Ng2+ Framework
310 lines (309 loc) • 28.3 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
import * as tslib_1 from "tslib";
import { Component, Input, ElementRef } from '@angular/core';
import { ComponentDialogModel } from '.././model/ComponentDialogModel';
import { PhloxAppInfoService } from '../../service/PhloxAppInfoService.service';
import { AbstractDialogController } from '../AbstractDialogController';
var /** @type {?} */ TYPE_NAME = "phx-component-dialog";
/**
* <p style="text-indent: 2em;">
* A <code>child-view</code> component class of [[PhloxDialog]] handling logic of <code>component dialog</code>. This class should be
* <b>internally used by the framework</b>. If you just want to show a <code>component dialog</code>. Please see [[DialogService.showComponentDialog]]
* for more info.
* </p>
*
* @author shiorin, tee4cute
* @see [[PhloxDialog]]
* @see [[DialogService]]
*/
var ComponentDialog = /** @class */ (function (_super) {
tslib_1.__extends(ComponentDialog, _super);
function ComponentDialog(elementRef, phloxAppService) {
var _this = _super.call(this, elementRef) || this;
_this.componentInstance = null;
if (phloxAppService != null) {
phloxAppService.getAppInfo().then(function (result) {
_this.phloxAppInfo = result;
});
}
_this.componentHandler = function (result) {
_this.componentInstance = result.instance;
if (typeof _this.componentInstance.getButtonsChangeEvent === 'function') {
var /** @type {?} */ btnChangeEV = _this.componentInstance.getButtonsChangeEvent();
if (btnChangeEV !== null && typeof btnChangeEV !== 'undefined') {
btnChangeEV.subscribe(function (event) {
_this.refreshActionButtons();
});
}
}
_this.refreshActionButtons();
};
return _this;
}
/**
* @return {?}
*/
ComponentDialog.prototype.ngOnInit = /**
* @return {?}
*/
function () {
this.refreshActionButtons();
};
/**
* @param {?} changes
* @return {?}
*/
ComponentDialog.prototype.ngOnChanges = /**
* @param {?} changes
* @return {?}
*/
function (changes) {
if (changes['model'] !== null && typeof changes['model'] !== 'undefined') {
this.refreshActionButtons();
}
};
/**
* @return {?}
*/
ComponentDialog.prototype.getResultFromComponentWrapper = /**
* @return {?}
*/
function () {
if (this.componentInstance !== null && typeof this.componentInstance !== 'undefined') {
if (typeof this.componentInstance.getDialogResult === 'function') {
return this.componentInstance.getDialogResult();
}
}
return null;
};
/**
* @return {?}
*/
ComponentDialog.prototype.refreshActionButtons = /**
* @return {?}
*/
function () {
var _this = this;
var /** @type {?} */ dialogButtons = [];
if (this.componentInstance !== null && typeof this.componentInstance !== 'undefined') {
if (typeof this.componentInstance.getDialogButtons === 'function') {
var /** @type {?} */ actionBths = this.componentInstance.getDialogButtons();
if (actionBths !== null && typeof actionBths !== 'undefined' && Array.isArray(actionBths)) {
try {
for (var actionBths_1 = tslib_1.__values(actionBths), actionBths_1_1 = actionBths_1.next(); !actionBths_1_1.done; actionBths_1_1 = actionBths_1.next()) {
var btn = actionBths_1_1.value;
dialogButtons.push(btn);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (actionBths_1_1 && !actionBths_1_1.done && (_a = actionBths_1.return)) _a.call(actionBths_1);
}
finally { if (e_1) throw e_1.error; }
}
}
}
}
if (dialogButtons.length <= 0) {
if (this.model !== null && typeof this.model !== 'undefined') {
if (this.model.buttonModels !== null && typeof this.model.buttonModels !== 'undefined') {
try {
for (var _b = tslib_1.__values(this.model.buttonModels), _c = _b.next(); !_c.done; _c = _b.next()) {
var btn = _c.value;
dialogButtons.push(btn);
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (_c && !_c.done && (_d = _b.return)) _d.call(_b);
}
finally { if (e_2) throw e_2.error; }
}
}
}
}
// auto add btn
if (dialogButtons.length <= 0) {
var /** @type {?} */ cancelHandler = function () {
var /** @type {?} */ result = -1;
if (_this.dialog !== null && typeof _this.dialog !== 'undefined') {
_this.dialog.hideDialog();
}
};
dialogButtons.push(new ComponentDialogModel.ButtonModel(this.getI18NMessage('CANCEL'), null, cancelHandler, ['dialog-btn', 'cancel']));
}
this.dialogButtons = dialogButtons;
var e_1, _a, e_2, _d;
};
/**
* @param {?} key
* @return {?}
*/
ComponentDialog.prototype.getI18NMessage = /**
* @param {?} key
* @return {?}
*/
function (key) {
if (this.phloxAppInfo != null && this.phloxAppInfo.i18n != null) {
if (this.phloxAppInfo.i18n[key] !== null && typeof this.phloxAppInfo.i18n[key] !== 'undefined') {
return this.phloxAppInfo.i18n[key];
}
}
return key;
};
/**
* @param {?} $event
* @return {?}
*/
ComponentDialog.prototype._onXBtnClicked = /**
* @param {?} $event
* @return {?}
*/
function ($event) {
if (this.model !== null && typeof this.model !== 'undefined') {
if (this.model.closeHandler !== null && typeof this.model.closeHandler !== 'undefined') {
if (typeof this.model.closeHandler === 'function') {
this.model.closeHandler.call(null, $event);
}
}
}
};
/**
* @return {?}
*/
ComponentDialog.prototype._isShowXBtn = /**
* @return {?}
*/
function () {
if (this.model !== null && typeof this.model !== 'undefined') {
if (this.model.closeHandler !== null && typeof this.model.closeHandler !== 'undefined') {
if (typeof this.model.closeHandler === 'function') {
return true;
}
}
}
return false;
};
/**
* @return {?}
*/
ComponentDialog.prototype._getComponentHandler = /**
* @return {?}
*/
function () {
return this.componentHandler;
};
/**
* @param {?} styleClass
* @return {?}
*/
ComponentDialog.prototype._getDefaultItemStyleClass = /**
* @param {?} styleClass
* @return {?}
*/
function (styleClass) {
var /** @type {?} */ defStyleClass = ["dialog-btn"];
if (styleClass !== null && styleClass !== undefined && styleClass.length > 0) {
return styleClass;
}
return defStyleClass;
};
/**
* @return {?}
*/
ComponentDialog.prototype.showDialog = /**
* @return {?}
*/
function () {
this.show = true;
};
/**
* @return {?}
*/
ComponentDialog.prototype.hideDialog = /**
* @return {?}
*/
function () {
this.show = false;
};
/**
* @return {?}
*/
ComponentDialog.prototype.isShow = /**
* @return {?}
*/
function () {
return this.show;
};
/**
* @return {?}
*/
ComponentDialog.prototype.getModel = /**
* @return {?}
*/
function () {
return this.model;
};
/**
* @param {?} model
* @return {?}
*/
ComponentDialog.prototype.setModel = /**
* @param {?} model
* @return {?}
*/
function (model) {
this.model = model;
this.refreshActionButtons();
};
ComponentDialog.TYPE_NAME = TYPE_NAME;
ComponentDialog.decorators = [
{ type: Component, args: [{
moduleId: module.id,
selector: TYPE_NAME,
template: "<div class=\"phx-component-dialog\" [class.show]=\"isShow()\">\n\t<ng-template [ngIf]=\"getModel() != null\">\n\t\t<div class=\"dialog-header\" [ngClass]=\"getModel().headerStyleClass\">\n\t\t\t<div class=\"wrapper\">\n\t\t\t\t<div>\n\t\t\t\t\t{{getModel() != null ? getModel().title : ''}}\n\t\t\t\t</div>\n\t\t\t\t<div>\n\t\t\t\t\t<div class=\"table-wrapper fluid\">\n\t\t\t\t\t\t<div class=\"table-cell-wrapper middle\">\n\t\t\t\t\t\t\t<h4 class=\"x-btn\" *ngIf=\"_isShowXBtn()\" (click)=\"_onXBtnClicked($event)\">X</h4>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<div class=\"dialog-body\" [ngClass]=\"getModel().bodyStyleClass\">\n\t\t\t<div>\n\t\t\t\t<phx-component-wrapper #componentWrapper [type]=\"getModel().componentType\" [model]=\"getModel().model\" [handler]=\"_getComponentHandler()\"\n\t\t\t\t\t[data]=\"getModel().data\"></phx-component-wrapper>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<div class=\"dialog-footer\" [ngClass]=\"getModel().footerStyleClass\">\n\t\t\t<div class=\"wrapper\">\n\t\t\t\t<div>\n\t\t\t\t\t<ng-template [ngIf]=\"getModel() != null\">\n\t\t\t\t\t<div *ngFor=\"let item of getDialogButtons(); let j = index\"\n\t\t\t\t\t\t[ngClass]=\"_getDefaultItemStyleClass(item.styleClass)\" (click)=\"item.handler()\">{{item.label}}</div>\n\t\t\t\t\t</ng-template>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</ng-template>\n</div>\n"
},] },
];
/** @nocollapse */
ComponentDialog.ctorParameters = function () { return [
{ type: ElementRef, },
{ type: PhloxAppInfoService, },
]; };
ComponentDialog.propDecorators = {
"model": [{ type: Input },],
"dialog": [{ type: Input },],
};
return ComponentDialog;
}(AbstractDialogController));
export { ComponentDialog };
function ComponentDialog_tsickle_Closure_declarations() {
/** @type {!Array<{type: !Function, args: (undefined|!Array<?>)}>} */
ComponentDialog.decorators;
/**
* @nocollapse
* @type {function(): !Array<(null|{type: ?, decorators: (undefined|!Array<{type: !Function, args: (undefined|!Array<?>)}>)})>}
*/
ComponentDialog.ctorParameters;
/** @type {!Object<string,!Array<{type: !Function, args: (undefined|!Array<?>)}>>} */
ComponentDialog.propDecorators;
/** @type {?} */
ComponentDialog.TYPE_NAME;
/** @type {?} */
ComponentDialog.prototype.model;
/** @type {?} */
ComponentDialog.prototype.dialog;
/** @type {?} */
ComponentDialog.prototype.componentInstance;
/** @type {?} */
ComponentDialog.prototype.show;
/** @type {?} */
ComponentDialog.prototype.phloxAppInfo;
/** @type {?} */
ComponentDialog.prototype.componentHandler;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ29tcG9uZW50RGlhbG9nLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2NvbS5waGxveHVpLyIsInNvdXJjZXMiOlsibGliL2NvbXBvbmVudC9kaWFsb2cuaW50ZXJuYWwvQ29tcG9uZW50RGlhbG9nLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUE4QyxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDekcsT0FBTyxFQUFFLG9CQUFvQixFQUFlLE1BQU0saUNBQWlDLENBQUM7QUFJcEYsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sMkNBQTJDLENBQUM7QUFDaEYsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFFdkUscUJBQU0sU0FBUyxHQUFXLHNCQUFzQixDQUFDOzs7Ozs7Ozs7Ozs7O0lBc0RaLDJDQUF3QjtJQWEzRCx5QkFBWSxVQUFzQixFQUFFLGVBQW9DO1FBQXhFLFlBQ0Usa0JBQU0sVUFBVSxDQUFDLFNBdUJsQjtRQXJCQyxLQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDO1FBRTlCLEVBQUUsQ0FBQyxDQUFDLGVBQWUsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQzVCLGVBQWUsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBQyxNQUFNO2dCQUN2QyxLQUFJLENBQUMsWUFBWSxHQUFHLE1BQU0sQ0FBQzthQUM1QixDQUFDLENBQUM7U0FDSjtRQUVELEtBQUksQ0FBQyxnQkFBZ0IsR0FBRyxVQUFDLE1BQVc7WUFDbEMsS0FBSSxDQUFDLGlCQUFpQixHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUM7WUFDekMsRUFBRSxDQUFDLENBQUMsT0FBTyxLQUFJLENBQUMsaUJBQWlCLENBQUMscUJBQXFCLEtBQUssVUFBVSxDQUFDLENBQUMsQ0FBQztnQkFDdkUscUJBQUksV0FBVyxHQUFHLEtBQUksQ0FBQyxp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QyxDQUFDLENBQUEsQ0FBQztZQUMzRSxNQUFNLENBQUMsVUFBVSxDQUFDO1NBQ25CO1FBRUQsTUFBTSxDQUFDLGFBQWEsQ0FBQzs7Ozs7SUFHaEIsb0NBQVU7Ozs7UUFDZixJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQzs7Ozs7SUFHWixvQ0FBVTs7OztRQUNmLElBQUksQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDOzs7OztJQUdiLGdDQUFNOzs7O1FBQ1gsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7Ozs7O0lBR1osa0NBQVE7Ozs7UUFDYixNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQzs7Ozs7O0lBR2Isa0NBQVE7Ozs7Y0FBQyxLQUFVO1FBQ3hCLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1FBRW5CLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDOztnQ0EvSmEsU0FBUzs7Z0JBM0NyRCxTQUFTLFNBQUM7b0JBQ1QsUUFBUSxFQUFFLE1BQU0sQ0FBQyxFQUFFO29CQUNuQixRQUFRLEVBQUUsU0FBUztvQkFDbkIsUUFBUSxFQUFFLDAzQ0FvQ1g7aUJBQ0E7Ozs7Z0JBN0RzRSxVQUFVO2dCQUt4RSxtQkFBbUI7OzswQkE2RHpCLEtBQUs7MkJBRUwsS0FBSzs7MEJBcEVSO0VBOERxQyx3QkFBd0I7U0FBaEQsZUFBZSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIE9uSW5pdCwgT25DaGFuZ2VzLCBWaWV3Q2hpbGQsIEV2ZW50RW1pdHRlciwgRWxlbWVudFJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tcG9uZW50RGlhbG9nTW9kZWwsIEJ1dHRvbk1vZGVsIH0gZnJvbSAnLi4vLi9tb2RlbC9Db21wb25lbnREaWFsb2dNb2RlbCc7XG5pbXBvcnQgeyBEaWFsb2dNb2RlbCB9IGZyb20gJy4uLy4vbW9kZWwvRGlhbG9nTW9kZWwnO1xuaW1wb3J0IHsgSURpYWxvZyB9IGZyb20gJy4vSURpYWxvZyc7XG5pbXBvcnQgeyBQaGxveEFwcEluZm8gfSBmcm9tICcuLi8uLi9jb21wb25lbnQvbW9kZWwvUGhsb3hBcHBJbmZvJztcbmltcG9ydCB7IFBobG94QXBwSW5mb1NlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlL1BobG94QXBwSW5mb1NlcnZpY2Uuc2VydmljZSc7XG5pbXBvcnQgeyBBYnN0cmFjdERpYWxvZ0NvbnRyb2xsZXIgfSBmcm9tICcuLi9BYnN0cmFjdERpYWxvZ0NvbnRyb2xsZXInO1xuXG5jb25zdCBUWVBFX05BTUU6IHN0cmluZyA9IFwicGh4LWNvbXBvbmVudC1kaWFsb2dcIjtcblxuLyoqXG4gKiA8cCBzdHlsZT1cInRleHQtaW5kZW50OiAyZW07XCI+XG4gKiBBIDxjb2RlPmNoaWxkLXZpZXc8L2NvZGU+IGNvbXBvbmVudCBjbGFzcyBvZiBbW1BobG94RGlhbG9nXV0gaGFuZGxpbmcgbG9naWMgb2YgPGNvZGU+Y29tcG9uZW50IGRpYWxvZzwvY29kZT4uIFRoaXMgY2xhc3Mgc2hvdWxkIGJlXG4gKiA8Yj5pbnRlcm5hbGx5IHVzZWQgYnkgdGhlIGZyYW1ld29yazwvYj4uIElmIHlvdSBqdXN0IHdhbnQgdG8gc2hvdyBhIDxjb2RlPmNvbXBvbmVudCBkaWFsb2c8L2NvZGU+LiBQbGVhc2Ugc2VlIFtbRGlhbG9nU2VydmljZS5zaG93Q29tcG9uZW50RGlhbG9nXV1cbiAqIGZvciBtb3JlIGluZm8uXG4gKiA8L3A+XG4gKlxuICogQGF1dGhvciBzaGlvcmluLCB0ZWU0Y3V0ZVxuICogQHNlZSBbW1BobG94RGlhbG9nXV1cbiAqIEBzZWUgW1tEaWFsb2dTZXJ2aWNlXV1cbiAqL1xuQENvbXBvbmVudCh7XG4gIG1vZHVsZUlkOiBtb2R1bGUuaWQsXG4gIHNlbGVjdG9yOiBUWVBFX05BTUUsXG4gIHRlbXBsYXRlOiBgPGRpdiBjbGFzcz1cInBoeC1jb21wb25lbnQtZGlhbG9nXCIgW2NsYXNzLnNob3ddPVwiaXNTaG93KClcIj5cblx0PG5nLXRlbXBsYXRlIFtuZ0lmXT1cImdldE1vZGVsKCkgIT0gbnVsbFwiPlxuXHRcdDxkaXYgY2xhc3M9XCJkaWFsb2ctaGVhZGVyXCIgW25nQ2xhc3NdPVwiZ2V0TW9kZWwoKS5oZWFkZXJTdHlsZUNsYXNzXCI+XG5cdFx0XHQ8ZGl2IGNsYXNzPVwid3JhcHBlclwiPlxuXHRcdFx0XHQ8ZGl2PlxuXHRcdFx0XHRcdHt7Z2V0TW9kZWwoKSAhPSBudWxsID8gZ2V0TW9kZWwoKS50aXRsZSA6ICcnfX1cblx0XHRcdFx0PC9kaXY+XG5cdFx0XHRcdDxkaXY+XG5cdFx0XHRcdFx0PGRpdiBjbGFzcz1cInRhYmxlLXdyYXBwZXIgZmx1aWRcIj5cblx0XHRcdFx0XHRcdDxkaXYgY2xhc3M9XCJ0YWJsZS1jZWxsLXdyYXBwZXIgbWlkZGxlXCI+XG5cdFx0XHRcdFx0XHRcdDxoNCBjbGFzcz1cIngtYnRuXCIgKm5nSWY9XCJfaXNTaG93WEJ0bigpXCIgKGNsaWNrKT1cIl9vblhCdG5DbGlja2VkKCRldmVudClcIj5YPC9oND5cblx0XHRcdFx0XHRcdDwvZGl2PlxuXHRcdFx0XHRcdDwvZGl2PlxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdDwvZGl2PlxuXHRcdDwvZGl2PlxuXG5cdFx0PGRpdiBjbGFzcz1cImRpYWxvZy1ib2R5XCIgW25nQ2xhc3NdPVwiZ2V0TW9kZWwoKS5ib2R5U3R5bGVDbGFzc1wiPlxuXHRcdFx0PGRpdj5cblx0XHRcdFx0PHBoeC1jb21wb25lbnQtd3JhcHBlciAjY29tcG9uZW50V3JhcHBlciBbdHlwZV09XCJnZXRNb2RlbCgpLmNvbXBvbmVudFR5cGVcIiBbbW9kZWxdPVwiZ2V0TW9kZWwoKS5tb2RlbFwiIFtoYW5kbGVyXT1cIl9nZXRDb21wb25lbnRIYW5kbGVyKClcIlxuXHRcdFx0XHRcdFtkYXRhXT1cImdldE1vZGVsKCkuZGF0YVwiPjwvcGh4LWNvbXBvbmVudC13cmFwcGVyPlxuXHRcdFx0PC9kaXY+XG5cdFx0PC9kaXY+XG5cblx0XHQ8ZGl2IGNsYXNzPVwiZGlhbG9nLWZvb3RlclwiIFtuZ0NsYXNzXT1cImdldE1vZGVsKCkuZm9vdGVyU3R5bGVDbGFzc1wiPlxuXHRcdFx0PGRpdiBjbGFzcz1cIndyYXBwZXJcIj5cblx0XHRcdFx0PGRpdj5cblx0XHRcdFx0XHQ8bmctdGVtcGxhdGUgW25nSWZdPVwiZ2V0TW9kZWwoKSAhPSBudWxsXCI+XG5cdFx0XHRcdFx0PGRpdiAqbmdGb3I9XCJsZXQgaXRlbSBvZiBnZXREaWFsb2dCdXR0b25zKCk7IGxldCBqID0gaW5kZXhcIlxuXHRcdFx0XHRcdFx0W25nQ2xhc3NdPVwiX2dldERlZmF1bHRJdGVtU3R5bGVDbGFzcyhpdGVtLnN0eWxlQ2xhc3MpXCIgKGNsaWNrKT1cIml0ZW0uaGFuZGxlcigpXCI+e3tpdGVtLmxhYmVsfX08L2Rpdj5cblx0XHRcdFx0XHQ8L25nLXRlbXBsYXRlPlxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdDwvZGl2PlxuXHRcdDwvZGl2PlxuXHQ8L25nLXRlbXBsYXRlPlxuPC9kaXY+XG5gXG59KVxuZXhwb3J0IGNsYXNzIENvbXBvbmVudERpYWxvZyBleHRlbmRzIEFic3RyYWN0RGlhbG9nQ29udHJvbGxlciBpbXBsZW1lbnRzIElEaWFsb2csIE9uSW5pdCwgT25DaGFuZ2VzIHtcblxuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IFRZUEVfTkFNRTogc3RyaW5nID0gVFlQRV9OQU1FO1xuXG4gIEBJbnB1dCgpXG4gIHByaXZhdGUgbW9kZWw6IENvbXBvbmVudERpYWxvZ01vZGVsO1xuICBASW5wdXQoKVxuICBwcml2YXRlIGRpYWxvZzogYW55O1xuICBwcml2YXRlIGNvbXBvbmVudEluc3RhbmNlOiBhbnk7XG4gIHByaXZhdGUgc2hvdzogYm9vbGVhbjtcbiAgcHJpdmF0ZSBwaGxveEFwcEluZm86IFBobG94QXBwSW5mbztcbiAgcHJpdmF0ZSBjb21wb25lbnRIYW5kbGVyOiBGdW5jdGlvbjtcblxuICBjb25zdHJ1Y3RvcihlbGVtZW50UmVmOiBFbGVtZW50UmVmLCBwaGxveEFwcFNlcnZpY2U6IFBobG94QXBwSW5mb1NlcnZpY2UpIHtcbiAgICBzdXBlcihlbGVtZW50UmVmKTtcblxuICAgIHRoaXMuY29tcG9uZW50SW5zdGFuY2UgPSBudWxsO1xuXG4gICAgaWYgKHBobG94QXBwU2VydmljZSAhPSBudWxsKSB7XG4gICAgICBwaGxveEFwcFNlcnZpY2UuZ2V0QXBwSW5mbygpLnRoZW4oKHJlc3VsdCkgPT4ge1xuICAgICAgICB0aGlzLnBobG94QXBwSW5mbyA9IHJlc3VsdDtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMuY29tcG9uZW50SGFuZGxlciA9IChyZXN1bHQ6IGFueSkgPT4ge1xuICAgICAgdGhpcy5jb21wb25lbnRJbnN0YW5jZSA9IHJlc3VsdC5pbnN0YW5jZTtcbiAgICAgIGlmICh0eXBlb2YgdGhpcy5jb21wb25lbnRJbnN0YW5jZS5nZXRCdXR0b25zQ2hhbmdlRXZlbnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgbGV0IGJ0bkNoYW5nZUVWID0gdGhpcy5jb21wb25lbnRJbnN0YW5jZS5nZXRCdXR0b25zQ2hhbmdlRXZlbnQoKTtcbiAgICAgICAgaWYgKGJ0bkNoYW5nZUVWICE9PSBudWxsICYmIHR5cGVvZiBidG5DaGFuZ2VFViAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICBidG5DaGFuZ2VFVi5zdWJzY3JpYmUoKGV2ZW50OiBhbnkpID0+IHtcbiAgICAgICAgICAgIHRoaXMucmVmcmVzaEFjdGlvbkJ1dHRvbnMoKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB0aGlzLnJlZnJlc2hBY3Rpb25CdXR0b25zKCk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMucmVmcmVzaEFjdGlvbkJ1dHRvbnMoKTtcbiAgfVxuXG4gIHB1YmxpYyBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBhbnkpIHtcbiAgICBpZiAoY2hhbmdlc1snbW9kZWwnXSAhPT0gbnVsbCAmJiB0eXBlb2YgY2hhbmdlc1snbW9kZWwnXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHRoaXMucmVmcmVzaEFjdGlvbkJ1dHRvbnMoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGdldFJlc3VsdEZyb21Db21wb25lbnRXcmFwcGVyKCk6IGFueSB7XG4gICAgaWYgKHRoaXMuY29tcG9uZW50SW5zdGFuY2UgIT09IG51bGwgJiYgdHlwZW9mIHRoaXMuY29tcG9uZW50SW5zdGFuY2UgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBpZiAodHlwZW9mIHRoaXMuY29tcG9uZW50SW5zdGFuY2UuZ2V0RGlhbG9nUmVzdWx0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbXBvbmVudEluc3RhbmNlLmdldERpYWxvZ1Jlc3VsdCgpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHByaXZhdGUgcmVmcmVzaEFjdGlvbkJ1dHRvbnMoKTogdm9pZCB7XG4gICAgbGV0IGRpYWxvZ0J1dHRvbnMgPSBbXTtcblxuICAgIGlmICh0aGlzLmNvbXBvbmVudEluc3RhbmNlICE9PSBudWxsICYmIHR5cGVvZiB0aGlzLmNvbXBvbmVudEluc3RhbmNlICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgaWYgKHR5cGVvZiB0aGlzLmNvbXBvbmVudEluc3RhbmNlLmdldERpYWxvZ0J1dHRvbnMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgbGV0IGFjdGlvbkJ0aHMgPSB0aGlzLmNvbXBvbmVudEluc3RhbmNlLmdldERpYWxvZ0J1dHRvbnMoKTtcblxuICAgICAgICBpZiAoYWN0aW9uQnRocyAhPT0gbnVsbCAmJiB0eXBlb2YgYWN0aW9uQnRocyAhPT0gJ3VuZGVmaW5lZCcgJiYgQXJyYXkuaXNBcnJheShhY3Rpb25CdGhzKSkge1xuICAgICAgICAgIGZvciAobGV0IGJ0biBvZiBhY3Rpb25CdGhzKSB7XG4gICAgICAgICAgICBkaWFsb2dCdXR0b25zLnB1c2goYnRuKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZGlhbG9nQnV0dG9ucy5sZW5ndGggPD0gMCkge1xuICAgICAgaWYgKHRoaXMubW9kZWwgIT09IG51bGwgJiYgdHlwZW9mIHRoaXMubW9kZWwgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIGlmICh0aGlzLm1vZGVsLmJ1dHRvbk1vZGVscyAhPT0gbnVsbCAmJiB0eXBlb2YgdGhpcy5tb2RlbC5idXR0b25Nb2RlbHMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgZm9yIChsZXQgYnRuIG9mIHRoaXMubW9kZWwuYnV0dG9uTW9kZWxzKSB7XG4gICAgICAgICAgICBkaWFsb2dCdXR0b25zLnB1c2goYnRuKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBhdXRvIGFkZCBidG5cbiAgICBpZiAoZGlhbG9nQnV0dG9ucy5sZW5ndGggPD0gMCkge1xuICAgICAgbGV0IGNhbmNlbEhhbmRsZXI6IEZ1bmN0aW9uID0gKCkgPT4ge1xuICAgICAgICBsZXQgcmVzdWx0ID0gLTE7XG4gICAgICAgIGlmICh0aGlzLmRpYWxvZyAhPT0gbnVsbCAmJiB0eXBlb2YgdGhpcy5kaWFsb2cgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgdGhpcy5kaWFsb2cuaGlkZURpYWxvZygpO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgICAgZGlhbG9nQnV0dG9ucy5wdXNoKG5ldyBDb21wb25lbnREaWFsb2dNb2RlbC5CdXR0b25Nb2RlbCh0aGlzLmdldEkxOE5NZXNzYWdlKCdDQU5DRUwnKSwgbnVsbCwgY2FuY2VsSGFuZGxlciwgWydkaWFsb2ctYnRuJywgJ2NhbmNlbCddKSk7XG4gICAgfVxuXG4gICAgdGhpcy5kaWFsb2dCdXR0b25zID0gZGlhbG9nQnV0dG9ucztcbiAgfVxuXG4gIHByaXZhdGUgZ2V0STE4Tk1lc3NhZ2Uoa2V5OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGlmICh0aGlzLnBobG94QXBwSW5mbyAhPSBudWxsICYmIHRoaXMucGhsb3hBcHBJbmZvLmkxOG4gIT0gbnVsbCkge1xuICAgICAgaWYgKHRoaXMucGhsb3hBcHBJbmZvLmkxOG5ba2V5XSAhPT0gbnVsbCAmJiB0eXBlb2YgdGhpcy5waGxveEFwcEluZm8uaTE4bltrZXldICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICByZXR1cm4gdGhpcy5waGxveEFwcEluZm8uaTE4bltrZXldO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ga2V5O1xuICB9XG5cbiAgcHVibGljIF9vblhCdG5DbGlja2VkKCRldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5tb2RlbCAhPT0gbnVsbCAmJiB0eXBlb2YgdGhpcy5tb2RlbCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGlmICh0aGlzLm1vZGVsLmNsb3NlSGFuZGxlciAhPT0gbnVsbCAmJiB0eXBlb2YgdGhpcy5tb2RlbC5jbG9zZUhhbmRsZXIgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5tb2RlbC5jbG9zZUhhbmRsZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICB0aGlzLm1vZGVsLmNsb3NlSGFuZGxlci5jYWxsKG51bGwsICRldmVudCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwdWJsaWMgX2lzU2hvd1hCdG4oKTogYm9vbGVhbiB7XG4gICAgaWYgKHRoaXMubW9kZWwgIT09IG51bGwgJiYgdHlwZW9mIHRoaXMubW9kZWwgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBpZiAodGhpcy5tb2RlbC5jbG9zZUhhbmRsZXIgIT09IG51bGwgJiYgdHlwZW9mIHRoaXMubW9kZWwuY2xvc2VIYW5kbGVyICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMubW9kZWwuY2xvc2VIYW5kbGVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBwdWJsaWMgX2dldENvbXBvbmVudEhhbmRsZXIoKTogRnVuY3Rpb24ge1xuICAgIHJldHVybiB0aGlzLmNvbXBvbmVudEhhbmRsZXI7XG4gIH1cblxuICBwdWJsaWMgX2dldERlZmF1bHRJdGVtU3R5bGVDbGFzcyhzdHlsZUNsYXNzOiBTdHJpbmdbXSk6IFN0cmluZ1tde1xuICAgIGxldCBkZWZTdHlsZUNsYXNzID0gW1wiZGlhbG9nLWJ0blwiXTtcblxuICAgIGlmKHN0eWxlQ2xhc3MgIT09IG51bGwgJiYgc3R5bGVDbGFzcyAhPT0gdW5kZWZpbmVkICYmIHN0eWxlQ2xhc3MubGVuZ3RoID4gMCl7XG4gICAgICByZXR1cm4gc3R5bGVDbGFzcztcbiAgICB9XG5cbiAgICByZXR1cm4gZGVmU3R5bGVDbGFzcztcbiAgfVxuXG4gIHB1YmxpYyBzaG93RGlhbG9nKCk6IHZvaWQge1xuICAgIHRoaXMuc2hvdyA9IHRydWU7XG4gIH1cblxuICBwdWJsaWMgaGlkZURpYWxvZygpOiB2b2lkIHtcbiAgICB0aGlzLnNob3cgPSBmYWxzZTtcbiAgfVxuXG4gIHB1YmxpYyBpc1Nob3coKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuc2hvdztcbiAgfVxuXG4gIHB1YmxpYyBnZXRNb2RlbCgpOiBhbnkge1xuICAgIHJldHVybiB0aGlzLm1vZGVsO1xuICB9XG5cbiAgcHVibGljIHNldE1vZGVsKG1vZGVsOiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLm1vZGVsID0gbW9kZWw7XG5cbiAgICB0aGlzLnJlZnJlc2hBY3Rpb25CdXR0b25zKCk7XG4gIH1cbn1cbiJdfQ==