theme-lib
Version:
This is a simple example Angular Library published to npm.
350 lines • 30 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/*
* @license
* Copyright Akveo. All Rights Reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*/
import { ComponentFactoryResolver, Inject, Injectable, Injector, TemplateRef } from '@angular/core';
import { fromEvent as observableFromEvent } from 'rxjs';
import { filter } from 'rxjs/operators';
import { NbComponentPortal, NbOverlayService, NbPortalInjector, NbPositionBuilderService, NbTemplatePortal, } from '../cdk';
import { NB_DOCUMENT } from '../../theme.options';
import { NB_DIALOG_CONFIG, NbDialogConfig } from './dialog-config';
import { NbDialogRef } from './dialog-ref';
import { NbDialogContainerComponent } from './dialog-container';
/*
* The `NbDialogService` helps to open dialogs.
*
* @stacked-example(Showcase, dialog/dialog-showcase.component)
*
* A new dialog is opened by calling the `open` method with a component to be loaded and an optional configuration.
* `open` method will return `NbDialogRef` that can be used for the further manipulations.
*
* ### Installation
*
* Import `NbDialogModule.forRoot()` to your app module.
* ```ts
* @NgModule({
* imports: [
* // ...
* NbDialogModule.forRoot(config),
* ],
* })
* export class AppModule { }
* ```
*
* If you are using it in a lazy loaded module than you have to install it with `NbDialogModule.forChild()`:
* ```ts
* @NgModule({
* imports: [
* // ...
* NbDialogModule.forChild(config),
* ],
* })
* export class LazyLoadedModule { }
* ```
*
* ### Usage
*
* ```ts
* const dialogRef = this.dialogService.open(MyDialogComponent, { ... });
* ```
*
* `NbDialogRef` gives capability access reference to the rendered dialog component,
* destroy dialog and some other options described below.
*
* Also, you can inject `NbDialogRef` in dialog component.
*
* ```ts
* this.dialogService.open(MyDialogComponent, { ... });
*
* // my-dialog.component.ts
* constructor(protected dialogRef: NbDialogRef) {
* }
*
* close() {
* this.dialogRef.close();
* }
* ```
*
* Instead of component you can create dialog from TemplateRef:
*
* @stacked-example(Template ref, dialog/dialog-template.component)
*
* The dialog may return result through `NbDialogRef`. Calling component can receive this result with `onClose`
* stream of `NbDialogRef`.
*
* @stacked-example(Result, dialog/dialog-result.component)
*
* ### Configuration
*
* As we mentioned above, `open` method of the `NbDialogService` may receive optional configuration options.
* Also, you can provide global dialogs configuration through `NbDialogModule.forRoot({ ... })`.
*
* This config may contain the following:
*
* `context` - both, template and component may receive data through `config.context` property.
* For components, this data will be assigned through inputs.
* For templates, you can access it inside template as $implicit.
*
* ```ts
* this.dialogService.open(template, { context: 'pass data in template' });
* ```
*
* ```html
* <ng-template let-some-additional-data>
* {{ some-additional-data }}
* <ng-template/>
* ```
*
* `hasBackdrop` - determines is service have to render backdrop under the dialog.
* Default is true.
* @stacked-example(Backdrop, dialog/dialog-has-backdrop.component)
*
* `closeOnBackdropClick` - close dialog on backdrop click if true.
* Default is true.
* @stacked-example(Backdrop click, dialog/dialog-backdrop-click.component)
*
* `closeOnEsc` - close dialog on escape button on the keyboard.
* Default is true.
* @stacked-example(Escape hit, dialog/dialog-esc.component)
*
* `hasScroll` - Disables scroll on content under dialog if true and does nothing otherwise.
* Default is false.
* Please, open dialogs in the separate window and try to scroll.
* @stacked-example(Scroll, dialog/dialog-scroll.component)
*
* `autoFocus` - Focuses dialog automatically after open if true. It's useful to prevent misclicks on
* trigger elements and opening multiple dialogs.
* Default is true.
*
* As you can see, if you open dialog with auto focus dialog will focus first focusable element
* or just blur previously focused automatically.
* Otherwise, without auto focus, the focus will stay on the previously focused element.
* Please, open dialogs in the separate window and try to click on the button without focus
* and then hit space any times. Multiple same dialogs will be opened.
* @stacked-example(Auto focus, dialog/dialog-auto-focus.component)
* */
export class NbDialogService {
/**
* @param {?} document
* @param {?} globalConfig
* @param {?} positionBuilder
* @param {?} overlay
* @param {?} injector
* @param {?} cfr
*/
constructor(document, globalConfig, positionBuilder, overlay, injector, cfr) {
this.document = document;
this.globalConfig = globalConfig;
this.positionBuilder = positionBuilder;
this.overlay = overlay;
this.injector = injector;
this.cfr = cfr;
}
/*
* Opens new instance of the dialog, may receive optional config.
* */
/**
* @template T
* @param {?} content
* @param {?=} userConfig
* @return {?}
*/
open(content, userConfig = {}) {
/** @type {?} */
const config = new NbDialogConfig(Object.assign({}, this.globalConfig, userConfig));
/** @type {?} */
const overlayRef = this.createOverlay(config);
/** @type {?} */
const dialogRef = new NbDialogRef(overlayRef);
/** @type {?} */
const container = this.createContainer(config, overlayRef);
this.createContent(config, content, container, dialogRef);
this.registerCloseListeners(config, overlayRef, dialogRef);
return dialogRef;
}
/**
* @protected
* @param {?} config
* @return {?}
*/
createOverlay(config) {
/** @type {?} */
const positionStrategy = this.createPositionStrategy();
/** @type {?} */
const scrollStrategy = this.createScrollStrategy(config.hasScroll);
return this.overlay.create({
positionStrategy,
scrollStrategy,
hasBackdrop: config.hasBackdrop,
backdropClass: config.backdropClass,
});
}
/**
* @protected
* @return {?}
*/
createPositionStrategy() {
return this.positionBuilder
.global()
.centerVertically()
.centerHorizontally();
}
/**
* @protected
* @param {?} hasScroll
* @return {?}
*/
createScrollStrategy(hasScroll) {
if (hasScroll) {
return this.overlay.scrollStrategies.noop();
}
else {
return this.overlay.scrollStrategies.block();
}
}
/**
* @protected
* @param {?} config
* @param {?} overlayRef
* @return {?}
*/
createContainer(config, overlayRef) {
/** @type {?} */
const injector = new NbPortalInjector(this.createInjector(config), new WeakMap([[NbDialogConfig, config]]));
/** @type {?} */
const containerPortal = new NbComponentPortal(NbDialogContainerComponent, null, injector, this.cfr);
/** @type {?} */
const containerRef = overlayRef.attach(containerPortal);
return containerRef.instance;
}
/**
* @protected
* @template T
* @param {?} config
* @param {?} content
* @param {?} container
* @param {?} dialogRef
* @return {?}
*/
createContent(config, content, container, dialogRef) {
if (content instanceof TemplateRef) {
/** @type {?} */
const portal = this.createTemplatePortal(config, content, dialogRef);
container.attachTemplatePortal(portal);
}
else {
/** @type {?} */
const portal = this.createComponentPortal(config, content, dialogRef);
dialogRef.componentRef = container.attachComponentPortal(portal);
if (config.context) {
Object.assign(dialogRef.componentRef.instance, Object.assign({}, config.context));
}
}
}
/**
* @protected
* @template T
* @param {?} config
* @param {?} content
* @param {?} dialogRef
* @return {?}
*/
createTemplatePortal(config, content, dialogRef) {
return new NbTemplatePortal(content, null, (/** @type {?} */ ({ $implicit: config.context, dialogRef })));
}
/*
* We're creating portal with custom injector provided through config or using global injector.
* This approach provides us capability inject `NbDialogRef` in dialog component.
* */
/**
* @protected
* @template T
* @param {?} config
* @param {?} content
* @param {?} dialogRef
* @return {?}
*/
createComponentPortal(config, content, dialogRef) {
/** @type {?} */
const injector = this.createInjector(config);
/** @type {?} */
const portalInjector = new NbPortalInjector(injector, new WeakMap([[NbDialogRef, dialogRef]]));
return new NbComponentPortal(content, config.viewContainerRef, portalInjector);
}
/**
* @protected
* @param {?} config
* @return {?}
*/
createInjector(config) {
return config.viewContainerRef && config.viewContainerRef.injector || this.injector;
}
/**
* @protected
* @template T
* @param {?} config
* @param {?} overlayRef
* @param {?} dialogRef
* @return {?}
*/
registerCloseListeners(config, overlayRef, dialogRef) {
if (config.closeOnBackdropClick) {
overlayRef.backdropClick().subscribe(() => dialogRef.close());
}
if (config.closeOnEsc) {
observableFromEvent(this.document, 'keyup')
.pipe(filter((event) => event.keyCode === 27))
.subscribe(() => dialogRef.close());
}
}
}
NbDialogService.decorators = [
{ type: Injectable }
];
/** @nocollapse */
NbDialogService.ctorParameters = () => [
{ type: undefined, decorators: [{ type: Inject, args: [NB_DOCUMENT,] }] },
{ type: undefined, decorators: [{ type: Inject, args: [NB_DIALOG_CONFIG,] }] },
{ type: NbPositionBuilderService },
{ type: NbOverlayService },
{ type: Injector },
{ type: ComponentFactoryResolver }
];
if (false) {
/**
* @type {?}
* @protected
*/
NbDialogService.prototype.document;
/**
* @type {?}
* @protected
*/
NbDialogService.prototype.globalConfig;
/**
* @type {?}
* @protected
*/
NbDialogService.prototype.positionBuilder;
/**
* @type {?}
* @protected
*/
NbDialogService.prototype.overlay;
/**
* @type {?}
* @protected
*/
NbDialogService.prototype.injector;
/**
* @type {?}
* @protected
*/
NbDialogService.prototype.cfr;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlhbG9nLnNlcnZpY2UuanMiLCJzb3VyY2VSb290Ijoibmc6Ly90aGVtZS1saWIvIiwic291cmNlcyI6WyJsaWIvY29tcG9uZW50cy9kaWFsb2cvZGlhbG9nLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7O0FBTUEsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBUSxNQUFNLGVBQWUsQ0FBQztBQUMxRyxPQUFPLEVBQUUsU0FBUyxJQUFJLG1CQUFtQixFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3hELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUV4QyxPQUFPLEVBQ0wsaUJBQWlCLEVBR2pCLGdCQUFnQixFQUNoQixnQkFBZ0IsRUFDaEIsd0JBQXdCLEVBRXhCLGdCQUFnQixHQUNqQixNQUFNLFFBQVEsQ0FBQztBQUNoQixPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDbEQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLGNBQWMsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ25FLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDM0MsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0sb0JBQW9CLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQXFIaEUsTUFBTSxPQUFPLGVBQWU7Ozs7Ozs7OztJQUMxQixZQUEyQyxRQUFRLEVBQ0gsWUFBWSxFQUN0QyxlQUF5QyxFQUN6QyxPQUF5QixFQUN6QixRQUFrQixFQUNsQixHQUE2QjtRQUxSLGFBQVEsR0FBUixRQUFRLENBQUE7UUFDSCxpQkFBWSxHQUFaLFlBQVksQ0FBQTtRQUN0QyxvQkFBZSxHQUFm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O1NBQy9EO1FBRUQsSUFBSSxNQUFNLENBQUMsVUFBVSxFQUFFO1lBQ3JCLG1CQUFtQixDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDO2lCQUN4QyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsS0FBb0IsRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLE9BQU8sS0FBSyxFQUFFLENBQUMsQ0FBQztpQkFDNUQsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1NBQ3ZDO0lBQ0gsQ0FBQzs7O1lBNUdGLFVBQVU7Ozs7NENBRUksTUFBTSxTQUFDLFdBQVc7NENBQ2xCLE1BQU0sU0FBQyxnQkFBZ0I7WUE5SHBDLHdCQUF3QjtZQUZ4QixnQkFBZ0I7WUFScUMsUUFBUTtZQUF0RCx3QkFBd0I7Ozs7Ozs7SUF1SW5CLG1DQUF1Qzs7Ozs7SUFDdkMsdUNBQWdEOzs7OztJQUNoRCwwQ0FBbUQ7Ozs7O0lBQ25ELGtDQUFtQzs7Ozs7SUFDbkMsbUNBQTRCOzs7OztJQUM1Qiw4QkFBdUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxyXG4gKiBAbGljZW5zZVxyXG4gKiBDb3B5cmlnaHQgQWt2ZW8uIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXHJcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS4gU2VlIExpY2Vuc2UudHh0IGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcbiAqL1xyXG5cclxuaW1wb3J0IHsgQ29tcG9uZW50RmFjdG9yeVJlc29sdmVyLCBJbmplY3QsIEluamVjdGFibGUsIEluamVjdG9yLCBUZW1wbGF0ZVJlZiwgVHlwZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBmcm9tRXZlbnQgYXMgb2JzZXJ2YWJsZUZyb21FdmVudCB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBmaWx0ZXIgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcblxyXG5pbXBvcnQge1xyXG4gIE5iQ29tcG9uZW50UG9ydGFsLFxyXG4gIE5iR2xvYmFsUG9zaXRpb25TdHJhdGVneSxcclxuICBOYk92ZXJsYXlSZWYsXHJcbiAgTmJPdmVybGF5U2VydmljZSxcclxuICBOYlBvcnRhbEluamVjdG9yLFxyXG4gIE5iUG9zaXRpb25CdWlsZGVyU2VydmljZSxcclxuICBOYlNjcm9sbFN0cmF0ZWd5LFxyXG4gIE5iVGVtcGxhdGVQb3J0YWwsXHJcbn0gZnJvbSAnLi4vY2RrJztcclxuaW1wb3J0IHsgTkJfRE9DVU1FTlQgfSBmcm9tICcuLi8uLi90aGVtZS5vcHRpb25zJztcclxuaW1wb3J0IHsgTkJfRElBTE9HX0NPTkZJRywgTmJEaWFsb2dDb25maWcgfSBmcm9tICcuL2RpYWxvZy1jb25maWcnO1xyXG5pbXBvcnQgeyBOYkRpYWxvZ1JlZiB9IGZyb20gJy4vZGlhbG9nLXJlZic7XHJcbmltcG9ydCB7IE5iRGlhbG9nQ29udGFpbmVyQ29tcG9uZW50IH0gZnJvbSAnLi9kaWFsb2ctY29udGFpbmVyJztcclxuXHJcblxyXG4vKlxyXG4gKiBUaGUgYE5iRGlhbG9nU2VydmljZWAgaGVscHMgdG8gb3BlbiBkaWFsb2dzLlxyXG4gKlxyXG4gKiBAc3RhY2tlZC1leGFtcGxlKFNob3djYXNlLCBkaWFsb2cvZGlhbG9nLXNob3djYXNlLmNvbXBvbmVudClcclxuICpcclxuICogQSBuZXcgZGlhbG9nIGlzIG9wZW5lZCBieSBjYWxsaW5nIHRoZSBgb3BlbmAgbWV0aG9kIHdpdGggYSBjb21wb25lbnQgdG8gYmUgbG9hZGVkIGFuZCBhbiBvcHRpb25hbCBjb25maWd1cmF0aW9uLlxyXG4gKiBgb3BlbmAgbWV0aG9kIHdpbGwgcmV0dXJuIGBOYkRpYWxvZ1JlZmAgdGhhdCBjYW4gYmUgdXNlZCBmb3IgdGhlIGZ1cnRoZXIgbWFuaXB1bGF0aW9ucy5cclxuICpcclxuICogIyMjIEluc3RhbGxhdGlvblxyXG4gKlxyXG4gKiBJbXBvcnQgYE5iRGlhbG9nTW9kdWxlLmZvclJvb3QoKWAgdG8geW91ciBhcHAgbW9kdWxlLlxyXG4gKiBgYGB0c1xyXG4gKiBATmdNb2R1bGUoe1xyXG4gKiAgIGltcG9ydHM6IFtcclxuICogICBcdC8vIC4uLlxyXG4gKiAgICAgTmJEaWFsb2dNb2R1bGUuZm9yUm9vdChjb25maWcpLFxyXG4gKiAgIF0sXHJcbiAqIH0pXHJcbiAqIGV4cG9ydCBjbGFzcyBBcHBNb2R1bGUgeyB9XHJcbiAqIGBgYFxyXG4gKlxyXG4gKiBJZiB5b3UgYXJlIHVzaW5nIGl0IGluIGEgbGF6eSBsb2FkZWQgbW9kdWxlIHRoYW4geW91IGhhdmUgdG8gaW5zdGFsbCBpdCB3aXRoIGBOYkRpYWxvZ01vZHVsZS5mb3JDaGlsZCgpYDpcclxuICogYGBgdHNcclxuICogQE5nTW9kdWxlKHtcclxuICogICBpbXBvcnRzOiBbXHJcbiAqICAgXHQvLyAuLi5cclxuICogICAgIE5iRGlhbG9nTW9kdWxlLmZvckNoaWxkKGNvbmZpZyksXHJcbiAqICAgXSxcclxuICogfSlcclxuICogZXhwb3J0IGNsYXNzIExhenlMb2FkZWRNb2R1bGUgeyB9XHJcbiAqIGBgYFxyXG4gKlxyXG4gKiAjIyMgVXNhZ2VcclxuICpcclxuICogYGBgdHNcclxuICogY29uc3QgZGlhbG9nUmVmID0gdGhpcy5kaWFsb2dTZXJ2aWNlLm9wZW4oTXlEaWFsb2dDb21wb25lbnQsIHsgLi4uIH0pO1xyXG4gKiBgYGBcclxuICpcclxuICogYE5iRGlhbG9nUmVmYCBnaXZlcyBjYXBhYmlsaXR5IGFjY2VzcyByZWZlcmVuY2UgdG8gdGhlIHJlbmRlcmVkIGRpYWxvZyBjb21wb25lbnQsXHJcbiAqIGRlc3Ryb3kgZGlhbG9nIGFuZCBzb21lIG90aGVyIG9wdGlvbnMgZGVzY3JpYmVkIGJlbG93LlxyXG4gKlxyXG4gKiBBbHNvLCB5b3UgY2FuIGluamVjdCBgTmJEaWFsb2dSZWZgIGluIGRpYWxvZyBjb21wb25lbnQuXHJcbiAqXHJcbiAqIGBgYHRzXHJcbiAqIHRoaXMuZGlhbG9nU2VydmljZS5vcGVuKE15RGlhbG9nQ29tcG9uZW50LCB7IC4uLiB9KTtcclxuICpcclxuICogLy8gbXktZGlhbG9nLmNvbXBvbmVudC50c1xyXG4gKiBjb25zdHJ1Y3Rvcihwcm90ZWN0ZWQgZGlhbG9nUmVmOiBOYkRpYWxvZ1JlZikge1xyXG4gKiB9XHJcbiAqXHJcbiAqIGNsb3NlKCkge1xyXG4gKiAgIHRoaXMuZGlhbG9nUmVmLmNsb3NlKCk7XHJcbiAqIH1cclxuICogYGBgXHJcbiAqXHJcbiAqIEluc3RlYWQgb2YgY29tcG9uZW50IHlvdSBjYW4gY3JlYXRlIGRpYWxvZyBmcm9tIFRlbXBsYXRlUmVmOlxyXG4gKlxyXG4gKiBAc3RhY2tlZC1leGFtcGxlKFRlbXBsYXRlIHJlZiwgZGlhbG9nL2RpYWxvZy10ZW1wbGF0ZS5jb21wb25lbnQpXHJcbiAqXHJcbiAqIFRoZSBkaWFsb2cgbWF5IHJldHVybiByZXN1bHQgdGhyb3VnaCBgTmJEaWFsb2dSZWZgLiBDYWxsaW5nIGNvbXBvbmVudCBjYW4gcmVjZWl2ZSB0aGlzIHJlc3VsdCB3aXRoIGBvbkNsb3NlYFxyXG4gKiBzdHJlYW0gb2YgYE5iRGlhbG9nUmVmYC5cclxuICpcclxuICogQHN0YWNrZWQtZXhhbXBsZShSZXN1bHQsIGRpYWxvZy9kaWFsb2ctcmVzdWx0LmNvbXBvbmVudClcclxuICpcclxuICogIyMjIENvbmZpZ3VyYXRpb25cclxuICpcclxuICogQXMgd2UgbWVudGlvbmVkIGFib3ZlLCBgb3BlbmAgbWV0aG9kIG9mIHRoZSBgTmJEaWFsb2dTZXJ2aWNlYCBtYXkgcmVjZWl2ZSBvcHRpb25hbCBjb25maWd1cmF0aW9uIG9wdGlvbnMuXHJcbiAqIEFsc28sIHlvdSBjYW4gcHJvdmlkZSBnbG9iYWwgZGlhbG9ncyBjb25maWd1cmF0aW9uIHRocm91Z2ggYE5iRGlhbG9nTW9kdWxlLmZvclJvb3QoeyAuLi4gfSlgLlxyXG4gKlxyXG4gKiBUaGlzIGNvbmZpZyBtYXkgY29udGFpbiB0aGUgZm9sbG93aW5nOlxyXG4gKlxyXG4gKiBgY29udGV4dGAgLSBib3RoLCB0ZW1wbGF0ZSBhbmQgY29tcG9uZW50IG1heSByZWNlaXZlIGRhdGEgdGhyb3VnaCBgY29uZmlnLmNvbnRleHRgIHByb3BlcnR5LlxyXG4gKiBGb3IgY29tcG9uZW50cywgdGhpcyBkYXRhIHdpbGwgYmUgYXNzaWduZWQgdGhyb3VnaCBpbnB1dHMuXHJcbiAqIEZvciB0ZW1wbGF0ZXMsIHlvdSBjYW4gYWNjZXNzIGl0IGluc2lkZSB0ZW1wbGF0ZSBhcyAkaW1wbGljaXQuXHJcbiAqXHJcbiAqIGBgYHRzXHJcbiAqIHRoaXMuZGlhbG9nU2VydmljZS5vcGVuKHRlbXBsYXRlLCB7IGNvbnRleHQ6ICdwYXNzIGRhdGEgaW4gdGVtcGxhdGUnIH0pO1xyXG4gKiBgYGBcclxuICpcclxuICogYGBgaHRtbFxyXG4gKiA8bmctdGVtcGxhdGUgbGV0LXNvbWUtYWRkaXRpb25hbC1kYXRhPlxyXG4gKiAgIHt7IHNvbWUtYWRkaXRpb25hbC1kYXRhIH19XHJcbiAqIDxuZy10ZW1wbGF0ZS8+XHJcbiAqIGBgYFxyXG4gKlxyXG4gKiBgaGFzQmFja2Ryb3BgIC0gZGV0ZXJtaW5lcyBpcyBzZXJ2aWNlIGhhdmUgdG8gcmVuZGVyIGJhY2tkcm9wIHVuZGVyIHRoZSBkaWFsb2cuXHJcbiAqIERlZmF1bHQgaXMgdHJ1ZS5cclxuICogQHN0YWNrZWQtZXhhbXBsZShCYWNrZHJvcCwgZGlhbG9nL2RpYWxvZy1oYXMtYmFja2Ryb3AuY29tcG9uZW50KVxyXG4gKlxyXG4gKiBgY2xvc2VPbkJhY2tkcm9wQ2xpY2tgIC0gY2xvc2UgZGlhbG9nIG9uIGJhY2tkcm9wIGNsaWNrIGlmIHRydWUuXHJcbiAqIERlZmF1bHQgaXMgdHJ1ZS5cclxuICogQHN0YWNrZWQtZXhhbXBsZShCYWNrZHJvcCBjbGljaywgZGlhbG9nL2RpYWxvZy1iYWNrZHJvcC1jbGljay5jb21wb25lbnQpXHJcbiAqXHJcbiAqIGBjbG9zZU9uRXNjYCAtIGNsb3NlIGRpYWxvZyBvbiBlc2NhcGUgYnV0dG9uIG9uIHRoZSBrZXlib2FyZC5cclxuICogRGVmYXVsdCBpcyB0cnVlLlxyXG4gKiBAc3RhY2tlZC1leGFtcGxlKEVzY2FwZSBoaXQsIGRpYWxvZy9kaWFsb2ctZXNjLmNvbXBvbmVudClcclxuICpcclxuICogYGhhc1Njcm9sbGAgLSBEaXNhYmxlcyBzY3JvbGwgb24gY29udGVudCB1bmRlciBkaWFsb2cgaWYgdHJ1ZSBhbmQgZG9lcyBub3RoaW5nIG90aGVyd2lzZS5cclxuICogRGVmYXVsdCBpcyBmYWxzZS5cclxuICogUGxlYXNlLCBvcGVuIGRpYWxvZ3MgaW4gdGhlIHNlcGFyYXRlIHdpbmRvdyBhbmQgdHJ5IHRvIHNjcm9sbC5cclxuICogQHN0YWNrZWQtZXhhbXBsZShTY3JvbGwsIGRpYWxvZy9kaWFsb2ctc2Nyb2xsLmNvbXBvbmVudClcclxuICpcclxuICogYGF1dG9Gb2N1c2AgLSBGb2N1c2VzIGRpYWxvZyBhdXRvbWF0aWNhbGx5IGFmdGVyIG9wZW4gaWYgdHJ1ZS4gSXQncyB1c2VmdWwgdG8gcHJldmVudCBtaXNjbGlja3Mgb25cclxuICogdHJpZ2dlciBlbGVtZW50cyBhbmQgb3BlbmluZyBtdWx0aXBsZSBkaWFsb2dzLlxyXG4gKiBEZWZhdWx0IGlzIHRydWUuXHJcbiAqXHJcbiAqIEFzIHlvdSBjYW4gc2VlLCBpZiB5b3Ugb3BlbiBkaWFsb2cgd2l0aCBhdXRvIGZvY3VzIGRpYWxvZyB3aWxsIGZvY3VzIGZpcnN0IGZvY3VzYWJsZSBlbGVtZW50XHJcbiAqIG9yIGp1c3QgYmx1ciBwcmV2aW91c2x5IGZvY3VzZWQgYXV0b21hdGljYWxseS5cclxuICogT3RoZXJ3aXNlLCB3aXRob3V0IGF1dG8gZm9jdXMsIHRoZSBmb2N1cyB3aWxsIHN0YXkgb24gdGhlIHByZXZpb3VzbHkgZm9jdXNlZCBlbGVtZW50LlxyXG4gKiBQbGVhc2UsIG9wZW4gZGlhbG9ncyBpbiB0aGUgc2VwYXJhdGUgd2luZG93IGFuZCB0cnkgdG8gY2xpY2sgb24gdGhlIGJ1dHRvbiB3aXRob3V0IGZvY3VzXHJcbiAqIGFuZCB0aGVuIGhpdCBzcGFjZSBhbnkgdGltZXMuIE11bHRpcGxlIHNhbWUgZGlhbG9ncyB3aWxsIGJlIG9wZW5lZC5cclxuICogQHN0YWNrZWQtZXhhbXBsZShBdXRvIGZvY3VzLCBkaWFsb2cvZGlhbG9nLWF1dG8tZm9jdXMuY29tcG9uZW50KVxyXG4gKiAqL1xyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBOYkRpYWxvZ1NlcnZpY2Uge1xyXG4gIGNvbnN0cnVjdG9yKEBJbmplY3QoTkJfRE9DVU1FTlQpIHByb3RlY3RlZCBkb2N1bWVudCxcclxuICAgICAgICAgICAgICBASW5qZWN0KE5CX0RJQUxPR19DT05GSUcpIHByb3RlY3RlZCBnbG9iYWxDb25maWcsXHJcbiAgICAgICAgICAgICAgcHJvdGVjdGVkIHBvc2l0aW9uQnVpbGRlcjogTmJQb3NpdGlvbkJ1aWxkZXJTZXJ2aWNlLFxyXG4gICAgICAgICAgICAgIHByb3RlY3RlZCBvdmVybGF5OiBOYk92ZXJsYXlTZXJ2aWNlLFxyXG4gICAgICAgICAgICAgIHByb3RlY3RlZCBpbmplY3RvcjogSW5qZWN0b3IsXHJcbiAgICAgICAgICAgICAgcHJvdGVjdGVkIGNmcjogQ29tcG9uZW50RmFjdG9yeVJlc29sdmVyKSB7XHJcbiAgfVxyXG5cclxuICAvKlxyXG4gICAqIE9wZW5zIG5ldyBpbnN0YW5jZSBvZiB0aGUgZGlhbG9nLCBtYXkgcmVjZWl2ZSBvcHRpb25hbCBjb25maWcuXHJcbiAgICogKi9cclxuICBvcGVuPFQ+KGNvbnRlbnQ6IFR5cGU8VD4gfCBUZW1wbGF0ZVJlZjxUPiwgdXNlckNvbmZpZzogUGFydGlhbDxOYkRpYWxvZ0NvbmZpZzxUPj4gPSB7fSk6IE5iRGlhbG9nUmVmPFQ+IHtcclxuICAgIGNvbnN0IGNvbmZpZyA9IG5ldyBOYkRpYWxvZ0NvbmZpZyh7IC4uLnRoaXMuZ2xvYmFsQ29uZmlnLCAuLi51c2VyQ29uZmlnIH0pO1xyXG4gICAgY29uc3Qgb3ZlcmxheVJlZiA9IHRoaXMuY3JlYXRlT3ZlcmxheShjb25maWcpO1xyXG4gICAgY29uc3QgZGlhbG9nUmVmID0gbmV3IE5iRGlhbG9nUmVmPFQ+KG92ZXJsYXlSZWYpO1xyXG4gICAgY29uc3QgY29udGFpbmVyID0gdGhpcy5jcmVhdGVDb250YWluZXIoY29uZmlnLCBvdmVybGF5UmVmKTtcclxuICAgIHRoaXMuY3JlYXRlQ29udGVudChjb25maWcsIGNvbnRlbnQsIGNvbnRhaW5lciwgZGlhbG9nUmVmKTtcclxuXHJcbiAgICB0aGlzLnJlZ2lzdGVyQ2xvc2VMaXN0ZW5lcnMoY29uZmlnLCBvdmVybGF5UmVmLCBkaWFsb2dSZWYpO1xyXG5cclxuICAgIHJldHVybiBkaWFsb2dSZWY7XHJcbiAgfVxyXG5cclxuICBwcm90ZWN0ZWQgY3JlYXRlT3ZlcmxheShjb25maWc6IE5iRGlhbG9nQ29uZmlnKTogTmJPdmVybGF5UmVmIHtcclxuICAgIGNvbnN0IHBvc2l0aW9uU3RyYXRlZ3kgPSB0aGlzLmNyZWF0ZVBvc2l0aW9uU3RyYXRlZ3koKTtcclxuICAgIGNvbnN0IHNjcm9sbFN0cmF0ZWd5ID0gdGhpcy5jcmVhdGVTY3JvbGxTdHJhdGVneShjb25maWcuaGFzU2Nyb2xsKTtcclxuXHJcbiAgICByZXR1cm4gdGhpcy5vdmVybGF5LmNyZWF0ZSh7XHJcbiAgICAgIHBvc2l0aW9uU3RyYXRlZ3ksXHJcbiAgICAgIHNjcm9sbFN0cmF0ZWd5LFxyXG4gICAgICBoYXNCYWNrZHJvcDogY29uZmlnLmhhc0JhY2tkcm9wLFxyXG4gICAgICBiYWNrZHJvcENsYXNzOiBjb25maWcuYmFja2Ryb3BDbGFzcyxcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHJvdGVjdGVkIGNyZWF0ZVBvc2l0aW9uU3RyYXRlZ3koKTogTmJHbG9iYWxQb3NpdGlvblN0cmF0ZWd5IHtcclxuICAgIHJldHVybiB0aGlzLnBvc2l0aW9uQnVpbGRlclxyXG4gICAgICAuZ2xvYmFsKClcclxuICAgICAgLmNlbnRlclZlcnRpY2FsbHkoKVxyXG4gICAgICAuY2VudGVySG9yaXpvbnRhbGx5KCk7XHJcbiAgfVxyXG5cclxuICBwcm90ZWN0ZWQgY3JlYXRlU2Nyb2xsU3RyYXRlZ3koaGFzU2Nyb2xsOiBib29sZWFuKTogTmJTY3JvbGxTdHJhdGVneSB7XHJcbiAgICBpZiAoaGFzU2Nyb2xsKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLm92ZXJsYXkuc2Nyb2xsU3RyYXRlZ2llcy5ub29wKCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICByZXR1cm4gdGhpcy5vdmVybGF5LnNjcm9sbFN0cmF0ZWdpZXMuYmxvY2soKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByb3RlY3RlZCBjcmVhdGVDb250YWluZXIoY29uZmlnOiBOYkRpYWxvZ0NvbmZpZywgb3ZlcmxheVJlZjogTmJPdmVybGF5UmVmKTogTmJEaWFsb2dDb250YWluZXJDb21wb25lbnQge1xyXG4gICAgY29uc3QgaW5qZWN0b3IgPSBuZXcgTmJQb3J0YWxJbmplY3Rvcih0aGlzLmNyZWF0ZUluamVjdG9yKGNvbmZpZyksIG5ldyBXZWFrTWFwKFtbTmJEaWFsb2dDb25maWcsIGNvbmZpZ11dKSk7XHJcbiAgICBjb25zdCBjb250YWluZXJQb3J0YWwgPSBuZXcgTmJDb21wb25lbnRQb3J0YWwoTmJEaWFsb2dDb250YWluZXJDb21wb25lbnQsIG51bGwsIGluamVjdG9yLCB0aGlzLmNmcik7XHJcbiAgICBjb25zdCBjb250YWluZXJSZWYgPSBvdmVybGF5UmVmLmF0dGFjaChjb250YWluZXJQb3J0YWwpO1xyXG4gICAgcmV0dXJuIGNvbnRhaW5lclJlZi5pbnN0YW5jZTtcclxuICB9XHJcblxyXG4gIHByb3RlY3RlZCBjcmVhdGVDb250ZW50PFQ+KGNvbmZpZzogTmJEaWFsb2dDb25maWcsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudDogVHlwZTxUPiB8IFRlbXBsYXRlUmVmPFQ+LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRhaW5lcjogTmJEaWFsb2dDb250YWluZXJDb21wb25lbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlhbG9nUmVmOiBOYkRpYWxvZ1JlZjxUPikge1xyXG4gICAgaWYgKGNvbnRlbnQgaW5zdGFuY2VvZiBUZW1wbGF0ZVJlZikge1xyXG4gICAgICBjb25zdCBwb3J0YWwgPSB0aGlzLmNyZWF0ZVRlbXBsYXRlUG9ydGFsKGNvbmZpZywgY29udGVudCwgZGlhbG9nUmVmKTtcclxuICAgICAgY29udGFpbmVyLmF0dGFjaFRlbXBsYXRlUG9ydGFsKHBvcnRhbCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb25zdCBwb3J0YWwgPSB0aGlzLmNyZWF0ZUNvbXBvbmVudFBvcnRhbChjb25maWcsIGNvbnRlbnQsIGRpYWxvZ1JlZik7XHJcbiAgICAgIGRpYWxvZ1JlZi5jb21wb25lbnRSZWYgPSBjb250YWluZXIuYXR0YWNoQ29tcG9uZW50UG9ydGFsKHBvcnRhbCk7XHJcblxyXG4gICAgICBpZiAoY29uZmlnLmNvbnRleHQpIHtcclxuICAgICAgICBPYmplY3QuYXNzaWduKGRpYWxvZ1JlZi5jb21wb25lbnRSZWYuaW5zdGFuY2UsIHsgLi4uY29uZmlnLmNvbnRleHQgfSlcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJvdGVjdGVkIGNyZWF0ZVRlbXBsYXRlUG9ydGFsPFQ+KGNvbmZpZzogTmJEaWFsb2dDb25maWcsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ6IFRlbXBsYXRlUmVmPFQ+LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaWFsb2dSZWY6IE5iRGlhbG9nUmVmPFQ+KTogTmJUZW1wbGF0ZVBvcnRhbCB7XHJcbiAgICByZXR1cm4gbmV3IE5iVGVtcGxhdGVQb3J0YWwoY29udGVudCwgbnVsbCwgPGFueT57ICRpbXBsaWNpdDogY29uZmlnLmNvbnRleHQsIGRpYWxvZ1JlZiB9KTtcclxuICB9XHJcblxyXG4gIC8qXHJcbiAgICogV2UncmUgY3JlYXRpbmcgcG9ydGFsIHdpdGggY3VzdG9tIGluamVjdG9yIHByb3ZpZGVkIHRocm91Z2ggY29uZmlnIG9yIHVzaW5nIGdsb2JhbCBpbmplY3Rvci5cclxuICAgKiBUaGlzIGFwcHJvYWNoIHByb3ZpZGVzIHVzIGNhcGFiaWxpdHkgaW5qZWN0IGBOYkRpYWxvZ1JlZmAgaW4gZGlhbG9nIGNvbXBvbmVudC5cclxuICAgKiAqL1xyXG4gIHByb3RlY3RlZCBjcmVhdGVDb21wb25lbnRQb3J0YWw8VD4oY29uZmlnOiBOYkRpYWxvZ0NvbmZpZyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ6IFR5cGU8VD4sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaWFsb2dSZWY6IE5iRGlhbG9nUmVmPFQ+KTogTmJDb21wb25lbnRQb3J0YWwge1xyXG4gICAgY29uc3QgaW5qZWN0b3IgPSB0aGlzLmNyZWF0ZUluamVjdG9yKGNvbmZpZyk7XHJcbiAgICBjb25zdCBwb3J0YWxJbmplY3RvciA9IG5ldyBOYlBvcnRhbEluamVjdG9yKGluamVjdG9yLCBuZXcgV2Vha01hcChbW05iRGlhbG9nUmVmLCBkaWFsb2dSZWZdXSkpO1xyXG4gICAgcmV0dXJuIG5ldyBOYkNvbXBvbmVudFBvcnRhbChjb250ZW50LCBjb25maWcudmlld0NvbnRhaW5lclJlZiwgcG9ydGFsSW5qZWN0b3IpO1xyXG4gIH1cclxuXHJcbiAgcHJvdGVjdGVkIGNyZWF0ZUluamVjdG9yKGNvbmZpZzogTmJEaWFsb2dDb25maWcpOiBJbmplY3RvciB7XHJcbiAgICByZXR1cm4gY29uZmlnLnZpZXdDb250YWluZXJSZWYgJiYgY29uZmlnLnZpZXdDb250YWluZXJSZWYuaW5qZWN0b3IgfHwgdGhpcy5pbmplY3RvcjtcclxuICB9XHJcblxyXG4gIHByb3RlY3RlZCByZWdpc3RlckNsb3NlTGlzdGVuZXJzPFQ+KGNvbmZpZzogTmJEaWFsb2dDb25maWcsIG92ZXJsYXlSZWY6IE5iT3ZlcmxheVJlZiwgZGlhbG9nUmVmOiBOYkRpYWxvZ1JlZjxUPikge1xyXG4gICAgaWYgKGNvbmZpZy5jbG9zZU9uQmFja2Ryb3BDbGljaykge1xyXG4gICAgICBvdmVybGF5UmVmLmJhY2tkcm9wQ2xpY2soKS5zdWJzY3JpYmUoKCkgPT4gZGlhbG9nUmVmLmNsb3NlKCkpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChjb25maWcuY2xvc2VPbkVzYykge1xyXG4gICAgICBvYnNlcnZhYmxlRnJvbUV2ZW50KHRoaXMuZG9jdW1lbnQsICdrZXl1cCcpXHJcbiAgICAgICAgLnBpcGUoZmlsdGVyKChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4gZXZlbnQua2V5Q29kZSA9PT0gMjcpKVxyXG4gICAgICAgIC5zdWJzY3JpYmUoKCkgPT4gZGlhbG9nUmVmLmNsb3NlKCkpO1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG4iXX0=