| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679 |
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
- */
- import { ChangeDetectorRef, ContentChild, ContentChildren, Directive, ElementRef, EventEmitter, forwardRef, Inject, Input, NgZone, Output, QueryList, Renderer2, Optional } from '@angular/core';
- import { DOCUMENT } from '@angular/common';
- import { fromEvent, Subject } from 'rxjs';
- import { take } from 'rxjs/operators';
- import { positionElements } from '../util/positioning';
- import { ngbAutoClose } from '../util/autoclose';
- import { Key } from '../util/key';
- import { NgbDropdownConfig } from './dropdown-config';
- export class NgbNavbar {
- }
- NgbNavbar.decorators = [
- { type: Directive, args: [{ selector: '.navbar' },] }
- ];
- /**
- * A directive you should put on a dropdown item to enable keyboard navigation.
- * Arrow keys will move focus between items marked with this directive.
- *
- * \@since 4.1.0
- */
- export class NgbDropdownItem {
- /**
- * @param {?} elementRef
- */
- constructor(elementRef) {
- this.elementRef = elementRef;
- this._disabled = false;
- }
- /**
- * @param {?} value
- * @return {?}
- */
- set disabled(value) {
- this._disabled = (/** @type {?} */ (value)) === '' || value === true; // accept an empty attribute as true
- }
- /**
- * @return {?}
- */
- get disabled() { return this._disabled; }
- }
- NgbDropdownItem.decorators = [
- { type: Directive, args: [{ selector: '[ngbDropdownItem]', host: { 'class': 'dropdown-item', '[class.disabled]': 'disabled' } },] }
- ];
- /** @nocollapse */
- NgbDropdownItem.ctorParameters = () => [
- { type: ElementRef }
- ];
- NgbDropdownItem.propDecorators = {
- disabled: [{ type: Input }]
- };
- if (false) {
- /**
- * @type {?}
- * @private
- */
- NgbDropdownItem.prototype._disabled;
- /** @type {?} */
- NgbDropdownItem.prototype.elementRef;
- }
- /**
- * A directive that wraps dropdown menu content and dropdown items.
- */
- export class NgbDropdownMenu {
- /**
- * @param {?} dropdown
- */
- constructor(dropdown) {
- this.dropdown = dropdown;
- this.placement = 'bottom';
- this.isOpen = false;
- }
- }
- NgbDropdownMenu.decorators = [
- { type: Directive, args: [{
- selector: '[ngbDropdownMenu]',
- host: {
- '[class.dropdown-menu]': 'true',
- '[class.show]': 'dropdown.isOpen()',
- '[attr.x-placement]': 'placement',
- '(keydown.ArrowUp)': 'dropdown.onKeyDown($event)',
- '(keydown.ArrowDown)': 'dropdown.onKeyDown($event)',
- '(keydown.Home)': 'dropdown.onKeyDown($event)',
- '(keydown.End)': 'dropdown.onKeyDown($event)',
- '(keydown.Enter)': 'dropdown.onKeyDown($event)',
- '(keydown.Space)': 'dropdown.onKeyDown($event)'
- }
- },] }
- ];
- /** @nocollapse */
- NgbDropdownMenu.ctorParameters = () => [
- { type: undefined, decorators: [{ type: Inject, args: [forwardRef((/**
- * @return {?}
- */
- () => NgbDropdown)),] }] }
- ];
- NgbDropdownMenu.propDecorators = {
- menuItems: [{ type: ContentChildren, args: [NgbDropdownItem,] }]
- };
- if (false) {
- /** @type {?} */
- NgbDropdownMenu.prototype.placement;
- /** @type {?} */
- NgbDropdownMenu.prototype.isOpen;
- /** @type {?} */
- NgbDropdownMenu.prototype.menuItems;
- /** @type {?} */
- NgbDropdownMenu.prototype.dropdown;
- }
- /**
- * A directive to mark an element to which dropdown menu will be anchored.
- *
- * This is a simple version of the `NgbDropdownToggle` directive.
- * It plays the same role, but doesn't listen to click events to toggle dropdown menu thus enabling support
- * for events other than click.
- *
- * \@since 1.1.0
- */
- export class NgbDropdownAnchor {
- /**
- * @param {?} dropdown
- * @param {?} _elementRef
- */
- constructor(dropdown, _elementRef) {
- this.dropdown = dropdown;
- this._elementRef = _elementRef;
- this.anchorEl = _elementRef.nativeElement;
- }
- /**
- * @return {?}
- */
- getNativeElement() { return this._elementRef.nativeElement; }
- }
- NgbDropdownAnchor.decorators = [
- { type: Directive, args: [{
- selector: '[ngbDropdownAnchor]',
- host: { 'class': 'dropdown-toggle', 'aria-haspopup': 'true', '[attr.aria-expanded]': 'dropdown.isOpen()' }
- },] }
- ];
- /** @nocollapse */
- NgbDropdownAnchor.ctorParameters = () => [
- { type: undefined, decorators: [{ type: Inject, args: [forwardRef((/**
- * @return {?}
- */
- () => NgbDropdown)),] }] },
- { type: ElementRef }
- ];
- if (false) {
- /** @type {?} */
- NgbDropdownAnchor.prototype.anchorEl;
- /** @type {?} */
- NgbDropdownAnchor.prototype.dropdown;
- /**
- * @type {?}
- * @private
- */
- NgbDropdownAnchor.prototype._elementRef;
- }
- /**
- * A directive to mark an element that will toggle dropdown via the `click` event.
- *
- * You can also use `NgbDropdownAnchor` as an alternative.
- */
- export class NgbDropdownToggle extends NgbDropdownAnchor {
- /**
- * @param {?} dropdown
- * @param {?} elementRef
- */
- constructor(dropdown, elementRef) {
- super(dropdown, elementRef);
- }
- }
- NgbDropdownToggle.decorators = [
- { type: Directive, args: [{
- selector: '[ngbDropdownToggle]',
- host: {
- 'class': 'dropdown-toggle',
- 'aria-haspopup': 'true',
- '[attr.aria-expanded]': 'dropdown.isOpen()',
- '(click)': 'dropdown.toggle()',
- '(keydown.ArrowUp)': 'dropdown.onKeyDown($event)',
- '(keydown.ArrowDown)': 'dropdown.onKeyDown($event)',
- '(keydown.Home)': 'dropdown.onKeyDown($event)',
- '(keydown.End)': 'dropdown.onKeyDown($event)'
- },
- providers: [{ provide: NgbDropdownAnchor, useExisting: forwardRef((/**
- * @return {?}
- */
- () => NgbDropdownToggle)) }]
- },] }
- ];
- /** @nocollapse */
- NgbDropdownToggle.ctorParameters = () => [
- { type: undefined, decorators: [{ type: Inject, args: [forwardRef((/**
- * @return {?}
- */
- () => NgbDropdown)),] }] },
- { type: ElementRef }
- ];
- /**
- * A directive that provides contextual overlays for displaying lists of links and more.
- */
- export class NgbDropdown {
- /**
- * @param {?} _changeDetector
- * @param {?} config
- * @param {?} _document
- * @param {?} _ngZone
- * @param {?} _elementRef
- * @param {?} _renderer
- * @param {?} ngbNavbar
- */
- constructor(_changeDetector, config, _document, _ngZone, _elementRef, _renderer, ngbNavbar) {
- this._changeDetector = _changeDetector;
- this._document = _document;
- this._ngZone = _ngZone;
- this._elementRef = _elementRef;
- this._renderer = _renderer;
- this._closed$ = new Subject();
- /**
- * Defines whether or not the dropdown menu is opened initially.
- */
- this._open = false;
- /**
- * An event fired when the dropdown is opened or closed.
- *
- * The event payload is a `boolean`:
- * * `true` - the dropdown was opened
- * * `false` - the dropdown was closed
- */
- this.openChange = new EventEmitter();
- this.placement = config.placement;
- this.container = config.container;
- this.autoClose = config.autoClose;
- this.display = ngbNavbar ? 'static' : 'dynamic';
- this._zoneSubscription = _ngZone.onStable.subscribe((/**
- * @return {?}
- */
- () => { this._positionMenu(); }));
- }
- /**
- * @return {?}
- */
- ngAfterContentInit() {
- this._ngZone.onStable.pipe(take(1)).subscribe((/**
- * @return {?}
- */
- () => {
- this._applyPlacementClasses();
- if (this._open) {
- this._setCloseHandlers();
- }
- }));
- }
- /**
- * @param {?} changes
- * @return {?}
- */
- ngOnChanges(changes) {
- if (changes.container && this._open) {
- this._applyContainer(this.container);
- }
- if (changes.placement && !changes.placement.isFirstChange) {
- this._applyPlacementClasses();
- }
- }
- /**
- * Checks if the dropdown menu is open.
- * @return {?}
- */
- isOpen() { return this._open; }
- /**
- * Opens the dropdown menu.
- * @return {?}
- */
- open() {
- if (!this._open) {
- this._open = true;
- this._applyContainer(this.container);
- this.openChange.emit(true);
- this._setCloseHandlers();
- }
- }
- /**
- * @private
- * @return {?}
- */
- _setCloseHandlers() {
- /** @type {?} */
- const anchor = this._anchor;
- ngbAutoClose(this._ngZone, this._document, this.autoClose, (/**
- * @return {?}
- */
- () => this.close()), this._closed$, this._menu ? [this._menuElement.nativeElement] : [], anchor ? [anchor.getNativeElement()] : [], '.dropdown-item,.dropdown-divider');
- }
- /**
- * Closes the dropdown menu.
- * @return {?}
- */
- close() {
- if (this._open) {
- this._open = false;
- this._resetContainer();
- this._closed$.next();
- this.openChange.emit(false);
- this._changeDetector.markForCheck();
- }
- }
- /**
- * Toggles the dropdown menu.
- * @return {?}
- */
- toggle() {
- if (this.isOpen()) {
- this.close();
- }
- else {
- this.open();
- }
- }
- /**
- * @return {?}
- */
- ngOnDestroy() {
- this._resetContainer();
- this._closed$.next();
- this._zoneSubscription.unsubscribe();
- }
- /**
- * @param {?} event
- * @return {?}
- */
- onKeyDown(event) {
- // tslint:disable-next-line:deprecation
- /** @type {?} */
- const key = event.which;
- /** @type {?} */
- const itemElements = this._getMenuElements();
- /** @type {?} */
- let position = -1;
- /** @type {?} */
- let isEventFromItems = false;
- /** @type {?} */
- let itemElement = null;
- /** @type {?} */
- const isEventFromToggle = this._isEventFromToggle(event);
- if (!isEventFromToggle && itemElements.length) {
- itemElements.forEach((/**
- * @param {?} item
- * @param {?} index
- * @return {?}
- */
- (item, index) => {
- if (item.contains((/** @type {?} */ (event.target)))) {
- isEventFromItems = true;
- itemElement = item;
- }
- if (item === this._document.activeElement) {
- position = index;
- }
- }));
- }
- // closing on Enter / Space
- if (key === Key.Space || key === Key.Enter) {
- if (isEventFromItems && (this.autoClose === true || this.autoClose === 'inside')) {
- // Item is either a button or a link, so click will be triggered by the browser on Enter or Space.
- // So we have to register a one-time click handler that will fire after any user defined click handlers
- // to close the dropdown
- fromEvent(itemElement, 'click').pipe(take(1)).subscribe((/**
- * @return {?}
- */
- () => this.close()));
- }
- return;
- }
- // opening / navigating
- if (isEventFromToggle || isEventFromItems) {
- this.open();
- if (itemElements.length) {
- switch (key) {
- case Key.ArrowDown:
- position = Math.min(position + 1, itemElements.length - 1);
- break;
- case Key.ArrowUp:
- if (this._isDropup() && position === -1) {
- position = itemElements.length - 1;
- break;
- }
- position = Math.max(position - 1, 0);
- break;
- case Key.Home:
- position = 0;
- break;
- case Key.End:
- position = itemElements.length - 1;
- break;
- }
- itemElements[position].focus();
- }
- event.preventDefault();
- }
- }
- /**
- * @private
- * @return {?}
- */
- _isDropup() { return this._elementRef.nativeElement.classList.contains('dropup'); }
- /**
- * @private
- * @param {?} event
- * @return {?}
- */
- _isEventFromToggle(event) {
- return this._anchor.getNativeElement().contains((/** @type {?} */ (event.target)));
- }
- /**
- * @private
- * @return {?}
- */
- _getMenuElements() {
- /** @type {?} */
- const menu = this._menu;
- if (menu == null) {
- return [];
- }
- return menu.menuItems.filter((/**
- * @param {?} item
- * @return {?}
- */
- item => !item.disabled)).map((/**
- * @param {?} item
- * @return {?}
- */
- item => item.elementRef.nativeElement));
- }
- /**
- * @private
- * @return {?}
- */
- _positionMenu() {
- /** @type {?} */
- const menu = this._menu;
- if (this.isOpen() && menu) {
- this._applyPlacementClasses(this.display === 'dynamic' ?
- positionElements(this._anchor.anchorEl, this._bodyContainer || this._menuElement.nativeElement, this.placement, this.container === 'body') :
- this._getFirstPlacement(this.placement));
- }
- }
- /**
- * @private
- * @param {?} placement
- * @return {?}
- */
- _getFirstPlacement(placement) {
- return Array.isArray(placement) ? placement[0] : (/** @type {?} */ (placement.split(' ')[0]));
- }
- /**
- * @private
- * @return {?}
- */
- _resetContainer() {
- /** @type {?} */
- const renderer = this._renderer;
- /** @type {?} */
- const menuElement = this._menuElement;
- if (menuElement) {
- /** @type {?} */
- const dropdownElement = this._elementRef.nativeElement;
- /** @type {?} */
- const dropdownMenuElement = menuElement.nativeElement;
- renderer.appendChild(dropdownElement, dropdownMenuElement);
- renderer.removeStyle(dropdownMenuElement, 'position');
- renderer.removeStyle(dropdownMenuElement, 'transform');
- }
- if (this._bodyContainer) {
- renderer.removeChild(this._document.body, this._bodyContainer);
- this._bodyContainer = null;
- }
- }
- /**
- * @private
- * @param {?=} container
- * @return {?}
- */
- _applyContainer(container = null) {
- this._resetContainer();
- if (container === 'body') {
- /** @type {?} */
- const renderer = this._renderer;
- /** @type {?} */
- const dropdownMenuElement = this._menuElement.nativeElement;
- /** @type {?} */
- const bodyContainer = this._bodyContainer = this._bodyContainer || renderer.createElement('div');
- // Override some styles to have the positionning working
- renderer.setStyle(bodyContainer, 'position', 'absolute');
- renderer.setStyle(dropdownMenuElement, 'position', 'static');
- renderer.setStyle(bodyContainer, 'z-index', '1050');
- renderer.appendChild(bodyContainer, dropdownMenuElement);
- renderer.appendChild(this._document.body, bodyContainer);
- }
- }
- /**
- * @private
- * @param {?=} placement
- * @return {?}
- */
- _applyPlacementClasses(placement) {
- /** @type {?} */
- const menu = this._menu;
- if (menu) {
- if (!placement) {
- placement = this._getFirstPlacement(this.placement);
- }
- /** @type {?} */
- const renderer = this._renderer;
- /** @type {?} */
- const dropdownElement = this._elementRef.nativeElement;
- // remove the current placement classes
- renderer.removeClass(dropdownElement, 'dropup');
- renderer.removeClass(dropdownElement, 'dropdown');
- menu.placement = this.display === 'static' ? null : placement;
- /*
- * apply the new placement
- * in case of top use up-arrow or down-arrow otherwise
- */
- /** @type {?} */
- const dropdownClass = placement.search('^top') !== -1 ? 'dropup' : 'dropdown';
- renderer.addClass(dropdownElement, dropdownClass);
- /** @type {?} */
- const bodyContainer = this._bodyContainer;
- if (bodyContainer) {
- renderer.removeClass(bodyContainer, 'dropup');
- renderer.removeClass(bodyContainer, 'dropdown');
- renderer.addClass(bodyContainer, dropdownClass);
- }
- }
- }
- }
- NgbDropdown.decorators = [
- { type: Directive, args: [{ selector: '[ngbDropdown]', exportAs: 'ngbDropdown', host: { '[class.show]': 'isOpen()' } },] }
- ];
- /** @nocollapse */
- NgbDropdown.ctorParameters = () => [
- { type: ChangeDetectorRef },
- { type: NgbDropdownConfig },
- { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] },
- { type: NgZone },
- { type: ElementRef },
- { type: Renderer2 },
- { type: NgbNavbar, decorators: [{ type: Optional }] }
- ];
- NgbDropdown.propDecorators = {
- _menu: [{ type: ContentChild, args: [NgbDropdownMenu, { static: false },] }],
- _menuElement: [{ type: ContentChild, args: [NgbDropdownMenu, { read: ElementRef, static: false },] }],
- _anchor: [{ type: ContentChild, args: [NgbDropdownAnchor, { static: false },] }],
- autoClose: [{ type: Input }],
- _open: [{ type: Input, args: ['open',] }],
- placement: [{ type: Input }],
- container: [{ type: Input }],
- display: [{ type: Input }],
- openChange: [{ type: Output }]
- };
- if (false) {
- /**
- * @type {?}
- * @private
- */
- NgbDropdown.prototype._closed$;
- /**
- * @type {?}
- * @private
- */
- NgbDropdown.prototype._zoneSubscription;
- /**
- * @type {?}
- * @private
- */
- NgbDropdown.prototype._bodyContainer;
- /**
- * @type {?}
- * @private
- */
- NgbDropdown.prototype._menu;
- /**
- * @type {?}
- * @private
- */
- NgbDropdown.prototype._menuElement;
- /**
- * @type {?}
- * @private
- */
- NgbDropdown.prototype._anchor;
- /**
- * Indicates whether the dropdown should be closed when clicking one of dropdown items or pressing ESC.
- *
- * * `true` - the dropdown will close on both outside and inside (menu) clicks.
- * * `false` - the dropdown can only be closed manually via `close()` or `toggle()` methods.
- * * `"inside"` - the dropdown will close on inside menu clicks, but not outside clicks.
- * * `"outside"` - the dropdown will close only on the outside clicks and not on menu clicks.
- * @type {?}
- */
- NgbDropdown.prototype.autoClose;
- /**
- * Defines whether or not the dropdown menu is opened initially.
- * @type {?}
- */
- NgbDropdown.prototype._open;
- /**
- * The preferred placement of the dropdown.
- *
- * Possible values are `"top"`, `"top-left"`, `"top-right"`, `"bottom"`, `"bottom-left"`,
- * `"bottom-right"`, `"left"`, `"left-top"`, `"left-bottom"`, `"right"`, `"right-top"`,
- * `"right-bottom"`
- *
- * Accepts an array of strings or a string with space separated possible values.
- *
- * The default order of preference is `"bottom-left bottom-right top-left top-right"`
- *
- * Please see the [positioning overview](#/positioning) for more details.
- * @type {?}
- */
- NgbDropdown.prototype.placement;
- /**
- * A selector specifying the element the dropdown should be appended to.
- * Currently only supports "body".
- *
- * \@since 4.1.0
- * @type {?}
- */
- NgbDropdown.prototype.container;
- /**
- * Enable or disable the dynamic positioning. The default value is dynamic unless the dropdown is used
- * inside a Bootstrap navbar. If you need custom placement for a dropdown in a navbar, set it to
- * dynamic explicitly. See the [positioning of dropdown](#/positioning#dropdown)
- * and the [navbar demo](/#/components/dropdown/examples#navbar) for more details.
- *
- * \@since 4.2.0
- * @type {?}
- */
- NgbDropdown.prototype.display;
- /**
- * An event fired when the dropdown is opened or closed.
- *
- * The event payload is a `boolean`:
- * * `true` - the dropdown was opened
- * * `false` - the dropdown was closed
- * @type {?}
- */
- NgbDropdown.prototype.openChange;
- /**
- * @type {?}
- * @private
- */
- NgbDropdown.prototype._changeDetector;
- /**
- * @type {?}
- * @private
- */
- NgbDropdown.prototype._document;
- /**
- * @type {?}
- * @private
- */
- NgbDropdown.prototype._ngZone;
- /**
- * @type {?}
- * @private
- */
- NgbDropdown.prototype._elementRef;
- /**
- * @type {?}
- * @private
- */
- NgbDropdown.prototype._renderer;
- }
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJvcGRvd24uanMiLCJzb3VyY2VSb290Ijoibmc6Ly9AbmctYm9vdHN0cmFwL25nLWJvb3RzdHJhcC8iLCJzb3VyY2VzIjpbImRyb3Bkb3duL2Ryb3Bkb3duLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQ0wsaUJBQWlCLEVBQ2pCLFlBQVksRUFDWixlQUFlLEVBQ2YsU0FBUyxFQUNULFVBQVUsRUFDVixZQUFZLEVBQ1osVUFBVSxFQUNWLE1BQU0sRUFDTixLQUFLLEVBQ0wsTUFBTSxFQUdOLE1BQU0sRUFDTixTQUFTLEVBQ1QsU0FBUyxFQUVULFFBQVEsRUFDVCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUMsUUFBUSxFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFDekMsT0FBTyxFQUFDLFNBQVMsRUFBRSxPQUFPLEVBQWUsTUFBTSxNQUFNLENBQUM7QUFDdEQsT0FBTyxFQUFDLElBQUksRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBRXBDLE9BQU8sRUFBNEIsZ0JBQWdCLEVBQUMsTUFBTSxxQkFBcUIsQ0FBQztBQUNoRixPQUFPLEVBQUMsWUFBWSxFQUFDLE1BQU0sbUJBQW1CLENBQUM7QUFDL0MsT0FBTyxFQUFDLEdBQUcsRUFBQyxNQUFNLGFBQWEsQ0FBQztBQUVoQyxPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSxtQkFBbUIsQ0FBQztBQUdwRCxNQUFNLE9BQU8sU0FBUzs7O1lBRHJCLFNBQVMsU0FBQyxFQUFDLFFBQVEsRUFBRSxTQUFTLEVBQUM7Ozs7Ozs7O0FBV2hDLE1BQU0sT0FBTyxlQUFlOzs7O0lBVTFCLFlBQW1CLFVBQW1DO1FBQW5DLGVBQVUsR0FBVixVQUFVLENBQXlCO1FBVDlDLGNBQVMsR0FBRyxLQUFLLENBQUM7SUFTK0IsQ0FBQzs7Ozs7SUFQMUQsSUFDSSxRQUFRLENBQUMsS0FBYztRQUN6QixJQUFJLENBQUMsU0FBUyxHQUFHLG1CQUFLLEtBQUssRUFBQSxLQUFLLEVBQUUsSUFBSSxLQUFLLEtB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QUMsQ0FBQzthQUNqRDtTQUNGO0lBQ0gsQ0FBQzs7O1lBdFRGLFNBQVMsU0FBQyxFQUFDLFFBQVEsRUFBRSxlQUFlLEVBQUUsUUFBUSxFQUFFLGFBQWEsRUFBRSxJQUFJLEVBQUUsRUFBQyxjQUFjLEVBQUUsVUFBVSxFQUFDLEVBQUM7Ozs7WUFqSWpHLGlCQUFpQjtZQTBCWCxpQkFBaUI7NENBMktxRCxNQUFNLFNBQUMsUUFBUTtZQTVMM0YsTUFBTTtZQUxOLFVBQVU7WUFVVixTQUFTO1lBeUxrQixTQUFTLHVCQUEvQixRQUFROzs7b0JBaEVaLFlBQVksU0FBQyxlQUFlLEVBQUUsRUFBQyxNQUFNLEVBQUUsS0FBSyxFQUFDOzJCQUM3QyxZQUFZLFNBQUMsZUFBZSxFQUFFLEVBQUMsSUFBSSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFDO3NCQUMvRCxZQUFZLFNBQUMsaUJBQWlCLEVBQUUsRUFBQyxNQUFNLEVBQUUsS0FBSyxFQUFDO3dCQVUvQyxLQUFLO29CQUtMLEtBQUssU0FBQyxNQUFNO3dCQWVaLEtBQUs7d0JBUUwsS0FBSztzQkFVTCxLQUFLO3lCQVNMLE1BQU07Ozs7Ozs7SUEvRFAsK0JBQXVDOzs7OztJQUN2Qyx3Q0FBd0M7Ozs7O0lBQ3hDLHFDQUFvQzs7Ozs7SUFFcEMsNEJBQStFOzs7OztJQUMvRSxtQ0FBbUc7Ozs7O0lBQ25HLDhCQUFxRjs7Ozs7Ozs7OztJQVVyRixnQ0FBbUQ7Ozs7O0lBS25ELDRCQUE2Qjs7Ozs7Ozs7Ozs7Ozs7O0lBZTdCLGdDQUFtQzs7Ozs7Ozs7SUFRbkMsZ0NBQWtDOzs7Ozs7Ozs7O0lBVWxDLDhCQUF1Qzs7Ozs7Ozs7O0lBU3ZDLGlDQUFtRDs7Ozs7SUFHL0Msc0NBQTBDOzs7OztJQUE2QixnQ0FBd0M7Ozs7O0lBQy9HLDhCQUF1Qjs7Ozs7SUFBRSxrQ0FBNEM7Ozs7O0lBQUUsZ0NBQTRCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbnRlbnRDaGlsZCxcbiAgQ29udGVudENoaWxkcmVuLFxuICBEaXJlY3RpdmUsXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgZm9yd2FyZFJlZixcbiAgSW5qZWN0LFxuICBJbnB1dCxcbiAgTmdab25lLFxuICBBZnRlckNvbnRlbnRJbml0LFxuICBPbkRlc3Ryb3ksXG4gIE91dHB1dCxcbiAgUXVlcnlMaXN0LFxuICBSZW5kZXJlcjIsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIE9wdGlvbmFsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtET0NVTUVOVH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7ZnJvbUV2ZW50LCBTdWJqZWN0LCBTdWJzY3JpcHRpb259IGZyb20gJ3J4anMnO1xuaW1wb3J0IHt0YWtlfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7UGxhY2VtZW50LCBQbGFjZW1lbnRBcnJheSwgcG9zaXRpb25FbGVtZW50c30gZnJvbSAnLi4vdXRpbC9wb3NpdGlvbmluZyc7XG5pbXBvcnQge25nYkF1dG9DbG9zZX0gZnJvbSAnLi4vdXRpbC9hdXRvY2xvc2UnO1xuaW1wb3J0IHtLZXl9IGZyb20gJy4uL3V0aWwva2V5JztcblxuaW1wb3J0IHtOZ2JEcm9wZG93bkNvbmZpZ30gZnJvbSAnLi9kcm9wZG93bi1jb25maWcnO1xuXG5ARGlyZWN0aXZlKHtzZWxlY3RvcjogJy5uYXZiYXInfSlcbmV4cG9ydCBjbGFzcyBOZ2JOYXZiYXIge1xufVxuXG4vKipcbiAqIEEgZGlyZWN0aXZlIHlvdSBzaG91bGQgcHV0IG9uIGEgZHJvcGRvd24gaXRlbSB0byBlbmFibGUga2V5Ym9hcmQgbmF2aWdhdGlvbi5cbiAqIEFycm93IGtleXMgd2lsbCBtb3ZlIGZvY3VzIGJldHdlZW4gaXRlbXMgbWFya2VkIHdpdGggdGhpcyBkaXJlY3RpdmUuXG4gKlxuICogQHNpbmNlIDQuMS4wXG4gKi9cbkBEaXJlY3RpdmUoe3NlbGVjdG9yOiAnW25nYkRyb3Bkb3duSXRlbV0nLCBob3N0OiB7J2NsYXNzJzogJ2Ryb3Bkb3duLWl0ZW0nLCAnW2NsYXNzLmRpc2FibGVkXSc6ICdkaXNhYmxlZCd9fSlcbmV4cG9ydCBjbGFzcyBOZ2JEcm9wZG93bkl0ZW0ge1xuICBwcml2YXRlIF9kaXNhYmxlZCA9IGZhbHNlO1xuXG4gIEBJbnB1dCgpXG4gIHNldCBkaXNhYmxlZCh2YWx1ZTogYm9vbGVhbikge1xuICAgIHRoaXMuX2Rpc2FibGVkID0gPGFueT52YWx1ZSA9PT0gJycgfHwgdmFsdWUgPT09IHRydWU7ICAvLyBhY2NlcHQgYW4gZW1wdHkgYXR0cmlidXRlIGFzIHRydWVcbiAgfVxuXG4gIGdldCBkaXNhYmxlZCgpOiBib29sZWFuIHsgcmV0dXJuIHRoaXMuX2Rpc2FibGVkOyB9XG5cbiAgY29uc3RydWN0b3IocHVibGljIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+KSB7fVxufVxuXG4vKipcbiAqIEEgZGlyZWN0aXZlIHRoYXQgd3JhcHMgZHJvcGRvd24gbWVudSBjb250ZW50IGFuZCBkcm9wZG93biBpdGVtcy5cbiAqL1xuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiAnW25nYkRyb3Bkb3duTWVudV0nLFxuICBob3N0OiB7XG4gICAgJ1tjbGFzcy5kcm9wZG93bi1tZW51XSc6ICd0cnVlJyxcbiAgICAnW2NsYXNzLnNob3ddJzogJ2Ryb3Bkb3duLmlzT3BlbigpJyxcbiAgICAnW2F0dHIueC1wbGFjZW1lbnRdJzogJ3BsYWNlbWVudCcsXG4gICAgJyhrZXlkb3duLkFycm93VXApJzogJ2Ryb3Bkb3duLm9uS2V5RG93bigkZXZlbnQpJyxcbiAgICAnKGtleWRvd24uQXJyb3dEb3duKSc6ICdkcm9wZG93bi5vbktleURvd24oJGV2ZW50KScsXG4gICAgJyhrZXlkb3duLkhvbWUpJzogJ2Ryb3Bkb3duLm9uS2V5RG93bigkZXZlbnQpJyxcbiAgICAnKGtleWRvd24uRW5kKSc6ICdkcm9wZG93bi5vbktleURvd24oJGV2ZW50KScsXG4gICAgJyhrZXlkb3duLkVudGVyKSc6ICdkcm9wZG93bi5vbktleURvd24oJGV2ZW50KScsXG4gICAgJyhrZXlkb3duLlNwYWNlKSc6ICdkcm9wZG93bi5vbktleURvd24oJGV2ZW50KSdcbiAgfVxufSlcbmV4cG9ydCBjbGFzcyBOZ2JEcm9wZG93bk1lbnUge1xuICBwbGFjZW1lbnQ6IFBsYWNlbWVudCA9ICdib3R0b20nO1xuICBpc09wZW4gPSBmYWxzZTtcblxuICBAQ29udGVudENoaWxkcmVuKE5nYkRyb3Bkb3duSXRlbSkgbWVudUl0ZW1zOiBRdWVyeUxpc3Q8TmdiRHJvcGRvd25JdGVtPjtcblxuICBjb25zdHJ1Y3RvcihASW5qZWN0KGZvcndhcmRSZWYoKCkgPT4gTmdiRHJvcGRvd24pKSBwdWJsaWMgZHJvcGRvd24pIHt9XG59XG5cbi8qKlxuICogQSBkaXJlY3RpdmUgdG8gbWFyayBhbiBlbGVtZW50IHRvIHdoaWNoIGRyb3Bkb3duIG1lbnUgd2lsbCBiZSBhbmNob3JlZC5cbiAqXG4gKiBUaGlzIGlzIGEgc2ltcGxlIHZlcnNpb24gb2YgdGhlIGBOZ2JEcm9wZG93blRvZ2dsZWAgZGlyZWN0aXZlLlxuICogSXQgcGxheXMgdGhlIHNhbWUgcm9sZSwgYnV0IGRvZXNuJ3QgbGlzdGVuIHRvIGNsaWNrIGV2ZW50cyB0byB0b2dnbGUgZHJvcGRvd24gbWVudSB0aHVzIGVuYWJsaW5nIHN1cHBvcnRcbiAqIGZvciBldmVudHMgb3RoZXIgdGhhbiBjbGljay5cbiAqXG4gKiBAc2luY2UgMS4xLjBcbiAqL1xuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiAnW25nYkRyb3Bkb3duQW5jaG9yXScsXG4gIGhvc3Q6IHsnY2xhc3MnOiAnZHJvcGRvd24tdG9nZ2xlJywgJ2FyaWEtaGFzcG9wdXAnOiAndHJ1ZScsICdbYXR0ci5hcmlhLWV4cGFuZGVkXSc6ICdkcm9wZG93bi5pc09wZW4oKSd9XG59KVxuZXhwb3J0IGNsYXNzIE5nYkRyb3Bkb3duQW5jaG9yIHtcbiAgYW5jaG9yRWw7XG5cbiAgY29uc3RydWN0b3IoQEluamVjdChmb3J3YXJkUmVmKCgpID0+IE5nYkRyb3Bkb3duKSkgcHVibGljIGRyb3Bkb3duLCBwcml2YXRlIF9lbGVtZW50UmVmOiBFbGVtZW50UmVmPEhUTUxFbGVtZW50Pikge1xuICAgIHRoaXMuYW5jaG9yRWwgPSBfZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50O1xuICB9XG5cbiAgZ2V0TmF0aXZlRWxlbWVudCgpIHsgcmV0dXJuIHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudDsgfVxufVxuXG4vKipcbiAqIEEgZGlyZWN0aXZlIHRvIG1hcmsgYW4gZWxlbWVudCB0aGF0IHdpbGwgdG9nZ2xlIGRyb3Bkb3duIHZpYSB0aGUgYGNsaWNrYCBldmVudC5cbiAqXG4gKiBZb3UgY2FuIGFsc28gdXNlIGBOZ2JEcm9wZG93bkFuY2hvcmAgYXMgYW4gYWx0ZXJuYXRpdmUuXG4gKi9cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogJ1tuZ2JEcm9wZG93blRvZ2dsZV0nLFxuICBob3N0OiB7XG4gICAgJ2NsYXNzJzogJ2Ryb3Bkb3duLXRvZ2dsZScsXG4gICAgJ2FyaWEtaGFzcG9wdXAnOiAndHJ1ZScsXG4gICAgJ1thdHRyLmFyaWEtZXhwYW5kZWRdJzogJ2Ryb3Bkb3duLmlzT3BlbigpJyxcbiAgICAnKGNsaWNrKSc6ICdkcm9wZG93bi50b2dnbGUoKScsXG4gICAgJyhrZXlkb3duLkFycm93VXApJzogJ2Ryb3Bkb3duLm9uS2V5RG93bigkZXZlbnQpJyxcbiAgICAnKGtleWRvd24uQXJyb3dEb3duKSc6ICdkcm9wZG93bi5vbktleURvd24oJGV2ZW50KScsXG4gICAgJyhrZXlkb3duLkhvbWUpJzogJ2Ryb3Bkb3duLm9uS2V5RG93bigkZXZlbnQpJyxcbiAgICAnKGtleWRvd24uRW5kKSc6ICdkcm9wZG93bi5vbktleURvd24oJGV2ZW50KSdcbiAgfSxcbiAgcHJvdmlkZXJzOiBbe3Byb3ZpZGU6IE5nYkRyb3Bkb3duQW5jaG9yLCB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBOZ2JEcm9wZG93blRvZ2dsZSl9XVxufSlcbmV4cG9ydCBjbGFzcyBOZ2JEcm9wZG93blRvZ2dsZSBleHRlbmRzIE5nYkRyb3Bkb3duQW5jaG9yIHtcbiAgY29uc3RydWN0b3IoQEluamVjdChmb3J3YXJkUmVmKCgpID0+IE5nYkRyb3Bkb3duKSkgZHJvcGRvd24sIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+KSB7XG4gICAgc3VwZXIoZHJvcGRvd24sIGVsZW1lbnRSZWYpO1xuICB9XG59XG5cbi8qKlxuICogQSBkaXJlY3RpdmUgdGhhdCBwcm92aWRlcyBjb250ZXh0dWFsIG92ZXJsYXlzIGZvciBkaXNwbGF5aW5nIGxpc3RzIG9mIGxpbmtzIGFuZCBtb3JlLlxuICovXG5ARGlyZWN0aXZlKHtzZWxlY3RvcjogJ1tuZ2JEcm9wZG93bl0nLCBleHBvcnRBczogJ25nYkRyb3Bkb3duJywgaG9zdDogeydbY2xhc3Muc2hvd10nOiAnaXNPcGVuKCknfX0pXG5leHBvcnQgY2xhc3MgTmdiRHJvcGRvd24gaW1wbGVtZW50cyBBZnRlckNvbnRlbnRJbml0LCBPbkRlc3Ryb3kge1xuICBwcml2YXRlIF9jbG9zZWQkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgcHJpdmF0ZSBfem9uZVN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uO1xuICBwcml2YXRlIF9ib2R5Q29udGFpbmVyOiBIVE1MRWxlbWVudDtcblxuICBAQ29udGVudENoaWxkKE5nYkRyb3Bkb3duTWVudSwge3N0YXRpYzogZmFsc2V9KSBwcml2YXRlIF9tZW51OiBOZ2JEcm9wZG93bk1lbnU7XG4gIEBDb250ZW50Q2hpbGQoTmdiRHJvcGRvd25NZW51LCB7cmVhZDogRWxlbWVudFJlZiwgc3RhdGljOiBmYWxzZX0pIHByaXZhdGUgX21lbnVFbGVtZW50OiBFbGVtZW50UmVmO1xuICBAQ29udGVudENoaWxkKE5nYkRyb3Bkb3duQW5jaG9yLCB7c3RhdGljOiBmYWxzZX0pIHByaXZhdGUgX2FuY2hvcjogTmdiRHJvcGRvd25BbmNob3I7XG5cbiAgLyoqXG4gICAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBkcm9wZG93biBzaG91bGQgYmUgY2xvc2VkIHdoZW4gY2xpY2tpbmcgb25lIG9mIGRyb3Bkb3duIGl0ZW1zIG9yIHByZXNzaW5nIEVTQy5cbiAgICpcbiAgICogKiBgdHJ1ZWAgLSB0aGUgZHJvcGRvd24gd2lsbCBjbG9zZSBvbiBib3RoIG91dHNpZGUgYW5kIGluc2lkZSAobWVudSkgY2xpY2tzLlxuICAgKiAqIGBmYWxzZWAgLSB0aGUgZHJvcGRvd24gY2FuIG9ubHkgYmUgY2xvc2VkIG1hbnVhbGx5IHZpYSBgY2xvc2UoKWAgb3IgYHRvZ2dsZSgpYCBtZXRob2RzLlxuICAgKiAqIGBcImluc2lkZVwiYCAtIHRoZSBkcm9wZG93biB3aWxsIGNsb3NlIG9uIGluc2lkZSBtZW51IGNsaWNrcywgYnV0IG5vdCBvdXRzaWRlIGNsaWNrcy5cbiAgICogKiBgXCJvdXRzaWRlXCJgIC0gdGhlIGRyb3Bkb3duIHdpbGwgY2xvc2Ugb25seSBvbiB0aGUgb3V0c2lkZSBjbGlja3MgYW5kIG5vdCBvbiBtZW51IGNsaWNrcy5cbiAgICovXG4gIEBJbnB1dCgpIGF1dG9DbG9zZTogYm9vbGVhbiB8ICdvdXRzaWRlJyB8ICdpbnNpZGUnO1xuXG4gIC8qKlxuICAgKiBEZWZpbmVzIHdoZXRoZXIgb3Igbm90IHRoZSBkcm9wZG93biBtZW51IGlzIG9wZW5lZCBpbml0aWFsbHkuXG4gICAqL1xuICBASW5wdXQoJ29wZW4nKSBfb3BlbiA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBUaGUgcHJlZmVycmVkIHBsYWNlbWVudCBvZiB0aGUgZHJvcGRvd24uXG4gICAqXG4gICAqIFBvc3NpYmxlIHZhbHVlcyBhcmUgYFwidG9wXCJgLCBgXCJ0b3AtbGVmdFwiYCwgYFwidG9wLXJpZ2h0XCJgLCBgXCJib3R0b21cImAsIGBcImJvdHRvbS1sZWZ0XCJgLFxuICAgKiBgXCJib3R0b20tcmlnaHRcImAsIGBcImxlZnRcImAsIGBcImxlZnQtdG9wXCJgLCBgXCJsZWZ0LWJvdHRvbVwiYCwgYFwicmlnaHRcImAsIGBcInJpZ2h0LXRvcFwiYCxcbiAgICogYFwicmlnaHQtYm90dG9tXCJgXG4gICAqXG4gICAqIEFjY2VwdHMgYW4gYXJyYXkgb2Ygc3RyaW5ncyBvciBhIHN0cmluZyB3aXRoIHNwYWNlIHNlcGFyYXRlZCBwb3NzaWJsZSB2YWx1ZXMuXG4gICAqXG4gICAqIFRoZSBkZWZhdWx0IG9yZGVyIG9mIHByZWZlcmVuY2UgaXMgYFwiYm90dG9tLWxlZnQgYm90dG9tLXJpZ2h0IHRvcC1sZWZ0IHRvcC1yaWdodFwiYFxuICAgKlxuICAgKiBQbGVhc2Ugc2VlIHRoZSBbcG9zaXRpb25pbmcgb3ZlcnZpZXddKCMvcG9zaXRpb25pbmcpIGZvciBtb3JlIGRldGFpbHMuXG4gICAqL1xuICBASW5wdXQoKSBwbGFjZW1lbnQ6IFBsYWNlbWVudEFycmF5O1xuXG4gIC8qKlxuICAqIEEgc2VsZWN0b3Igc3BlY2lmeWluZyB0aGUgZWxlbWVudCB0aGUgZHJvcGRvd24gc2hvdWxkIGJlIGFwcGVuZGVkIHRvLlxuICAqIEN1cnJlbnRseSBvbmx5IHN1cHBvcnRzIFwiYm9keVwiLlxuICAqXG4gICogQHNpbmNlIDQuMS4wXG4gICovXG4gIEBJbnB1dCgpIGNvbnRhaW5lcjogbnVsbCB8ICdib2R5JztcblxuICAvKipcbiAgICogRW5hYmxlIG9yIGRpc2FibGUgdGhlIGR5bmFtaWMgcG9zaXRpb25pbmcuIFRoZSBkZWZhdWx0IHZhbHVlIGlzIGR5bmFtaWMgdW5sZXNzIHRoZSBkcm9wZG93biBpcyB1c2VkXG4gICAqIGluc2lkZSBhIEJvb3RzdHJhcCBuYXZiYXIuIElmIHlvdSBuZWVkIGN1c3RvbSBwbGFjZW1lbnQgZm9yIGEgZHJvcGRvd24gaW4gYSBuYXZiYXIsIHNldCBpdCB0b1xuICAgKiBkeW5hbWljIGV4cGxpY2l0bHkuIFNlZSB0aGUgW3Bvc2l0aW9uaW5nIG9mIGRyb3Bkb3duXSgjL3Bvc2l0aW9uaW5nI2Ryb3Bkb3duKVxuICAgKiBhbmQgdGhlIFtuYXZiYXIgZGVtb10oLyMvY29tcG9uZW50cy9kcm9wZG93bi9leGFtcGxlcyNuYXZiYXIpIGZvciBtb3JlIGRldGFpbHMuXG4gICAqXG4gICAqIEBzaW5jZSA0LjIuMFxuICAgKi9cbiAgQElucHV0KCkgZGlzcGxheTogJ2R5bmFtaWMnIHwgJ3N0YXRpYyc7XG5cbiAgLyoqXG4gICAqIEFuIGV2ZW50IGZpcmVkIHdoZW4gdGhlIGRyb3Bkb3duIGlzIG9wZW5lZCBvciBjbG9zZWQuXG4gICAqXG4gICAqIFRoZSBldmVudCBwYXlsb2FkIGlzIGEgYGJvb2xlYW5gOlxuICAgKiAqIGB0cnVlYCAtIHRoZSBkcm9wZG93biB3YXMgb3BlbmVkXG4gICAqICogYGZhbHNlYCAtIHRoZSBkcm9wZG93biB3YXMgY2xvc2VkXG4gICAqL1xuICBAT3V0cHV0KCkgb3BlbkNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICAgIHByaXZhdGUgX2NoYW5nZURldGVjdG9yOiBDaGFuZ2VEZXRlY3RvclJlZiwgY29uZmlnOiBOZ2JEcm9wZG93bkNvbmZpZywgQEluamVjdChET0NVTUVOVCkgcHJpdmF0ZSBfZG9jdW1lbnQ6IGFueSxcbiAgICAgIHByaXZhdGUgX25nWm9uZTogTmdab25lLCBwcml2YXRlIF9lbGVtZW50UmVmOiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PiwgcHJpdmF0ZSBfcmVuZGVyZXI6IFJlbmRlcmVyMixcbiAgICAgIEBPcHRpb25hbCgpIG5nYk5hdmJhcjogTmdiTmF2YmFyKSB7XG4gICAgdGhpcy5wbGFjZW1lbnQgPSBjb25maWcucGxhY2VtZW50O1xuICAgIHRoaXMuY29udGFpbmVyID0gY29uZmlnLmNvbnRhaW5lcjtcbiAgICB0aGlzLmF1dG9DbG9zZSA9IGNvbmZpZy5hdXRvQ2xvc2U7XG5cbiAgICB0aGlzLmRpc3BsYXkgPSBuZ2JOYXZiYXIgPyAnc3RhdGljJyA6ICdkeW5hbWljJztcblxuICAgIHRoaXMuX3pvbmVTdWJzY3JpcHRpb24gPSBfbmdab25lLm9uU3RhYmxlLnN1YnNjcmliZSgoKSA9PiB7IHRoaXMuX3Bvc2l0aW9uTWVudSgpOyB9KTtcbiAgfVxuXG4gIG5nQWZ0ZXJDb250ZW50SW5pdCgpIHtcbiAgICB0aGlzLl9uZ1pvbmUub25TdGFibGUucGlwZSh0YWtlKDEpKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgdGhpcy5fYXBwbHlQbGFjZW1lbnRDbGFzc2VzKCk7XG4gICAgICBpZiAodGhpcy5fb3Blbikge1xuICAgICAgICB0aGlzLl9zZXRDbG9zZUhhbmRsZXJzKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XG4gICAgaWYgKGNoYW5nZXMuY29udGFpbmVyICYmIHRoaXMuX29wZW4pIHtcbiAgICAgIHRoaXMuX2FwcGx5Q29udGFpbmVyKHRoaXMuY29udGFpbmVyKTtcbiAgICB9XG5cbiAgICBpZiAoY2hhbmdlcy5wbGFjZW1lbnQgJiYgIWNoYW5nZXMucGxhY2VtZW50LmlzRmlyc3RDaGFuZ2UpIHtcbiAgICAgIHRoaXMuX2FwcGx5UGxhY2VtZW50Q2xhc3NlcygpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIGRyb3Bkb3duIG1lbnUgaXMgb3Blbi5cbiAgICovXG4gIGlzT3BlbigpOiBib29sZWFuIHsgcmV0dXJuIHRoaXMuX29wZW47IH1cblxuICAvKipcbiAgICogT3BlbnMgdGhlIGRyb3Bkb3duIG1lbnUuXG4gICAqL1xuICBvcGVuKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5fb3Blbikge1xuICAgICAgdGhpcy5fb3BlbiA9IHRydWU7XG4gICAgICB0aGlzLl9hcHBseUNvbnRhaW5lcih0aGlzLmNvbnRhaW5lcik7XG4gICAgICB0aGlzLm9wZW5DaGFuZ2UuZW1pdCh0cnVlKTtcbiAgICAgIHRoaXMuX3NldENsb3NlSGFuZGxlcnMoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIF9zZXRDbG9zZUhhbmRsZXJzKCkge1xuICAgIGNvbnN0IGFuY2hvciA9IHRoaXMuX2FuY2hvcjtcbiAgICBuZ2JBdXRvQ2xvc2UoXG4gICAgICAgIHRoaXMuX25nWm9uZSwgdGhpcy5fZG9jdW1lbnQsIHRoaXMuYXV0b0Nsb3NlLCAoKSA9PiB0aGlzLmNsb3NlKCksIHRoaXMuX2Nsb3NlZCQsXG4gICAgICAgIHRoaXMuX21lbnUgPyBbdGhpcy5fbWVudUVsZW1lbnQubmF0aXZlRWxlbWVudF0gOiBbXSwgYW5jaG9yID8gW2FuY2hvci5nZXROYXRpdmVFbGVtZW50KCldIDogW10sXG4gICAgICAgICcuZHJvcGRvd24taXRlbSwuZHJvcGRvd24tZGl2aWRlcicpO1xuICB9XG5cbiAgLyoqXG4gICAqIENsb3NlcyB0aGUgZHJvcGRvd24gbWVudS5cbiAgICovXG4gIGNsb3NlKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLl9vcGVuKSB7XG4gICAgICB0aGlzLl9vcGVuID0gZmFsc2U7XG4gICAgICB0aGlzLl9yZXNldENvbnRhaW5lcigpO1xuICAgICAgdGhpcy5fY2xvc2VkJC5uZXh0KCk7XG4gICAgICB0aGlzLm9wZW5DaGFuZ2UuZW1pdChmYWxzZSk7XG4gICAgICB0aGlzLl9jaGFuZ2VEZXRlY3Rvci5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVG9nZ2xlcyB0aGUgZHJvcGRvd24gbWVudS5cbiAgICovXG4gIHRvZ2dsZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5pc09wZW4oKSkge1xuICAgICAgdGhpcy5jbG9zZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm9wZW4oKTtcbiAgICB9XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLl9yZXNldENvbnRhaW5lcigpO1xuXG4gICAgdGhpcy5fY2xvc2VkJC5uZXh0KCk7XG4gICAgdGhpcy5fem9uZVN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICB9XG5cbiAgb25LZXlEb3duKGV2ZW50OiBLZXlib2FyZEV2ZW50KSB7XG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmRlcHJlY2F0aW9uXG4gICAgY29uc3Qga2V5ID0gZXZlbnQud2hpY2g7XG4gICAgY29uc3QgaXRlbUVsZW1lbnRzID0gdGhpcy5fZ2V0TWVudUVsZW1lbnRzKCk7XG5cbiAgICBsZXQgcG9zaXRpb24gPSAtMTtcbiAgICBsZXQgaXNFdmVudEZyb21JdGVtcyA9IGZhbHNlO1xuICAgIGxldCBpdGVtRWxlbWVudDogSFRNTEVsZW1lbnQgPSBudWxsO1xuICAgIGNvbnN0IGlzRXZlbnRGcm9tVG9nZ2xlID0gdGhpcy5faXNFdmVudEZyb21Ub2dnbGUoZXZlbnQpO1xuXG4gICAgaWYgKCFpc0V2ZW50RnJvbVRvZ2dsZSAmJiBpdGVtRWxlbWVudHMubGVuZ3RoKSB7XG4gICAgICBpdGVtRWxlbWVudHMuZm9yRWFjaCgoaXRlbSwgaW5kZXgpID0+IHtcbiAgICAgICAgaWYgKGl0ZW0uY29udGFpbnMoZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50KSkge1xuICAgICAgICAgIGlzRXZlbnRGcm9tSXRlbXMgPSB0cnVlO1xuICAgICAgICAgIGl0ZW1FbGVtZW50ID0gaXRlbTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXRlbSA9PT0gdGhpcy5fZG9jdW1lbnQuYWN0aXZlRWxlbWVudCkge1xuICAgICAgICAgIHBvc2l0aW9uID0gaW5kZXg7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIGNsb3Npbmcgb24gRW50ZXIgLyBTcGFjZVxuICAgIGlmIChrZXkgPT09IEtleS5TcGFjZSB8fCBrZXkgPT09IEtleS5FbnRlcikge1xuICAgICAgaWYgKGlzRXZlbnRGcm9tSXRlbXMgJiYgKHRoaXMuYXV0b0Nsb3NlID09PSB0cnVlIHx8IHRoaXMuYXV0b0Nsb3NlID09PSAnaW5zaWRlJykpIHtcbiAgICAgICAgLy8gSXRlbSBpcyBlaXRoZXIgYSBidXR0b24gb3IgYSBsaW5rLCBzbyBjbGljayB3aWxsIGJlIHRyaWdnZXJlZCBieSB0aGUgYnJvd3NlciBvbiBFbnRlciBvciBTcGFjZS5cbiAgICAgICAgLy8gU28gd2UgaGF2ZSB0byByZWdpc3RlciBhIG9uZS10aW1lIGNsaWNrIGhhbmRsZXIgdGhhdCB3aWxsIGZpcmUgYWZ0ZXIgYW55IHVzZXIgZGVmaW5lZCBjbGljayBoYW5kbGVyc1xuICAgICAgICAvLyB0byBjbG9zZSB0aGUgZHJvcGRvd25cbiAgICAgICAgZnJvbUV2ZW50KGl0ZW1FbGVtZW50LCAnY2xpY2snKS5waXBlKHRha2UoMSkpLnN1YnNjcmliZSgoKSA9PiB0aGlzLmNsb3NlKCkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIG9wZW5pbmcgLyBuYXZpZ2F0aW5nXG4gICAgaWYgKGlzRXZlbnRGcm9tVG9nZ2xlIHx8IGlzRXZlbnRGcm9tSXRlbXMpIHtcbiAgICAgIHRoaXMub3BlbigpO1xuXG4gICAgICBpZiAoaXRlbUVsZW1lbnRzLmxlbmd0aCkge1xuICAgICAgICBzd2l0Y2ggKGtleSkge1xuICAgICAgICAgIGNhc2UgS2V5LkFycm93RG93bjpcbiAgICAgICAgICAgIHBvc2l0aW9uID0gTWF0aC5taW4ocG9zaXRpb24gKyAxLCBpdGVtRWxlbWVudHMubGVuZ3RoIC0gMSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlIEtleS5BcnJvd1VwOlxuICAgICAgICAgICAgaWYgKHRoaXMuX2lzRHJvcHVwKCkgJiYgcG9zaXRpb24gPT09IC0xKSB7XG4gICAgICAgICAgICAgIHBvc2l0aW9uID0gaXRlbUVsZW1lbnRzLmxlbmd0aCAtIDE7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcG9zaXRpb24gPSBNYXRoLm1heChwb3NpdGlvbiAtIDEsIDApO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSBLZXkuSG9tZTpcbiAgICAgICAgICAgIHBvc2l0aW9uID0gMDtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgS2V5LkVuZDpcbiAgICAgICAgICAgIHBvc2l0aW9uID0gaXRlbUVsZW1lbnRzLmxlbmd0aCAtIDE7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBpdGVtRWxlbWVudHNbcG9zaXRpb25dLmZvY3VzKCk7XG4gICAgICB9XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2lzRHJvcHVwKCk6IGJvb2xlYW4geyByZXR1cm4gdGhpcy5fZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdC5jb250YWlucygnZHJvcHVwJyk7IH1cblxuICBwcml2YXRlIF9pc0V2ZW50RnJvbVRvZ2dsZShldmVudDogS2V5Ym9hcmRFdmVudCkge1xuICAgIHJldHVybiB0aGlzLl9hbmNob3IuZ2V0TmF0aXZlRWxlbWVudCgpLmNvbnRhaW5zKGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudCk7XG4gIH1cblxuICBwcml2YXRlIF9nZXRNZW51RWxlbWVudHMoKTogSFRNTEVsZW1lbnRbXSB7XG4gICAgY29uc3QgbWVudSA9IHRoaXMuX21lbnU7XG4gICAgaWYgKG1lbnUgPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgICByZXR1cm4gbWVudS5tZW51SXRlbXMuZmlsdGVyKGl0ZW0gPT4gIWl0ZW0uZGlzYWJsZWQpLm1hcChpdGVtID0+IGl0ZW0uZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50KTtcbiAgfVxuXG4gIHByaXZhdGUgX3Bvc2l0aW9uTWVudSgpIHtcbiAgICBjb25zdCBtZW51ID0gdGhpcy5fbWVudTtcbiAgICBpZiAodGhpcy5pc09wZW4oKSAmJiBtZW51KSB7XG4gICAgICB0aGlzLl9hcHBseVBsYWNlbWVudENsYXNzZXMoXG4gICAgICAgICAgdGhpcy5kaXNwbGF5ID09PSAnZHluYW1pYycgP1xuICAgICAgICAgICAgICBwb3NpdGlvbkVsZW1lbnRzKFxuICAgICAgICAgICAgICAgICAgdGhpcy5fYW5jaG9yLmFuY2hvckVsLCB0aGlzLl9ib2R5Q29udGFpbmVyIHx8IHRoaXMuX21lbnVFbGVtZW50Lm5hdGl2ZUVsZW1lbnQsIHRoaXMucGxhY2VtZW50LFxuICAgICAgICAgICAgICAgICAgdGhpcy5jb250YWluZXIgPT09ICdib2R5JykgOlxuICAgICAgICAgICAgICB0aGlzLl9nZXRGaXJzdFBsYWNlbWVudCh0aGlzLnBsYWNlbWVudCkpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2dldEZpcnN0UGxhY2VtZW50KHBsYWNlbWVudDogUGxhY2VtZW50QXJyYXkpOiBQbGFjZW1lbnQge1xuICAgIHJldHVybiBBcnJheS5pc0FycmF5KHBsYWNlbWVudCkgPyBwbGFjZW1lbnRbMF0gOiBwbGFjZW1lbnQuc3BsaXQoJyAnKVswXSBhcyBQbGFjZW1lbnQ7XG4gIH1cblxuICBwcml2YXRlIF9yZXNldENvbnRhaW5lcigpIHtcbiAgICBjb25zdCByZW5kZXJlciA9IHRoaXMuX3JlbmRlcmVyO1xuICAgIGNvbnN0IG1lbnVFbGVtZW50ID0gdGhpcy5fbWVudUVsZW1lbnQ7XG4gICAgaWYgKG1lbnVFbGVtZW50KSB7XG4gICAgICBjb25zdCBkcm9wZG93bkVsZW1lbnQgPSB0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQ7XG4gICAgICBjb25zdCBkcm9wZG93bk1lbnVFbGVtZW50ID0gbWVudUVsZW1lbnQubmF0aXZlRWxlbWVudDtcblxuICAgICAgcmVuZGVyZXIuYXBwZW5kQ2hpbGQoZHJvcGRvd25FbGVtZW50LCBkcm9wZG93bk1lbnVFbGVtZW50KTtcbiAgICAgIHJlbmRlcmVyLnJlbW92ZVN0eWxlKGRyb3Bkb3duTWVudUVsZW1lbnQsICdwb3NpdGlvbicpO1xuICAgICAgcmVuZGVyZXIucmVtb3ZlU3R5bGUoZHJvcGRvd25NZW51RWxlbWVudCwgJ3RyYW5zZm9ybScpO1xuICAgIH1cbiAgICBpZiAodGhpcy5fYm9keUNvbnRhaW5lcikge1xuICAgICAgcmVuZGVyZXIucmVtb3ZlQ2hpbGQodGhpcy5fZG9jdW1lbnQuYm9keSwgdGhpcy5fYm9keUNvbnRhaW5lcik7XG4gICAgICB0aGlzLl9ib2R5Q29udGFpbmVyID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIF9hcHBseUNvbnRhaW5lcihjb250YWluZXI6IG51bGwgfCAnYm9keScgPSBudWxsKSB7XG4gICAgdGhpcy5fcmVzZXRDb250YWluZXIoKTtcbiAgICBpZiAoY29udGFpbmVyID09PSAnYm9keScpIHtcbiAgICAgIGNvbnN0IHJlbmRlcmVyID0gdGhpcy5fcmVuZGVyZXI7XG4gICAgICBjb25zdCBkcm9wZG93bk1lbnVFbGVtZW50ID0gdGhpcy5fbWVudUVsZW1lbnQubmF0aXZlRWxlbWVudDtcbiAgICAgIGNvbnN0IGJvZHlDb250YWluZXIgPSB0aGlzLl9ib2R5Q29udGFpbmVyID0gdGhpcy5fYm9keUNvbnRhaW5lciB8fCByZW5kZXJlci5jcmVhdGVFbGVtZW50KCdkaXYnKTtcblxuICAgICAgLy8gT3ZlcnJpZGUgc29tZSBzdHlsZXMgdG8gaGF2ZSB0aGUgcG9zaXRpb25uaW5nIHdvcmtpbmdcbiAgICAgIHJlbmRlcmVyLnNldFN0eWxlKGJvZHlDb250YWluZXIsICdwb3NpdGlvbicsICdhYnNvbHV0ZScpO1xuICAgICAgcmVuZGVyZXIuc2V0U3R5bGUoZHJvcGRvd25NZW51RWxlbWVudCwgJ3Bvc2l0aW9uJywgJ3N0YXRpYycpO1xuICAgICAgcmVuZGVyZXIuc2V0U3R5bGUoYm9keUNvbnRhaW5lciwgJ3otaW5kZXgnLCAnMTA1MCcpO1xuXG4gICAgICByZW5kZXJlci5hcHBlbmRDaGlsZChib2R5Q29udGFpbmVyLCBkcm9wZG93bk1lbnVFbGVtZW50KTtcbiAgICAgIHJlbmRlcmVyLmFwcGVuZENoaWxkKHRoaXMuX2RvY3VtZW50LmJvZHksIGJvZHlDb250YWluZXIpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2FwcGx5UGxhY2VtZW50Q2xhc3NlcyhwbGFjZW1lbnQ/OiBQbGFjZW1lbnQpIHtcbiAgICBjb25zdCBtZW51ID0gdGhpcy5fbWVudTtcbiAgICBpZiAobWVudSkge1xuICAgICAgaWYgKCFwbGFjZW1lbnQpIHtcbiAgICAgICAgcGxhY2VtZW50ID0gdGhpcy5fZ2V0Rmlyc3RQbGFjZW1lbnQodGhpcy5wbGFjZW1lbnQpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCByZW5kZXJlciA9IHRoaXMuX3JlbmRlcmVyO1xuICAgICAgY29uc3QgZHJvcGRvd25FbGVtZW50ID0gdGhpcy5fZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50O1xuXG4gICAgICAvLyByZW1vdmUgdGhlIGN1cnJlbnQgcGxhY2VtZW50IGNsYXNzZXNcbiAgICAgIHJlbmRlcmVyLnJlbW92ZUNsYXNzKGRyb3Bkb3duRWxlbWVudCwgJ2Ryb3B1cCcpO1xuICAgICAgcmVuZGVyZXIucmVtb3ZlQ2xhc3MoZHJvcGRvd25FbGVtZW50LCAnZHJvcGRvd24nKTtcbiAgICAgIG1lbnUucGxhY2VtZW50ID0gdGhpcy5kaXNwbGF5ID09PSAnc3RhdGljJyA/IG51bGwgOiBwbGFjZW1lbnQ7XG5cbiAgICAgIC8qXG4gICAgICAqIGFwcGx5IHRoZSBuZXcgcGxhY2VtZW50XG4gICAgICAqIGluIGNhc2Ugb2YgdG9wIHVzZSB1cC1hcnJvdyBvciBkb3duLWFycm93IG90aGVyd2lzZVxuICAgICAgKi9cbiAgICAgIGNvbnN0IGRyb3Bkb3duQ2xhc3MgPSBwbGFjZW1lbnQuc2VhcmNoKCdedG9wJykgIT09IC0xID8gJ2Ryb3B1cCcgOiAnZHJvcGRvd24nO1xuICAgICAgcmVuZGVyZXIuYWRkQ2xhc3MoZHJvcGRvd25FbGVtZW50LCBkcm9wZG93bkNsYXNzKTtcblxuICAgICAgY29uc3QgYm9keUNvbnRhaW5lciA9IHRoaXMuX2JvZHlDb250YWluZXI7XG4gICAgICBpZiAoYm9keUNvbnRhaW5lcikge1xuICAgICAgICByZW5kZXJlci5yZW1vdmVDbGFzcyhib2R5Q29udGFpbmVyLCAnZHJvcHVwJyk7XG4gICAgICAgIHJlbmRlcmVyLnJlbW92ZUNsYXNzKGJvZHlDb250YWluZXIsICdkcm9wZG93bicpO1xuICAgICAgICByZW5kZXJlci5hZGRDbGFzcyhib2R5Q29udGFpbmVyLCBkcm9wZG93bkNsYXNzKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbiJdfQ==
|