ngx-modialog-7
Version:
Modal / Dialog for Angular
465 lines • 34 kB
JavaScript
/**
* @fileoverview added by tsickle
* Generated from: lib/overlay/overlay.component.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { __extends } from "tslib";
import { Component, ElementRef, ViewChild, ViewContainerRef, ViewEncapsulation, Renderer2, TemplateRef, HostListener } from '@angular/core';
import { PromiseCompleter, supportsKey } from '../framework/utils';
import { DialogRef } from '../models/dialog-ref';
import { BaseDynamicComponent } from '../components/index';
// TODO: use DI factory for this.
// TODO: consolidate dup code
/** @type {?} */
var isDoc = !(typeof document === 'undefined' || !document);
/**
* @record
*/
export function EmbedComponentConfig() { }
if (false) {
/** @type {?} */
EmbedComponentConfig.prototype.component;
/** @type {?|undefined} */
EmbedComponentConfig.prototype.projectableNodes;
}
/**
* Represents the modal overlay.
*/
var ModalOverlay = /** @class */ (function (_super) {
__extends(ModalOverlay, _super);
function ModalOverlay(dialogRef, vcr, el, renderer) {
var _this = _super.call(this, el, renderer) || this;
_this.dialogRef = dialogRef;
_this.vcr = vcr;
_this.activateAnimationListener();
return _this;
}
/**
* @internal
*/
/**
* \@internal
* @template T
* @param {?} content
* @return {?}
*/
ModalOverlay.prototype.getProjectables = /**
* \@internal
* @template T
* @param {?} content
* @return {?}
*/
function (content) {
/** @type {?} */
var nodes;
if (typeof content === 'string') {
nodes = [[this.renderer.createText("" + content)]];
}
else if (content instanceof TemplateRef) {
nodes = [this.vcr.createEmbeddedView(content, { $implicit: this.dialogRef.context, dialogRef: this.dialogRef }).rootNodes];
}
else {
nodes = [this.embedComponent({ component: content }).rootNodes];
}
return nodes;
};
/**
* @param {?} config
* @return {?}
*/
ModalOverlay.prototype.embedComponent = /**
* @param {?} config
* @return {?}
*/
function (config) {
/** @type {?} */
var ctx = (/** @type {?} */ (config));
return this.vcr.createEmbeddedView(this.template, (/** @type {?} */ ({
$implicit: ctx
})));
};
/**
* @template T
* @param {?} type
* @param {?=} projectableNodes
* @return {?}
*/
ModalOverlay.prototype.addComponent = /**
* @template T
* @param {?} type
* @param {?=} projectableNodes
* @return {?}
*/
function (type, projectableNodes) {
if (projectableNodes === void 0) { projectableNodes = []; }
return _super.prototype._addComponent.call(this, {
component: type,
vcRef: this.innerVcr,
projectableNodes: projectableNodes
});
};
/**
* @return {?}
*/
ModalOverlay.prototype.fullscreen = /**
* @return {?}
*/
function () {
var _this = this;
/** @type {?} */
var style = {
position: 'fixed',
top: 0,
left: 0,
bottom: 0,
right: 0,
'z-index': 1500
};
Object.keys(style).forEach((/**
* @template THIS
* @this {THIS}
* @param {?} k
* @return {THIS}
*/
function (k) { return _this.setStyle(k, style[k]); }));
};
/**
* @return {?}
*/
ModalOverlay.prototype.insideElement = /**
* @return {?}
*/
function () {
var _this = this;
/** @type {?} */
var style = {
position: 'absolute',
overflow: 'hidden',
width: '100%',
height: '100%',
top: 0,
left: 0,
bottom: 0,
right: 0
};
Object.keys(style).forEach((/**
* @template THIS
* @this {THIS}
* @param {?} k
* @return {THIS}
*/
function (k) { return _this.setStyle(k, style[k]); }));
};
/**
* Set a specific inline style for the container of the whole dialog component
* The dialog component root element is the host of this component, it contains only 1 direct
* child which is the container.
*
* Structure:
*
* ```html
* <modal-overlay>
* <div>
* <!-- BACKDROP ELEMENT -->
* <!-- DIALOG CONTAINER ELEMENT -->
* </div>
* </modal-overlay>
* ```
*
* @param prop The style key
* @param value The value, undefined to remove
*/
/**
* Set a specific inline style for the container of the whole dialog component
* The dialog component root element is the host of this component, it contains only 1 direct
* child which is the container.
*
* Structure:
*
* ```html
* <modal-overlay>
* <div>
* <!-- BACKDROP ELEMENT -->
* <!-- DIALOG CONTAINER ELEMENT -->
* </div>
* </modal-overlay>
* ```
*
* @template THIS
* @this {THIS}
* @param {?} prop The style key
* @param {?} value The value, undefined to remove
* @return {THIS}
*/
ModalOverlay.prototype.setContainerStyle = /**
* Set a specific inline style for the container of the whole dialog component
* The dialog component root element is the host of this component, it contains only 1 direct
* child which is the container.
*
* Structure:
*
* ```html
* <modal-overlay>
* <div>
* <!-- BACKDROP ELEMENT -->
* <!-- DIALOG CONTAINER ELEMENT -->
* </div>
* </modal-overlay>
* ```
*
* @template THIS
* @this {THIS}
* @param {?} prop The style key
* @param {?} value The value, undefined to remove
* @return {THIS}
*/
function (prop, value) {
(/** @type {?} */ (this)).renderer.setStyle((/** @type {?} */ (this)).container.nativeElement, prop, value);
return (/** @type {?} */ (this));
};
/**
* Define an element that click inside it will not trigger modal close.
* Since events bubble, clicking on a dialog will bubble up to the overlay, a plugin
* must define an element that represent the dialog, the overlay will make sure no to close when
* it was clicked.
* @param element
*/
/**
* Define an element that click inside it will not trigger modal close.
* Since events bubble, clicking on a dialog will bubble up to the overlay, a plugin
* must define an element that represent the dialog, the overlay will make sure no to close when
* it was clicked.
* @param {?} element
* @return {?}
*/
ModalOverlay.prototype.setClickBoundary = /**
* Define an element that click inside it will not trigger modal close.
* Since events bubble, clicking on a dialog will bubble up to the overlay, a plugin
* must define an element that represent the dialog, the overlay will make sure no to close when
* it was clicked.
* @param {?} element
* @return {?}
*/
function (element) {
var _this = this;
/** @type {?} */
var target;
/** @type {?} */
var elListener = (/**
* @param {?} event
* @return {?}
*/
function (event) { return target = (/** @type {?} */ (event.target)); });
/** @type {?} */
var docListener = (/**
* @param {?} event
* @return {?}
*/
function (event) {
if (_this.dialogRef.context.isBlocking || !_this.dialogRef.overlay.isTopMost(_this.dialogRef)) {
return;
}
/** @type {?} */
var current = event.target;
// on click, this will hit.
if (current === target) {
return;
}
// on mouse down -> drag -> release the current might not be 'target', it might be
// a sibling or a child (i.e: not part of the tree-up direction). It might also be a release
// outside the dialog... so we compare to the boundary element
do {
if (current === element) {
return;
}
} while (current.parentNode && (current = current.parentNode));
_this.dialogRef.dismiss();
});
if (isDoc) {
this.dialogRef.onDestroy.subscribe((/**
* @return {?}
*/
function () {
element.removeEventListener('click', elListener, false);
element.removeEventListener('touchstart', elListener, false);
document.removeEventListener('click', docListener, false);
document.removeEventListener('touchend', docListener, false);
}));
setTimeout((/**
* @return {?}
*/
function () {
element.addEventListener('mousedown', elListener, false);
element.addEventListener('touchstart', docListener, false);
document.addEventListener('click', docListener, false);
document.addEventListener('touchend', docListener, false);
}));
}
};
/**
* Temp workaround for animation where destruction of the top level component does not
* trigger child animations. Solution should be found either in animation module or in design
* of the modal component tree.
*/
/**
* Temp workaround for animation where destruction of the top level component does not
* trigger child animations. Solution should be found either in animation module or in design
* of the modal component tree.
* @return {?}
*/
ModalOverlay.prototype.canDestroy = /**
* Temp workaround for animation where destruction of the top level component does not
* trigger child animations. Solution should be found either in animation module or in design
* of the modal component tree.
* @return {?}
*/
function () {
/** @type {?} */
var completer = new PromiseCompleter();
if (!Array.isArray(this.beforeDestroyHandlers)) {
completer.resolve();
}
else {
// run destroy notification but protect against halt.
/** @type {?} */
var id_1 = setTimeout((/**
* @return {?}
*/
function () {
id_1 = null;
completer.reject();
}), 1000);
/** @type {?} */
var resolve = (/**
* @return {?}
*/
function () {
if (id_1 === null) {
return;
}
clearTimeout(id_1);
completer.resolve();
});
Promise.all(this.beforeDestroyHandlers.map((/**
* @param {?} fn
* @return {?}
*/
function (fn) { return fn(); })))
.then(resolve)
.catch(resolve);
}
return completer.promise;
};
/**
* A handler running before destruction of the overlay
* use to delay destruction due to animation.
* This is part of the workaround for animation, see canDestroy.
*
* NOTE: There is no guarantee that the listeners will fire, use dialog.onDestory for that.
* @param fn
*/
/**
* A handler running before destruction of the overlay
* use to delay destruction due to animation.
* This is part of the workaround for animation, see canDestroy.
*
* NOTE: There is no guarantee that the listeners will fire, use dialog.onDestory for that.
* @param {?} fn
* @return {?}
*/
ModalOverlay.prototype.beforeDestroy = /**
* A handler running before destruction of the overlay
* use to delay destruction due to animation.
* This is part of the workaround for animation, see canDestroy.
*
* NOTE: There is no guarantee that the listeners will fire, use dialog.onDestory for that.
* @param {?} fn
* @return {?}
*/
function (fn) {
if (!this.beforeDestroyHandlers) {
this.beforeDestroyHandlers = [];
}
this.beforeDestroyHandlers.push(fn);
};
/**
* @param {?} event
* @return {?}
*/
ModalOverlay.prototype.documentKeypress = /**
* @param {?} event
* @return {?}
*/
function (event) {
// check that this modal is the last in the stack.
if (!this.dialogRef.overlay.isTopMost(this.dialogRef)) {
return;
}
if (supportsKey(event.keyCode, (/** @type {?} */ (this.dialogRef.context.keyboard)))) {
this.dialogRef.dismiss();
}
};
/**
* @return {?}
*/
ModalOverlay.prototype.ngOnDestroy = /**
* @return {?}
*/
function () {
_super.prototype.ngOnDestroy.call(this);
if (this.dialogRef.destroyed !== true) {
// if we're here the overlay is destroyed by an external event that is not user invoked.
// i.e: The user did no call dismiss or close and dialogRef.destroy() did not invoke.
// this will happen when routing or killing an element containing a blocked overlay (ngIf)
// we bail out, i.e gracefully shutting down.
this.dialogRef.bailOut();
}
};
ModalOverlay.decorators = [
{ type: Component, args: [{
// tslint:disable-next-line:component-selector
selector: 'modal-overlay',
encapsulation: ViewEncapsulation.None,
template: "<div #container>\n <ng-template #innerView></ng-template>\n</div>\n<ng-template #template let-ctx>\n <ng-container *ngComponentOutlet=\"ctx.component; injector: ctx.injector; content: ctx.projectableNodes\"></ng-container>\n</ng-template>"
}] }
];
/** @nocollapse */
ModalOverlay.ctorParameters = function () { return [
{ type: DialogRef },
{ type: ViewContainerRef },
{ type: ElementRef },
{ type: Renderer2 }
]; };
ModalOverlay.propDecorators = {
container: [{ type: ViewChild, args: ['container', { read: ElementRef, static: true },] }],
innerVcr: [{ type: ViewChild, args: ['innerView', { read: ViewContainerRef, static: true },] }],
template: [{ type: ViewChild, args: ['template', { static: true },] }],
documentKeypress: [{ type: HostListener, args: ['body:keydown', ['$event'],] }]
};
return ModalOverlay;
}(BaseDynamicComponent));
export { ModalOverlay };
if (false) {
/**
* @type {?}
* @private
*/
ModalOverlay.prototype.beforeDestroyHandlers;
/** @type {?} */
ModalOverlay.prototype.container;
/** @type {?} */
ModalOverlay.prototype.innerVcr;
/** @type {?} */
ModalOverlay.prototype.template;
/**
* @type {?}
* @private
*/
ModalOverlay.prototype.dialogRef;
/**
* @type {?}
* @private
*/
ModalOverlay.prototype.vcr;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3ZlcmxheS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZ3gtbW9kaWFsb2ctNy8iLCJzb3VyY2VzIjpbImxpYi9vdmVybGF5L292ZXJsYXkuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUVBLE9BQU8sRUFDTCxTQUFTLEVBRVQsVUFBVSxFQUdWLFNBQVMsRUFDVCxnQkFBZ0IsRUFDaEIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxXQUFXLEVBQUUsWUFBWSxFQUMxQixNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsV0FBVyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDbkUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBRWpELE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDOzs7O0lBSXJELEtBQUssR0FBWSxDQUFDLENBQUMsT0FBTyxRQUFRLEtBQUssV0FBVyxJQUFJLENBQUMsUUFBUSxDQUFDOzs7O0FBRXRFLDBDQUdDOzs7SUFGQyx5Q0FBZTs7SUFDZixnREFBMkI7Ozs7O0FBTTdCO0lBT2tDLGdDQUFvQjtJQU9wRCxzQkFBb0IsU0FBeUIsRUFDekIsR0FBcUIsRUFDN0IsRUFBYyxFQUNkLFFBQW1CO1FBSC9CLFlBSUUsa0JBQU0sRUFBRSxFQUFFLFFBQVEsQ0FBQyxTQUVwQjtRQU5tQixlQUFTLEdBQVQsU0FBUyxDQUFnQjtRQUN6QixTQUFHLEdBQUgsR0FBRyxDQUFrQjtRQUl2QyxLQUFJLENBQUMseUJBQXlCLEVBQUUsQ0FBQzs7SUFDbkMsQ0FBQztJQUVEOztPQUVHOzs7Ozs7O0lBQ0gsc0NBQWU7Ozs7OztJQUFmLFVBQW1CLE9BQXlCOztZQUV0QyxLQUFZO1FBQ2hCLElBQUksT0FBTyxPQUFPLEtBQUssUUFBUSxFQUFFO1lBQy9CLEtBQUssR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsS0FB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Q3hDOzs7O2dCQXJCUSxTQUFTO2dCQVBoQixnQkFBZ0I7Z0JBSmhCLFVBQVU7Z0JBTVYsU0FBUzs7OzRCQStCUixTQUFTLFNBQUMsV0FBVyxFQUFFLEVBQUMsSUFBSSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFDOzJCQUN2RCxTQUFTLFNBQUMsV0FBVyxFQUFFLEVBQUMsSUFBSSxFQUFFLGdCQUFnQixFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7MkJBQzlELFNBQVMsU0FBQyxVQUFVLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO21DQW1NdEMsWUFBWSxTQUFDLGNBQWMsRUFBRSxDQUFDLFFBQVEsQ0FBQzs7SUF1QjFDLG1CQUFDO0NBQUEsQUF0T0QsQ0FPa0Msb0JBQW9CLEdBK05yRDtTQS9OWSxZQUFZOzs7Ozs7SUFDdkIsNkNBQTBEOztJQUUxRCxpQ0FBdUY7O0lBQ3ZGLGdDQUFtRzs7SUFDbkcsZ0NBQTJFOzs7OztJQUUvRCxpQ0FBaUM7Ozs7O0lBQ2pDLDJCQUE2QiIsInNvdXJjZXNDb250ZW50IjpbImRlY2xhcmUgY29uc3QgY2xlYXJUaW1lb3V0OiBhbnk7XG5cbmltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgQ29tcG9uZW50UmVmLFxuICBFbGVtZW50UmVmLFxuICBFbWJlZGRlZFZpZXdSZWYsXG4gIEluamVjdG9yLFxuICBWaWV3Q2hpbGQsXG4gIFZpZXdDb250YWluZXJSZWYsXG4gIFZpZXdFbmNhcHN1bGF0aW9uLFxuICBSZW5kZXJlcjIsXG4gIFRlbXBsYXRlUmVmLCBIb3N0TGlzdGVuZXJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IFByb21pc2VDb21wbGV0ZXIsIHN1cHBvcnRzS2V5IH0gZnJvbSAnLi4vZnJhbWV3b3JrL3V0aWxzJztcbmltcG9ydCB7IERpYWxvZ1JlZiB9IGZyb20gJy4uL21vZGVscy9kaWFsb2ctcmVmJztcbmltcG9ydCB7IENvbnRhaW5lckNvbnRlbnQgfSBmcm9tICcuLi9tb2RlbHMvdG9rZW5zJztcbmltcG9ydCB7IEJhc2VEeW5hbWljQ29tcG9uZW50IH0gZnJvbSAnLi4vY29tcG9uZW50cy9pbmRleCc7XG5cbi8vIFRPRE86IHVzZSBESSBmYWN0b3J5IGZvciB0aGlzLlxuLy8gVE9ETzogY29uc29saWRhdGUgZHVwIGNvZGVcbmNvbnN0IGlzRG9jOiBib29sZWFuID0gISh0eXBlb2YgZG9jdW1lbnQgPT09ICd1bmRlZmluZWQnIHx8ICFkb2N1bWVudCk7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRW1iZWRDb21wb25lbnRDb25maWcge1xuICBjb21wb25lbnQ6IGFueTtcbiAgcHJvamVjdGFibGVOb2Rlcz86IGFueVtdW107XG59XG5cbi8qKlxuICogUmVwcmVzZW50cyB0aGUgbW9kYWwgb3ZlcmxheS5cbiAqL1xuQENvbXBvbmVudCh7XG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpjb21wb25lbnQtc2VsZWN0b3JcbiAgc2VsZWN0b3I6ICdtb2RhbC1vdmVybGF5JyxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgdGVtcGxhdGVVcmw6ICcuL292ZXJsYXkuY29tcG9uZW50Lmh0bWwnXG59KVxuLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmNvbXBvbmVudC1jbGFzcy1zdWZmaXhcbmV4cG9ydCBjbGFzcyBNb2RhbE92ZXJsYXkgZXh0ZW5kcyBCYXNlRHluYW1pY0NvbXBvbmVudCB7XG4gIHByaXZhdGUgYmVmb3JlRGVzdHJveUhhbmRsZXJzOiBBcnJheTwoKSA9PiBQcm9taXNlPHZvaWQ+PjtcblxuICBAVmlld0NoaWxkKCdjb250YWluZXInLCB7cmVhZDogRWxlbWVudFJlZiwgc3RhdGljOiB0cnVlfSkgcHVibGljIGNvbnRhaW5lcjogRWxlbWVudFJlZjtcbiAgQFZpZXdDaGlsZCgnaW5uZXJWaWV3Jywge3JlYWQ6IFZpZXdDb250YWluZXJSZWYsIHN0YXRpYzogdHJ1ZSB9KSBwdWJsaWMgaW5uZXJWY3I6IFZpZXdDb250YWluZXJSZWY7XG4gIEBWaWV3Q2hpbGQoJ3RlbXBsYXRlJywgeyBzdGF0aWM6IHRydWUgfSkgcHVibGljIHRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+O1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgZGlhbG9nUmVmOiBEaWFsb2dSZWY8YW55PixcbiAgICAgICAgICAgICAgcHJpdmF0ZSB2Y3I6IFZpZXdDb250YWluZXJSZWYsXG4gICAgICAgICAgICAgIGVsOiBFbGVtZW50UmVmLFxuICAgICAgICAgICAgICByZW5kZXJlcjogUmVuZGVyZXIyKSB7XG4gICAgc3VwZXIoZWwsIHJlbmRlcmVyKTtcbiAgICB0aGlzLmFjdGl2YXRlQW5pbWF0aW9uTGlzdGVuZXIoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIGdldFByb2plY3RhYmxlczxUPihjb250ZW50OiBDb250YWluZXJDb250ZW50KTogYW55W11bXSB7XG5cbiAgICBsZXQgbm9kZXM6IGFueVtdO1xuICAgIGlmICh0eXBlb2YgY29udGVudCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIG5vZGVzID0gW1t0aGlzLnJlbmRlcmVyLmNyZWF0ZVRleHQoYCR7Y29udGVudH1gKV1dO1xuICAgIH0gZWxzZSBpZiAoY29udGVudCBpbnN0YW5jZW9mIFRlbXBsYXRlUmVmKSB7XG4gICAgICBub2RlcyA9IFt0aGlzLnZjci5jcmVhdGVFbWJlZGRlZFZpZXcoY29udGVudCwgeyRpbXBsaWNpdDogdGhpcy5kaWFsb2dSZWYuY29udGV4dCwgZGlhbG9nUmVmOiB0aGlzLmRpYWxvZ1JlZn0pLnJvb3ROb2Rlc107XG4gICAgfSBlbHNlIHtcbiAgICAgIG5vZGVzID0gW3RoaXMuZW1iZWRDb21wb25lbnQoe2NvbXBvbmVudDogY29udGVudH0pLnJvb3ROb2Rlc107XG4gICAgfVxuXG4gICAgcmV0dXJuIG5vZGVzO1xuICB9XG5cbiAgZW1iZWRDb21wb25lbnQoY29uZmlnOiBFbWJlZENvbXBvbmVudENvbmZpZyk6IEVtYmVkZGVkVmlld1JlZjxFbWJlZENvbXBvbmVudENvbmZpZz4ge1xuICAgIGNvbnN0IGN0eDogRW1iZWRDb21wb25lbnRDb25maWcgJiB7IGluamVjdG9yOiBJbmplY3RvciB9ID0gPGFueT5jb25maWc7XG5cbiAgICByZXR1cm4gdGhpcy52Y3IuY3JlYXRlRW1iZWRkZWRWaWV3KHRoaXMudGVtcGxhdGUsIDxhbnk+e1xuICAgICAgJGltcGxpY2l0OiBjdHhcbiAgICB9KTtcbiAgfVxuXG4gIGFkZENvbXBvbmVudDxUPih0eXBlOiBhbnksIHByb2plY3RhYmxlTm9kZXM6IGFueVtdW10gPSBbXSk6IENvbXBvbmVudFJlZjxUPiB7XG4gICAgcmV0dXJuIHN1cGVyLl9hZGRDb21wb25lbnQ8VD4oe1xuICAgICAgY29tcG9uZW50OiB0eXBlLFxuICAgICAgdmNSZWY6IHRoaXMuaW5uZXJWY3IsXG4gICAgICBwcm9qZWN0YWJsZU5vZGVzXG4gICAgfSk7XG4gIH1cblxuICBmdWxsc2NyZWVuKCk6IHZvaWQge1xuICAgIGNvbnN0IHN0eWxlID0ge1xuICAgICAgcG9zaXRpb246ICdmaXhlZCcsXG4gICAgICB0b3A6IDAsXG4gICAgICBsZWZ0OiAwLFxuICAgICAgYm90dG9tOiAwLFxuICAgICAgcmlnaHQ6IDAsXG4gICAgICAnei1pbmRleCc6IDE1MDBcbiAgICB9O1xuICAgIE9iamVjdC5rZXlzKHN0eWxlKS5mb3JFYWNoKGsgPT4gdGhpcy5zZXRTdHlsZShrLCBzdHlsZVtrXSkpO1xuICB9XG5cbiAgaW5zaWRlRWxlbWVudCgpOiB2b2lkIHtcbiAgICBjb25zdCBzdHlsZSA9IHtcbiAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnLFxuICAgICAgb3ZlcmZsb3c6ICdoaWRkZW4nLFxuICAgICAgd2lkdGg6ICcxMDAlJyxcbiAgICAgIGhlaWdodDogJzEwMCUnLFxuICAgICAgdG9wOiAwLFxuICAgICAgbGVmdDogMCxcbiAgICAgIGJvdHRvbTogMCxcbiAgICAgIHJpZ2h0OiAwXG4gICAgfTtcbiAgICBPYmplY3Qua2V5cyhzdHlsZSkuZm9yRWFjaChrID0+IHRoaXMuc2V0U3R5bGUoaywgc3R5bGVba10pKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgYSBzcGVjaWZpYyBpbmxpbmUgc3R5bGUgZm9yIHRoZSBjb250YWluZXIgb2YgdGhlIHdob2xlIGRpYWxvZyBjb21wb25lbnRcbiAgICogVGhlIGRpYWxvZyBjb21wb25lbnQgcm9vdCBlbGVtZW50IGlzIHRoZSBob3N0IG9mIHRoaXMgY29tcG9uZW50LCBpdCBjb250YWlucyBvbmx5IDEgZGlyZWN0XG4gICAqIGNoaWxkIHdoaWNoIGlzIHRoZSBjb250YWluZXIuXG4gICAqXG4gICAqIFN0cnVjdHVyZTpcbiAgICpcbiAgICogYGBgaHRtbFxuICAgKiA8bW9kYWwtb3ZlcmxheT5cbiAgICogICA8ZGl2PlxuICAgKiAgICAgPCEtLSBCQUNLRFJPUCBFTEVNRU5UIC0tPlxuICAgKiAgICAgPCEtLSBESUFMT0cgQ09OVEFJTkVSIEVMRU1FTlQgLS0+XG4gICAqICAgPC9kaXY+XG4gICAqIDwvbW9kYWwtb3ZlcmxheT5cbiAgICogYGBgXG4gICAqXG4gICAqIEBwYXJhbSBwcm9wIFRoZSBzdHlsZSBrZXlcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZSwgdW5kZWZpbmVkIHRvIHJlbW92ZVxuICAgKi9cbiAgc2V0Q29udGFpbmVyU3R5bGUocHJvcDogc3RyaW5nLCB2YWx1ZTogc3RyaW5nKTogdGhpcyB7XG4gICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZSh0aGlzLmNvbnRhaW5lci5uYXRpdmVFbGVtZW50LCBwcm9wLCB2YWx1ZSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogRGVmaW5lIGFuIGVsZW1lbnQgdGhhdCBjbGljayBpbnNpZGUgaXQgd2lsbCBub3QgdHJpZ2dlciBtb2RhbCBjbG9zZS5cbiAgICogU2luY2UgZXZlbnRzIGJ1YmJsZSwgY2xpY2tpbmcgb24gYSBkaWFsb2cgd2lsbCBidWJibGUgdXAgdG8gdGhlIG92ZXJsYXksIGEgcGx1Z2luXG4gICAqIG11c3QgZGVmaW5lIGFuIGVsZW1lbnQgdGhhdCByZXByZXNlbnQgdGhlIGRpYWxvZywgdGhlIG92ZXJsYXkgd2lsbCBtYWtlIHN1cmUgbm8gdG8gY2xvc2Ugd2hlblxuICAgKiBpdCB3YXMgY2xpY2tlZC5cbiAgICogQHBhcmFtIGVsZW1lbnRcbiAgICovXG4gIHNldENsaWNrQm91bmRhcnkoZWxlbWVudDogRWxlbWVudCk6IHZvaWQge1xuICAgIGxldCB0YXJnZXQ6IEVsZW1lbnQ7XG4gICAgY29uc3QgZWxMaXN0ZW5lciA9IGV2ZW50ID0+IHRhcmdldCA9IGV2ZW50LnRhcmdldCBhcyBhbnk7XG4gICAgY29uc3QgZG9jTGlzdGVuZXIgPSBldmVudCA9PiB7XG4gICAgICBpZiAodGhpcy5kaWFsb2dSZWYuY29udGV4dC5pc0Jsb2NraW5nIHx8ICF0aGlzLmRpYWxvZ1JlZi5vdmVybGF5LmlzVG9wTW9zdCh0aGlzLmRpYWxvZ1JlZikpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBsZXQgY3VycmVudDogYW55ID0gZXZlbnQudGFyZ2V0O1xuXG4gICAgICAvLyBvbiBjbGljaywgdGhpcyB3aWxsIGhpdC5cbiAgICAgIGlmIChjdXJyZW50ID09PSB0YXJnZXQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBvbiBtb3VzZSBkb3duIC0+IGRyYWcgLT4gcmVsZWFzZSB0aGUgY3VycmVudCBtaWdodCBub3QgYmUgJ3RhcmdldCcsIGl0IG1pZ2h0IGJlXG4gICAgICAvLyBhIHNpYmxpbmcgb3IgYSBjaGlsZCAoaS5lOiBub3QgcGFydCBvZiB0aGUgdHJlZS11cCBkaXJlY3Rpb24pLiBJdCBtaWdodCBhbHNvIGJlIGEgcmVsZWFzZVxuICAgICAgLy8gb3V0c2lkZSB0aGUgZGlhbG9nLi4uIHNvIHdlIGNvbXBhcmUgdG8gdGhlIGJvdW5kYXJ5IGVsZW1lbnRcbiAgICAgIGRvIHtcbiAgICAgICAgaWYgKGN1cnJlbnQgPT09IGVsZW1lbnQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH0gd2hpbGUgKGN1cnJlbnQucGFyZW50Tm9kZSAmJiAoY3VycmVudCA9IGN1cnJlbnQucGFyZW50Tm9kZSkpO1xuICAgICAgdGhpcy5kaWFsb2dSZWYuZGlzbWlzcygpO1xuICAgIH07XG5cbiAgICBpZiAoaXNEb2MpIHtcbiAgICAgIHRoaXMuZGlhbG9nUmVmLm9uRGVzdHJveS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZWxMaXN0ZW5lciwgZmFsc2UpO1xuICAgICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCBlbExpc3RlbmVyLCBmYWxzZSk7XG4gICAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZG9jTGlzdGVuZXIsIGZhbHNlKTtcbiAgICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2hlbmQnLCBkb2NMaXN0ZW5lciwgZmFsc2UpO1xuICAgICAgfSk7XG5cblxuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgZWxMaXN0ZW5lciwgZmFsc2UpO1xuICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCBkb2NMaXN0ZW5lciwgZmFsc2UpO1xuICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGRvY0xpc3RlbmVyLCBmYWxzZSk7XG4gICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgZG9jTGlzdGVuZXIsIGZhbHNlKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUZW1wIHdvcmthcm91bmQgZm9yIGFuaW1hdGlvbiB3aGVyZSBkZXN0cnVjdGlvbiBvZiB0aGUgdG9wIGxldmVsIGNvbXBvbmVudCBkb2VzIG5vdFxuICAgKiB0cmlnZ2VyIGNoaWxkIGFuaW1hdGlvbnMuIFNvbHV0aW9uIHNob3VsZCBiZSBmb3VuZCBlaXRoZXIgaW4gYW5pbWF0aW9uIG1vZHVsZSBvciBpbiBkZXNpZ25cbiAgICogb2YgdGhlIG1vZGFsIGNvbXBvbmVudCB0cmVlLlxuICAgKi9cbiAgY2FuRGVzdHJveSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBjb21wbGV0ZXIgPSBuZXcgUHJvbWlzZUNvbXBsZXRlcjx2b2lkPigpO1xuXG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHRoaXMuYmVmb3JlRGVzdHJveUhhbmRsZXJzKSkge1xuICAgICAgY29tcGxldGVyLnJlc29sdmUoKTtcbiAgICB9IGVsc2Uge1xuXG4gICAgICAvLyBydW4gZGVzdHJveSBub3RpZmljYXRpb24gYnV0IHByb3RlY3QgYWdhaW5zdCBoYWx0LlxuICAgICAgbGV0IGlkID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIGlkID0gbnVsbDtcbiAgICAgICAgY29tcGxldGVyLnJlamVjdCgpO1xuICAgICAgfSwgMTAwMCk7XG5cbiAgICAgIGNvbnN0IHJlc29sdmUgPSAoKSA9PiB7XG4gICAgICAgIGlmIChpZCA9PT0gbnVsbCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNsZWFyVGltZW91dChpZCk7XG4gICAgICAgIGNvbXBsZXRlci5yZXNvbHZlKCk7XG4gICAgICB9O1xuXG4gICAgICBQcm9taXNlLmFsbCh0aGlzLmJlZm9yZURlc3Ryb3lIYW5kbGVycy5tYXAoZm4gPT4gZm4oKSkpXG4gICAgICAgIC50aGVuKHJlc29sdmUpXG4gICAgICAgIC5jYXRjaChyZXNvbHZlKTtcblxuICAgIH1cblxuICAgIHJldHVybiBjb21wbGV0ZXIucHJvbWlzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBIGhhbmRsZXIgcnVubmluZyBiZWZvcmUgZGVzdHJ1Y3Rpb24gb2YgdGhlIG92ZXJsYXlcbiAgICogdXNlIHRvIGRlbGF5IGRlc3RydWN0aW9uIGR1ZSB0byBhbmltYXRpb24uXG4gICAqIFRoaXMgaXMgcGFydCBvZiB0aGUgd29ya2Fyb3VuZCBmb3IgYW5pbWF0aW9uLCBzZWUgY2FuRGVzdHJveS5cbiAgICpcbiAgICogTk9URTogVGhlcmUgaXMgbm8gZ3VhcmFudGVlIHRoYXQgdGhlIGxpc3RlbmVycyB3aWxsIGZpcmUsIHVzZSBkaWFsb2cub25EZXN0b3J5IGZvciB0aGF0LlxuICAgKiBAcGFyYW0gZm5cbiAgICovXG4gIGJlZm9yZURlc3Ryb3koZm46ICgpID0+IFByb21pc2U8dm9pZD4pIHtcbiAgICBpZiAoIXRoaXMuYmVmb3JlRGVzdHJveUhhbmRsZXJzKSB7XG4gICAgICB0aGlzLmJlZm9yZURlc3Ryb3lIYW5kbGVycyA9IFtdO1xuICAgIH1cbiAgICB0aGlzLmJlZm9yZURlc3Ryb3lIYW5kbGVycy5wdXNoKGZuKTtcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ2JvZHk6a2V5ZG93bicsIFsnJGV2ZW50J10pXG4gIGRvY3VtZW50S2V5cHJlc3MoZXZlbnQ6IEtleWJvYXJkRXZlbnQpIHtcbiAgICAvLyBjaGVjayB0aGF0IHRoaXMgbW9kYWwgaXMgdGhlIGxhc3QgaW4gdGhlIHN0YWNrLlxuICAgIGlmICghdGhpcy5kaWFsb2dSZWYub3ZlcmxheS5pc1RvcE1vc3QodGhpcy5kaWFsb2dSZWYpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG5cbiAgICBpZiAoc3VwcG9ydHNLZXkoZXZlbnQua2V5Q29kZSwgPGFueT50aGlzLmRpYWxvZ1JlZi5jb250ZXh0LmtleWJvYXJkKSkge1xuICAgICAgdGhpcy5kaWFsb2dSZWYuZGlzbWlzcygpO1xuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHN1cGVyLm5nT25EZXN0cm95KCk7XG4gICAgaWYgKHRoaXMuZGlhbG9nUmVmLmRlc3Ryb3llZCAhPT0gdHJ1ZSkge1xuICAgICAgLy8gaWYgd2UncmUgaGVyZSB0aGUgb3ZlcmxheSBpcyBkZXN0cm95ZWQgYnkgYW4gZXh0ZXJuYWwgZXZlbnQgdGhhdCBpcyBub3QgdXNlciBpbnZva2VkLlxuICAgICAgLy8gaS5lOiBUaGUgdXNlciBkaWQgbm8gY2FsbCBkaXNtaXNzIG9yIGNsb3NlIGFuZCBkaWFsb2dSZWYuZGVzdHJveSgpIGRpZCBub3QgaW52b2tlLlxuICAgICAgLy8gdGhpcyB3aWxsIGhhcHBlbiB3aGVuIHJvdXRpbmcgb3Iga2lsbGluZyBhbiBlbGVtZW50IGNvbnRhaW5pbmcgYSBibG9ja2VkIG92ZXJsYXkgKG5nSWYpXG4gICAgICAvLyB3ZSBiYWlsIG91dCwgaS5lIGdyYWNlZnVsbHkgc2h1dHRpbmcgZG93bi5cbiAgICAgIHRoaXMuZGlhbG9nUmVmLmJhaWxPdXQoKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==